diff --git a/test/e2e/issuer_acme_dns01_test.go b/test/e2e/issuer_acme_dns01_test.go index ead6d0aba..cd848b6e3 100644 --- a/test/e2e/issuer_acme_dns01_test.go +++ b/test/e2e/issuer_acme_dns01_test.go @@ -5,18 +5,28 @@ package e2e import ( "context" + "encoding/json" + "errors" "fmt" "log" + "net/http" "os" "path/filepath" "strconv" "strings" "time" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/iam" "github.com/aws/aws-sdk-go-v2/service/sts" + "github.com/google/uuid" gcpcrm "google.golang.org/api/cloudresourcemanager/v1" gcpiam "google.golang.org/api/iam/v1" @@ -1386,6 +1396,212 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() { }) }) + Context("with Azure DNS in Workload Identity environment", Label("Platform:Azure", "CredentialsMode:Manual"), Label("TechPreview"), func() { + var identityClientID string + var subscriptionID, dnsResourceGroupName, hostedZoneName string + + BeforeAll(func() { + By("verifying cluster is STS-enabled") + isSTS, err := isSTSCluster(ctx, oseOperatorClient, configClient) + Expect(err).NotTo(HaveOccurred()) + if !isSTS { + Skip("Test requires Azure Workload Identity enabled") + } + + By("setting up Azure authentication environment variable from credentials file") + if os.Getenv("OPENSHIFT_CI") == "true" { + clusterProfileDir := os.Getenv("CLUSTER_PROFILE_DIR") + Expect(clusterProfileDir).NotTo(BeEmpty(), "CLUSTER_PROFILE_DIR should exist when running in OpenShift CI") + os.Setenv("AZURE_AUTH_LOCATION", filepath.Join(clusterProfileDir, "osServicePrincipal.json")) + } else { + Expect(os.Getenv("AZURE_AUTH_LOCATION")).NotTo(BeEmpty(), "AZURE_AUTH_LOCATION must be set when running locally") + } + azureAuthLocation := os.Getenv("AZURE_AUTH_LOCATION") + data, err := os.ReadFile(azureAuthLocation) + Expect(err).NotTo(HaveOccurred(), "failed to read Azure credentials file") + var sp struct { + ClientID string `json:"clientId"` + ClientSecret string `json:"clientSecret"` + TenantID string `json:"tenantId"` + SubscriptionID string `json:"subscriptionId"` + } + Expect(json.Unmarshal(data, &sp)).To(Succeed(), "failed to parse Azure credentials file") + + By("creating Azure SDK credential") + cred, err := azidentity.NewClientSecretCredential(sp.TenantID, sp.ClientID, sp.ClientSecret, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create Azure SDK credential") + + // The DNS zone may live in a different subscription than the cluster. + // Use the DNS zone subscription for DNS-related operations (issuer, role assignment scope), + // and the cluster subscription for infrastructure operations (RG lookup, MSI creation). + subscriptionID, dnsResourceGroupName, hostedZoneName = getAzureDNSZoneInfo(ctx) + clusterSubscriptionID := sp.SubscriptionID + + By("getting cluster resource group from Infrastructure object") + infra, err := configClient.Infrastructures().Get(ctx, "cluster", metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred(), "failed to get Infrastructure object") + clusterResourceGroup := infra.Status.PlatformStatus.Azure.ResourceGroupName + Expect(clusterResourceGroup).NotTo(BeEmpty(), "Azure resource group should not be empty") + + By("getting cluster resource group location") + rgClient, err := armresources.NewResourceGroupsClient(clusterSubscriptionID, cred, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create resource groups client") + rg, err := rgClient.Get(ctx, clusterResourceGroup, nil) + Expect(err).NotTo(HaveOccurred(), "failed to get resource group") + Expect(rg.Location).NotTo(BeNil(), "resource group location should be populated") + location := *rg.Location + + By("getting OIDC issuer from Authentication object") + authConfig, err := configClient.Authentications().Get(ctx, "cluster", metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred(), "failed to get Authentication object") + oidcIssuer := authConfig.Spec.ServiceAccountIssuer + Expect(oidcIssuer).NotTo(BeEmpty(), "OIDC issuer not found in Authentication object") + + By("creating Azure Managed Identity") + randomSuffix := randomStr(4) + identityName := "e2e-cert-manager-dns01-" + randomSuffix + msiClient, err := armmsi.NewUserAssignedIdentitiesClient(clusterSubscriptionID, cred, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create MSI client") + + identity, err := msiClient.CreateOrUpdate(ctx, clusterResourceGroup, identityName, armmsi.Identity{ + Location: &location, + }, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create Managed Identity") + Expect(identity.Properties).NotTo(BeNil(), "managed identity properties should be populated") + Expect(identity.Properties.ClientID).NotTo(BeNil(), "managed identity client ID should be populated") + Expect(identity.Properties.PrincipalID).NotTo(BeNil(), "managed identity principal ID should be populated") + identityClientID = *identity.Properties.ClientID + identityPrincipalID := *identity.Properties.PrincipalID + + DeferCleanup(func(ctx context.Context) { + By("Cleaning up Azure Managed Identity") + _, err := msiClient.Delete(ctx, clusterResourceGroup, identityName, nil) + if err != nil { + fmt.Fprintf(GinkgoWriter, "failed to delete Managed Identity during cleanup: %v\n", err) + } + }) + + By("granting DNS Zone Contributor role to Managed Identity on the DNS zone") + dnsZoneScope := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/dnszones/%s", + subscriptionID, dnsResourceGroupName, hostedZoneName) + + roleDefClient, err := armauthorization.NewRoleDefinitionsClient(cred, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create role definitions client") + roleName := "DNS Zone Contributor" + filter := fmt.Sprintf("roleName eq '%s'", roleName) + pager := roleDefClient.NewListPager(dnsZoneScope, &armauthorization.RoleDefinitionsClientListOptions{Filter: &filter}) + Expect(pager.More()).To(BeTrue(), "no role definitions found for %q", roleName) + page, err := pager.NextPage(ctx) + Expect(err).NotTo(HaveOccurred(), "failed to list role definitions") + Expect(page.Value).NotTo(BeEmpty(), "role definition %q not found", roleName) + dnsZoneContributorRoleID := *page.Value[0].ID + + authClient, err := armauthorization.NewRoleAssignmentsClient(subscriptionID, cred, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create authorization client") + roleAssignmentName := uuid.New().String() + + err = wait.PollUntilContextTimeout(ctx, fastPollInterval, lowTimeout, true, func(context.Context) (bool, error) { + _, assignErr := authClient.Create(ctx, dnsZoneScope, roleAssignmentName, armauthorization.RoleAssignmentCreateParameters{ + Properties: &armauthorization.RoleAssignmentProperties{ + RoleDefinitionID: &dnsZoneContributorRoleID, + PrincipalID: &identityPrincipalID, + PrincipalType: to.Ptr(armauthorization.PrincipalTypeServicePrincipal), + }, + }, nil) + if assignErr != nil { + var respErr *azcore.ResponseError + if errors.As(assignErr, &respErr) && + respErr.StatusCode == http.StatusConflict && respErr.ErrorCode == "RoleAssignmentExists" { + return true, nil + } + fmt.Fprintf(GinkgoWriter, "role assignment attempt failed (retrying): %v\n", assignErr) + return false, nil + } + return true, nil + }) + Expect(err).NotTo(HaveOccurred(), "failed to create role assignment") + + DeferCleanup(func(ctx context.Context) { + By("Cleaning up role assignment") + _, err := authClient.Delete(ctx, dnsZoneScope, roleAssignmentName, nil) + if err != nil { + fmt.Fprintf(GinkgoWriter, "failed to delete role assignment during cleanup: %v\n", err) + } + }) + + By("creating Federated Identity Credential for cert-manager ServiceAccount") + ficClient, err := armmsi.NewFederatedIdentityCredentialsClient(clusterSubscriptionID, cred, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create Federated Identity Credentials client") + + _, err = ficClient.CreateOrUpdate(ctx, clusterResourceGroup, identityName, "cert-manager", armmsi.FederatedIdentityCredential{ + Properties: &armmsi.FederatedIdentityCredentialProperties{ + Issuer: &oidcIssuer, + Subject: to.Ptr("system:serviceaccount:cert-manager:cert-manager"), + Audiences: []*string{to.Ptr("api://AzureADTokenExchange")}, + }, + }, nil) + Expect(err).NotTo(HaveOccurred(), "failed to create Federated Identity Credential") + + DeferCleanup(func(ctx context.Context) { + By("Cleaning up Federated Identity Credential") + _, err := ficClient.Delete(ctx, clusterResourceGroup, identityName, "cert-manager", nil) + if err != nil { + fmt.Fprintf(GinkgoWriter, "failed to delete Federated Identity Credential during cleanup: %v\n", err) + } + }) + }) + + It("should obtain a valid certificate using ambient credentials through AAD Workload Identity", func() { + + By("adding 'azure.workload.identity/use' label to cert-manager controller pods") + err := addOverrideLabels(certmanageroperatorclient, certmanagerControllerDeployment, map[string]string{ + "azure.workload.identity/use": "true", + }) + Expect(err).NotTo(HaveOccurred(), "failed to add workload identity label to cert-manager controller") + + DeferCleanup(func(ctx context.Context) { + By("Removing workload identity label from cert-manager controller pods") + if err := addOverrideLabels(certmanageroperatorclient, certmanagerControllerDeployment, nil); err != nil { + fmt.Fprintf(GinkgoWriter, "failed to remove workload identity label during cleanup: %v\n", err) + } + }) + + By("waiting for cert-manager deployment to rollout with workload identity label") + err = waitForDeploymentPodLabelAndRollout(ctx, "cert-manager", "cert-manager", "azure.workload.identity/use", "true", 2*time.Minute) + Expect(err).NotTo(HaveOccurred(), "timeout waiting for cert-manager deployment rollout with workload identity label") + + By("creating ACME ClusterIssuer with AzureDNS DNS-01 solver using managed identity") + clusterIssuerName := "letsencrypt-dns01-azuredns-wi" + solver := acmev1.ACMEChallengeSolver{ + DNS01: &acmev1.ACMEChallengeSolverDNS01{ + AzureDNS: &acmev1.ACMEIssuerDNS01ProviderAzureDNS{ + SubscriptionID: subscriptionID, + ResourceGroupName: dnsResourceGroupName, + HostedZoneName: hostedZoneName, + ManagedIdentity: &acmev1.AzureManagedIdentity{ + ClientID: identityClientID, + }, + }, + }, + } + clusterIssuer := createACMEClusterIssuer(clusterIssuerName, solver) + _, err = certmanagerClient.CertmanagerV1().ClusterIssuers().Create(ctx, clusterIssuer, metav1.CreateOptions{}) + Expect(err).NotTo(HaveOccurred(), "failed to create ClusterIssuer") + DeferCleanup(func(ctx context.Context) { + certmanagerClient.CertmanagerV1().ClusterIssuers().Delete(ctx, clusterIssuerName, metav1.DeleteOptions{}) + }) + + By("waiting for ClusterIssuer to become ready") + err = waitForClusterIssuerReadiness(ctx, clusterIssuerName) + Expect(err).NotTo(HaveOccurred(), "timeout waiting for ClusterIssuer to become Ready") + + // Create and verify certificate + certName := "letsencrypt-cert-azuredns-wi" + dnsName := fmt.Sprintf("adazwi-%s.%s", randomStr(3), appsDomain) // acronym for "ACME DNS01 AzureDNS Workload Identity" + createAndVerifyACMECertificate(ctx, certName, ns.Name, dnsName, clusterIssuerName, "ClusterIssuer") + }) + }) + Context("with IBM Cloud Internet Service Webhook", Label("Platform:IBM"), func() { // This test uses IBM Cloud Internet Services (CIS) for the DNS-01 challenge. diff --git a/test/e2e/utils_test.go b/test/e2e/utils_test.go index f8f3c3874..c6cd40d80 100644 --- a/test/e2e/utils_test.go +++ b/test/e2e/utils_test.go @@ -367,6 +367,48 @@ func verifyDeploymentEnv(k8sclient *kubernetes.Clientset, deploymentName string, }) } +// addOverrideLabels adds the override labels to specific the cert-manager operand. The update process +// is retried if a conflict error is encountered. +func addOverrideLabels(client *certmanoperatorclient.Clientset, deploymentName string, labels map[string]string) error { + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + operator, err := client.OperatorV1alpha1().CertManagers().Get(context.TODO(), "cluster", metav1.GetOptions{}) + if err != nil { + return err + } + + updatedOperator := operator.DeepCopy() + + switch deploymentName { + case certmanagerControllerDeployment: + cfg := updatedOperator.Spec.ControllerConfig + if cfg == nil { + cfg = &v1alpha1.DeploymentConfig{} + } + cfg.OverrideLabels = labels + updatedOperator.Spec.ControllerConfig = cfg + case certmanagerWebhookDeployment: + cfg := updatedOperator.Spec.WebhookConfig + if cfg == nil { + cfg = &v1alpha1.DeploymentConfig{} + } + cfg.OverrideLabels = labels + updatedOperator.Spec.WebhookConfig = cfg + case certmanagerCAinjectorDeployment: + cfg := updatedOperator.Spec.CAInjectorConfig + if cfg == nil { + cfg = &v1alpha1.DeploymentConfig{} + } + cfg.OverrideLabels = labels + updatedOperator.Spec.CAInjectorConfig = cfg + default: + return fmt.Errorf("unsupported deployment name: %s", deploymentName) + } + + _, err = client.OperatorV1alpha1().CertManagers().Update(context.TODO(), updatedOperator, metav1.UpdateOptions{}) + return err + }) +} + // addOverrideResources adds the override resources to the specific cert-manager operand. The update process // is retried if a conflict error is encountered. func addOverrideResources(client *certmanoperatorclient.Clientset, deploymentName string, res v1alpha1.CertManagerResourceRequirements) error { @@ -793,6 +835,21 @@ func waitForDeploymentArgAndRollout(ctx context.Context, namespace, deploymentNa }, timeout) } +// waitForDeploymentPodLabelAndRollout waits for a deployment's pod template to have +// a specific label and for the rollout to complete. This is useful when waiting for +// operator-driven label changes to propagate to operand deployments, +// as it ensures the expected change has been applied before checking rollout status. +func waitForDeploymentPodLabelAndRollout(ctx context.Context, namespace, deploymentName, labelKey, labelValue string, timeout time.Duration) error { + return waitForDeploymentConditionAndRollout(ctx, namespace, deploymentName, func(deployment *appsv1.Deployment) bool { + labels := deployment.Spec.Template.GetLabels() + if labels == nil { + return false + } + actual, ok := labels[labelKey] + return ok && actual == labelValue + }, timeout) +} + // waitForClusterIssuerReadiness waits for a ClusterIssuer to become Ready func waitForClusterIssuerReadiness(ctx context.Context, clusterIssuerName string) error { return wait.PollUntilContextTimeout(ctx, fastPollInterval, lowTimeout, true, diff --git a/test/go.mod b/test/go.mod index 7d2cdaca2..74899e39c 100644 --- a/test/go.mod +++ b/test/go.mod @@ -3,6 +3,11 @@ module github.com/openshift/cert-manager-operator/test go 1.25.0 require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 github.com/aws/aws-sdk-go-v2 v1.40.0 github.com/aws/aws-sdk-go-v2/config v1.31.12 github.com/aws/aws-sdk-go-v2/service/iam v1.52.1 @@ -10,6 +15,7 @@ require ( github.com/cert-manager/cert-manager v1.19.2 github.com/ghodss/yaml v1.0.0 github.com/google/go-cmp v0.7.0 + github.com/google/uuid v1.6.0 github.com/onsi/ginkgo/v2 v2.27.5 github.com/onsi/gomega v1.39.0 github.com/openshift/api v0.0.0-20260105191300-d1c4dc4fd37b @@ -32,6 +38,8 @@ require ( cloud.google.com/go/auth v0.16.5 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.18.16 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect @@ -72,17 +80,18 @@ require ( github.com/go-openapi/swag/yamlutils v0.24.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect github.com/google/s2a-go v0.1.9 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/krishicks/yaml-patch v0.0.10 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -92,6 +101,7 @@ require ( github.com/nxadm/tail v1.4.11 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect diff --git a/test/go.sum b/test/go.sum index bef916f38..a608e8d98 100644 --- a/test/go.sum +++ b/test/go.sum @@ -4,6 +4,30 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 h1:Hp+EScFOu9HeCbeW8WU2yQPJd4gGwhMgKxWe+G6jNzw= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0 h1:2qsIIvxVT+uE6yrNldntJKlLRgxGbZ85kgtz5SNBhMw= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0/go.mod h1:AW8VEadnhw9xox+VaVd9sP7NjzOAnaZBLRH6Tq3cJ38= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0 h1:L7G3dExHBgUxsO3qpTGhk/P2dgnYyW48yn7AO33Tbek= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0/go.mod h1:Ms6gYEy0+A2knfKrwdatsggTXYA2+ICKug8w7STorFw= +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/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -113,6 +137,8 @@ github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= 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.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -153,6 +179,8 @@ github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= +github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= @@ -205,6 +233,8 @@ github.com/openshift/client-go v0.0.0-20251205093018-96a6cbc1420c h1:TBE0Gl+oCo/ github.com/openshift/client-go v0.0.0-20251205093018-96a6cbc1420c/go.mod h1:IsynOWZAfdH+BgWimcFQRtI41Id9sgdhsCEjIk8ACLw= github.com/openshift/jetstack-cert-manager v1.19.2 h1:P/NabqqbsL+MzeODK8nAcVdzDenaSMWVYKvYlsBWfJI= github.com/openshift/jetstack-cert-manager v1.19.2/go.mod h1:e9NzLtOKxTw7y99qLyWGmPo6mrC1Nh0EKKcMkRfK+GE= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -303,6 +333,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md new file mode 100644 index 000000000..1799c6ef2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md @@ -0,0 +1,892 @@ +# Release History + +## 1.19.1 (2025-09-11) + +### Bugs Fixed + +* Fixed resource identifier parsing for provider-specific resource hierarchies containing "resourceGroups" segments. + +### Other Changes + +* Improved error fall-back for improperly authored long-running operations. +* Upgraded dependencies. + +## 1.19.0 (2025-08-21) + +### Features Added + +* Added `runtime.APIVersionLocationPath` to be set by clients that set the API version in the path. + +## 1.18.2 (2025-07-31) + +### Bugs Fixed + +* Fixed a case in which `BearerTokenPolicy` didn't ensure an authentication error is non-retriable + +## 1.18.1 (2025-07-10) + +### Bugs Fixed + +* Fixed incorrect request/response logging try info when logging a request that's being retried. +* Fixed a data race in `ResourceID.String()` + +## 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 + +* Added field `OperationLocationResultPath` to `runtime.NewPollerOptions[T]` for LROs that use the `Operation-Location` pattern. +* Support `encoding.TextMarshaler` and `encoding.TextUnmarshaler` interfaces in `arm.ResourceID`. + +## 1.16.0 (2024-10-17) + +### Features Added + +* Added field `Kind` to `runtime.StartSpanOptions` to allow a kind to be set when starting a span. + +### Bugs Fixed + +* `BearerTokenPolicy` now rewinds request bodies before retrying + +## 1.15.0 (2024-10-14) + +### Features Added + +* `BearerTokenPolicy` handles CAE claims challenges + +### Bugs Fixed + +* Omit the `ResponseError.RawResponse` field from JSON marshaling so instances can be marshaled. +* Fixed an integer overflow in the retry policy. + +### Other Changes + +* Update dependencies. + +## 1.14.0 (2024-08-07) + +### Features Added + +* Added field `Attributes` to `runtime.StartSpanOptions` to simplify creating spans with attributes. + +### Other Changes + +* Include the HTTP verb and URL in `log.EventRetryPolicy` log entries so it's clear which operation is being retried. + +## 1.13.0 (2024-07-16) + +### Features Added + +- Added runtime.NewRequestFromRequest(), allowing for a policy.Request to be created from an existing *http.Request. + +## 1.12.0 (2024-06-06) + +### Features Added + +* Added field `StatusCodes` to `runtime.FetcherForNextLinkOptions` allowing for additional HTTP status codes indicating success. +* Added func `NewUUID` to the `runtime` package for generating UUIDs. + +### Bugs Fixed + +* Fixed an issue that prevented pollers using the `Operation-Location` strategy from unmarshaling the final result in some cases. + +### Other Changes + +* Updated dependencies. + +## 1.11.1 (2024-04-02) + +### Bugs Fixed + +* Pollers that use the `Location` header won't consider `http.StatusRequestTimeout` a terminal failure. +* `runtime.Poller[T].Result` won't consider non-terminal error responses as terminal. + +## 1.11.0 (2024-04-01) + +### Features Added + +* Added `StatusCodes` to `arm/policy.RegistrationOptions` to allow supporting non-standard HTTP status codes during registration. +* Added field `InsecureAllowCredentialWithHTTP` to `azcore.ClientOptions` and dependent authentication pipeline policies. +* Added type `MultipartContent` to the `streaming` package to support multipart/form payloads with custom Content-Type and file name. + +### Bugs Fixed + +* `runtime.SetMultipartFormData` won't try to stringify `[]byte` values. +* Pollers that use the `Location` header won't consider `http.StatusTooManyRequests` a terminal failure. + +### Other Changes + +* Update dependencies. + +## 1.10.0 (2024-02-29) + +### Features Added + +* Added logging event `log.EventResponseError` that will contain the contents of `ResponseError.Error()` whenever an `azcore.ResponseError` is created. +* Added `runtime.NewResponseErrorWithErrorCode` for creating an `azcore.ResponseError` with a caller-supplied error code. +* Added type `MatchConditions` for use in conditional requests. + +### Bugs Fixed + +* Fixed a potential race condition between `NullValue` and `IsNullValue`. +* `runtime.EncodeQueryParams` will escape semicolons before calling `url.ParseQuery`. + +### Other Changes + +* Update dependencies. + +## 1.9.2 (2024-02-06) + +### Bugs Fixed + +* `runtime.MarshalAsByteArray` and `runtime.MarshalAsJSON` will preserve the preexisting value of the `Content-Type` header. + +### Other Changes + +* Update to latest version of `internal`. + +## 1.9.1 (2023-12-11) + +### Bugs Fixed + +* The `retry-after-ms` and `x-ms-retry-after-ms` headers weren't being checked during retries. + +### Other Changes + +* Update dependencies. + +## 1.9.0 (2023-11-06) + +### Breaking Changes +> These changes affect only code written against previous beta versions of `v1.7.0` and `v1.8.0` +* The function `NewTokenCredential` has been removed from the `fake` package. Use a literal `&fake.TokenCredential{}` instead. +* The field `TracingNamespace` in `runtime.PipelineOptions` has been replaced by `TracingOptions`. + +### Bugs Fixed + +* Fixed an issue that could cause some allowed HTTP header values to not show up in logs. +* Include error text instead of error type in traces when the transport returns an error. +* Fixed an issue that could cause an HTTP/2 request to hang when the TCP connection becomes unresponsive. +* Block key and SAS authentication for non TLS protected endpoints. +* Passing a `nil` credential value will no longer cause a panic. Instead, the authentication is skipped. +* Calling `Error` on a zero-value `azcore.ResponseError` will no longer panic. +* Fixed an issue in `fake.PagerResponder[T]` that would cause a trailing error to be omitted when iterating over pages. +* Context values created by `azcore` will no longer flow across disjoint HTTP requests. + +### Other Changes + +* Skip generating trace info for no-op tracers. +* The `clientName` paramater in client constructors has been renamed to `moduleName`. + +## 1.9.0-beta.1 (2023-10-05) + +### Other Changes + +* The beta features for tracing and fakes have been reinstated. + +## 1.8.0 (2023-10-05) + +### Features Added + +* This includes the following features from `v1.8.0-beta.N` releases. + * Claims and CAE for authentication. + * New `messaging` package. + * Various helpers in the `runtime` package. + * Deprecation of `runtime.With*` funcs and their replacements in the `policy` package. +* Added types `KeyCredential` and `SASCredential` to the `azcore` package. + * Includes their respective constructor functions. +* Added types `KeyCredentialPolicy` and `SASCredentialPolicy` to the `azcore/runtime` package. + * Includes their respective constructor functions and options types. + +### Breaking Changes +> These changes affect only code written against beta versions of `v1.8.0` +* The beta features for tracing and fakes have been omitted for this release. + +### Bugs Fixed + +* Fixed an issue that could cause some ARM RPs to not be automatically registered. +* Block bearer token authentication for non TLS protected endpoints. + +### Other Changes + +* Updated dependencies. + +## 1.8.0-beta.3 (2023-09-07) + +### Features Added + +* Added function `FetcherForNextLink` and `FetcherForNextLinkOptions` to the `runtime` package to centralize creation of `Pager[T].Fetcher` from a next link URL. + +### Bugs Fixed + +* Suppress creating spans for nested SDK API calls. The HTTP span will be a child of the outer API span. + +### Other Changes + +* The following functions in the `runtime` package are now exposed from the `policy` package, and the `runtime` versions have been deprecated. + * `WithCaptureResponse` + * `WithHTTPHeader` + * `WithRetryOptions` + +## 1.7.2 (2023-09-06) + +### Bugs Fixed + +* Fix default HTTP transport to work in WASM modules. + +## 1.8.0-beta.2 (2023-08-14) + +### Features Added + +* Added function `SanitizePagerPollerPath` to the `server` package to centralize sanitization and formalize the contract. +* Added `TokenRequestOptions.EnableCAE` to indicate whether to request a CAE token. + +### Breaking Changes + +> This change affects only code written against beta version `v1.8.0-beta.1`. +* `messaging.CloudEvent` deserializes JSON objects as `[]byte`, instead of `json.RawMessage`. See the documentation for CloudEvent.Data for more information. + +> This change affects only code written against beta versions `v1.7.0-beta.2` and `v1.8.0-beta.1`. +* Removed parameter from method `Span.End()` and its type `tracing.SpanEndOptions`. This API GA'ed in `v1.2.0` so we cannot change it. + +### Bugs Fixed + +* Propagate any query parameters when constructing a fake poller and/or injecting next links. + +## 1.7.1 (2023-08-14) + +## Bugs Fixed + +* Enable TLS renegotiation in the default transport policy. + +## 1.8.0-beta.1 (2023-07-12) + +### Features Added + +- `messaging/CloudEvent` allows you to serialize/deserialize CloudEvents, as described in the CloudEvents 1.0 specification: [link](https://github.com/cloudevents/spec) + +### Other Changes + +* The beta features for CAE, tracing, and fakes have been reinstated. + +## 1.7.0 (2023-07-12) + +### Features Added +* Added method `WithClientName()` to type `azcore.Client` to support shallow cloning of a client with a new name used for tracing. + +### Breaking Changes +> These changes affect only code written against beta versions v1.7.0-beta.1 or v1.7.0-beta.2 +* The beta features for CAE, tracing, and fakes have been omitted for this release. + +## 1.7.0-beta.2 (2023-06-06) + +### Breaking Changes +> These changes affect only code written against beta version v1.7.0-beta.1 +* Method `SpanFromContext()` on type `tracing.Tracer` had the `bool` return value removed. + * This includes the field `SpanFromContext` in supporting type `tracing.TracerOptions`. +* Method `AddError()` has been removed from type `tracing.Span`. +* Method `Span.End()` now requires an argument of type `*tracing.SpanEndOptions`. + +## 1.6.1 (2023-06-06) + +### Bugs Fixed +* Fixed an issue in `azcore.NewClient()` and `arm.NewClient()` that could cause an incorrect module name to be used in telemetry. + +### Other Changes +* This version contains all bug fixes from `v1.7.0-beta.1` + +## 1.7.0-beta.1 (2023-05-24) + +### Features Added +* Restored CAE support for ARM clients. +* Added supporting features to enable distributed tracing. + * Added func `runtime.StartSpan()` for use by SDKs to start spans. + * Added method `WithContext()` to `runtime.Request` to support shallow cloning with a new context. + * Added field `TracingNamespace` to `runtime.PipelineOptions`. + * Added field `Tracer` to `runtime.NewPollerOptions` and `runtime.NewPollerFromResumeTokenOptions` types. + * Added field `SpanFromContext` to `tracing.TracerOptions`. + * Added methods `Enabled()`, `SetAttributes()`, and `SpanFromContext()` to `tracing.Tracer`. + * Added supporting pipeline policies to include HTTP spans when creating clients. +* Added package `fake` to support generated fakes packages in SDKs. + * The package contains public surface area exposed by fake servers and supporting APIs intended only for use by the fake server implementations. + * Added an internal fake poller implementation. + +### Bugs Fixed +* Retry policy always clones the underlying `*http.Request` before invoking the next policy. +* Added some non-standard error codes to the list of error codes for unregistered resource providers. + +## 1.6.0 (2023-05-04) + +### Features Added +* Added support for ARM cross-tenant authentication. Set the `AuxiliaryTenants` field of `arm.ClientOptions` to enable. +* Added `TenantID` field to `policy.TokenRequestOptions`. + +## 1.5.0 (2023-04-06) + +### Features Added +* Added `ShouldRetry` to `policy.RetryOptions` for finer-grained control over when to retry. + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.5.0-beta.1 +> These features will return in v1.6.0-beta.1. +* Removed `TokenRequestOptions.Claims` and `.TenantID` +* Removed ARM client support for CAE and cross-tenant auth. + +### Bugs Fixed +* Added non-conformant LRO terminal states `Cancelled` and `Completed`. + +### Other Changes +* Updated to latest `internal` module. + +## 1.5.0-beta.1 (2023-03-02) + +### Features Added +* This release includes the features added in v1.4.0-beta.1 + +## 1.4.0 (2023-03-02) +> This release doesn't include features added in v1.4.0-beta.1. They will return in v1.5.0-beta.1. + +### Features Added +* Add `Clone()` method for `arm/policy.ClientOptions`. + +### Bugs Fixed +* ARM's RP registration policy will no longer swallow unrecognized errors. +* Fixed an issue in `runtime.NewPollerFromResumeToken()` when resuming a `Poller` with a custom `PollingHandler`. +* Fixed wrong policy copy in `arm/runtime.NewPipeline()`. + +## 1.4.0-beta.1 (2023-02-02) + +### Features Added +* Added support for ARM cross-tenant authentication. Set the `AuxiliaryTenants` field of `arm.ClientOptions` to enable. +* Added `Claims` and `TenantID` fields to `policy.TokenRequestOptions`. +* ARM bearer token policy handles CAE challenges. + +## 1.3.1 (2023-02-02) + +### Other Changes +* Update dependencies to latest versions. + +## 1.3.0 (2023-01-06) + +### Features Added +* Added `BearerTokenOptions.AuthorizationHandler` to enable extending `runtime.BearerTokenPolicy` + with custom authorization logic +* Added `Client` types and matching constructors to the `azcore` and `arm` packages. These represent a basic client for HTTP and ARM respectively. + +### Other Changes +* Updated `internal` module to latest version. +* `policy/Request.SetBody()` allows replacing a request's body with an empty one + +## 1.2.0 (2022-11-04) + +### Features Added +* Added `ClientOptions.APIVersion` field, which overrides the default version a client + requests of the service, if the client supports this (all ARM clients do). +* Added package `tracing` that contains the building blocks for distributed tracing. +* Added field `TracingProvider` to type `policy.ClientOptions` that will be used to set the per-client tracing implementation. + +### Bugs Fixed +* Fixed an issue in `runtime.SetMultipartFormData` to properly handle slices of `io.ReadSeekCloser`. +* Fixed the MaxRetryDelay default to be 60s. +* Failure to poll the state of an LRO will now return an `*azcore.ResponseError` for poller types that require this behavior. +* Fixed a bug in `runtime.NewPipeline` that would cause pipeline-specified allowed headers and query parameters to be lost. + +### Other Changes +* Retain contents of read-only fields when sending requests. + +## 1.1.4 (2022-10-06) + +### Bugs Fixed +* Don't retry a request if the `Retry-After` delay is greater than the configured `RetryOptions.MaxRetryDelay`. +* `runtime.JoinPaths`: do not unconditionally add a forward slash before the query string + +### Other Changes +* Removed logging URL from retry policy as it's redundant. +* Retry policy logs when it exits due to a non-retriable status code. + +## 1.1.3 (2022-09-01) + +### Bugs Fixed +* Adjusted the initial retry delay to 800ms per the Azure SDK guidelines. + +## 1.1.2 (2022-08-09) + +### Other Changes +* Fixed various doc bugs. + +## 1.1.1 (2022-06-30) + +### Bugs Fixed +* Avoid polling when a RELO LRO synchronously terminates. + +## 1.1.0 (2022-06-03) + +### Other Changes +* The one-second floor for `Frequency` when calling `PollUntilDone()` has been removed when running tests. + +## 1.0.0 (2022-05-12) + +### Features Added +* Added interface `runtime.PollingHandler` to support custom poller implementations. + * Added field `PollingHandler` of this type to `runtime.NewPollerOptions[T]` and `runtime.NewPollerFromResumeTokenOptions[T]`. + +### Breaking Changes +* Renamed `cloud.Configuration.LoginEndpoint` to `.ActiveDirectoryAuthorityHost` +* Renamed `cloud.AzurePublicCloud` to `cloud.AzurePublic` +* Removed `AuxiliaryTenants` field from `arm/ClientOptions` and `arm/policy/BearerTokenOptions` +* Removed `TokenRequestOptions.TenantID` +* `Poller[T].PollUntilDone()` now takes an `options *PollUntilDoneOptions` param instead of `freq time.Duration` +* Removed `arm/runtime.Poller[T]`, `arm/runtime.NewPoller[T]()` and `arm/runtime.NewPollerFromResumeToken[T]()` +* Removed `arm/runtime.FinalStateVia` and related `const` values +* Renamed `runtime.PageProcessor` to `runtime.PagingHandler` +* The `arm/runtime.ProviderRepsonse` and `arm/runtime.Provider` types are no longer exported. +* Renamed `NewRequestIdPolicy()` to `NewRequestIDPolicy()` +* `TokenCredential.GetToken` now returns `AccessToken` by value. + +### Bugs Fixed +* When per-try timeouts are enabled, only cancel the context after the body has been read and closed. +* The `Operation-Location` poller now properly handles `final-state-via` values. +* Improvements in `runtime.Poller[T]` + * `Poll()` shouldn't cache errors, allowing for additional retries when in a non-terminal state. + * `Result()` will cache the terminal result or error but not transient errors, allowing for additional retries. + +### Other Changes +* Updated to latest `internal` module and absorbed breaking changes. + * Use `temporal.Resource` and deleted copy. +* The internal poller implementation has been refactored. + * The implementation in `internal/pollers/poller.go` has been merged into `runtime/poller.go` with some slight modification. + * The internal poller types had their methods updated to conform to the `runtime.PollingHandler` interface. + * The creation of resume tokens has been refactored so that implementers of `runtime.PollingHandler` don't need to know about it. +* `NewPipeline()` places policies from `ClientOptions` after policies from `PipelineOptions` +* Default User-Agent headers no longer include `azcore` version information + +## 0.23.1 (2022-04-14) + +### Bugs Fixed +* Include XML header when marshalling XML content. +* Handle XML namespaces when searching for error code. +* Handle `odata.error` when searching for error code. + +## 0.23.0 (2022-04-04) + +### Features Added +* Added `runtime.Pager[T any]` and `runtime.Poller[T any]` supporting types for central, generic, implementations. +* Added `cloud` package with a new API for cloud configuration +* Added `FinalStateVia` field to `runtime.NewPollerOptions[T any]` type. + +### Breaking Changes +* Removed the `Poller` type-alias to the internal poller implementation. +* Added `Ptr[T any]` and `SliceOfPtrs[T any]` in the `to` package and removed all non-generic implementations. +* `NullValue` and `IsNullValue` now take a generic type parameter instead of an interface func parameter. +* Replaced `arm.Endpoint` with `cloud` API + * Removed the `endpoint` parameter from `NewRPRegistrationPolicy()` + * `arm/runtime.NewPipeline()` and `.NewRPRegistrationPolicy()` now return an `error` +* Refactored `NewPoller` and `NewPollerFromResumeToken` funcs in `arm/runtime` and `runtime` packages. + * Removed the `pollerID` parameter as it's no longer required. + * Created optional parameter structs and moved optional parameters into them. +* Changed `FinalStateVia` field to a `const` type. + +### Other Changes +* Converted expiring resource and dependent types to use generics. + +## 0.22.0 (2022-03-03) + +### Features Added +* Added header `WWW-Authenticate` to the default allow-list of headers for logging. +* Added a pipeline policy that enables the retrieval of HTTP responses from API calls. + * Added `runtime.WithCaptureResponse` to enable the policy at the API level (off by default). + +### Breaking Changes +* Moved `WithHTTPHeader` and `WithRetryOptions` from the `policy` package to the `runtime` package. + +## 0.21.1 (2022-02-04) + +### Bugs Fixed +* Restore response body after reading in `Poller.FinalResponse()`. (#16911) +* Fixed bug in `NullValue` that could lead to incorrect comparisons for empty maps/slices (#16969) + +### Other Changes +* `BearerTokenPolicy` is more resilient to transient authentication failures. (#16789) + +## 0.21.0 (2022-01-11) + +### Features Added +* Added `AllowedHeaders` and `AllowedQueryParams` to `policy.LogOptions` to control which headers and query parameters are written to the logger. +* Added `azcore.ResponseError` type which is returned from APIs when a non-success HTTP status code is received. + +### Breaking Changes +* Moved `[]policy.Policy` parameters of `arm/runtime.NewPipeline` and `runtime.NewPipeline` into a new struct, `runtime.PipelineOptions` +* Renamed `arm/ClientOptions.Host` to `.Endpoint` +* Moved `Request.SkipBodyDownload` method to function `runtime.SkipBodyDownload` +* Removed `azcore.HTTPResponse` interface type +* `arm.NewPoller()` and `runtime.NewPoller()` no longer require an `eu` parameter +* `runtime.NewResponseError()` no longer requires an `error` parameter + +## 0.20.0 (2021-10-22) + +### Breaking Changes +* Removed `arm.Connection` +* Removed `azcore.Credential` and `.NewAnonymousCredential()` + * `NewRPRegistrationPolicy` now requires an `azcore.TokenCredential` +* `runtime.NewPipeline` has a new signature that simplifies implementing custom authentication +* `arm/runtime.RegistrationOptions` embeds `policy.ClientOptions` +* Contents in the `log` package have been slightly renamed. +* Removed `AuthenticationOptions` in favor of `policy.BearerTokenOptions` +* Changed parameters for `NewBearerTokenPolicy()` +* Moved policy config options out of `arm/runtime` and into `arm/policy` + +### Features Added +* Updating Documentation +* Added string typdef `arm.Endpoint` to provide a hint toward expected ARM client endpoints +* `azcore.ClientOptions` contains common pipeline configuration settings +* Added support for multi-tenant authorization in `arm/runtime` +* Require one second minimum when calling `PollUntilDone()` + +### Bug Fixes +* Fixed a potential panic when creating the default Transporter. +* Close LRO initial response body when creating a poller. +* Fixed a panic when recursively cloning structs that contain time.Time. + +## 0.19.0 (2021-08-25) + +### Breaking Changes +* Split content out of `azcore` into various packages. The intent is to separate content based on its usage (common, uncommon, SDK authors). + * `azcore` has all core functionality. + * `log` contains facilities for configuring in-box logging. + * `policy` is used for configuring pipeline options and creating custom pipeline policies. + * `runtime` contains various helpers used by SDK authors and generated content. + * `streaming` has helpers for streaming IO operations. +* `NewTelemetryPolicy()` now requires module and version parameters and the `Value` option has been removed. + * As a result, the `Request.Telemetry()` method has been removed. +* The telemetry policy now includes the SDK prefix `azsdk-go-` so callers no longer need to provide it. +* The `*http.Request` in `runtime.Request` is no longer anonymously embedded. Use the `Raw()` method to access it. +* The `UserAgent` and `Version` constants have been made internal, `Module` and `Version` respectively. + +### Bug Fixes +* Fixed an issue in the retry policy where the request body could be overwritten after a rewind. + +### Other Changes +* Moved modules `armcore` and `to` content into `arm` and `to` packages respectively. + * The `Pipeline()` method on `armcore.Connection` has been replaced by `NewPipeline()` in `arm.Connection`. It takes module and version parameters used by the telemetry policy. +* Poller logic has been consolidated across ARM and core implementations. + * This required some changes to the internal interfaces for core pollers. +* The core poller types have been improved, including more logging and test coverage. + +## 0.18.1 (2021-08-20) + +### Features Added +* Adds an `ETag` type for comparing etags and handling etags on requests +* Simplifies the `requestBodyProgess` and `responseBodyProgress` into a single `progress` object + +### Bugs Fixed +* `JoinPaths` will preserve query parameters encoded in the `root` url. + +### Other Changes +* Bumps dependency on `internal` module to the latest version (v0.7.0) + +## 0.18.0 (2021-07-29) +### Features Added +* Replaces methods from Logger type with two package methods for interacting with the logging functionality. +* `azcore.SetClassifications` replaces `azcore.Logger().SetClassifications` +* `azcore.SetListener` replaces `azcore.Logger().SetListener` + +### Breaking Changes +* Removes `Logger` type from `azcore` + + +## 0.17.0 (2021-07-27) +### Features Added +* Adding TenantID to TokenRequestOptions (https://github.com/Azure/azure-sdk-for-go/pull/14879) +* Adding AuxiliaryTenants to AuthenticationOptions (https://github.com/Azure/azure-sdk-for-go/pull/15123) + +### Breaking Changes +* Rename `AnonymousCredential` to `NewAnonymousCredential` (https://github.com/Azure/azure-sdk-for-go/pull/15104) +* rename `AuthenticationPolicyOptions` to `AuthenticationOptions` (https://github.com/Azure/azure-sdk-for-go/pull/15103) +* Make Header constants private (https://github.com/Azure/azure-sdk-for-go/pull/15038) + + +## 0.16.2 (2021-05-26) +### Features Added +* Improved support for byte arrays [#14715](https://github.com/Azure/azure-sdk-for-go/pull/14715) + + +## 0.16.1 (2021-05-19) +### Features Added +* Add license.txt to azcore module [#14682](https://github.com/Azure/azure-sdk-for-go/pull/14682) + + +## 0.16.0 (2021-05-07) +### Features Added +* Remove extra `*` in UnmarshalAsByteArray() [#14642](https://github.com/Azure/azure-sdk-for-go/pull/14642) + + +## 0.15.1 (2021-05-06) +### Features Added +* Cache the original request body on Request [#14634](https://github.com/Azure/azure-sdk-for-go/pull/14634) + + +## 0.15.0 (2021-05-05) +### Features Added +* Add support for null map and slice +* Export `Response.Payload` method + +### Breaking Changes +* remove `Response.UnmarshalError` as it's no longer required + + +## 0.14.5 (2021-04-23) +### Features Added +* Add `UnmarshalError()` on `azcore.Response` + + +## 0.14.4 (2021-04-22) +### Features Added +* Support for basic LRO polling +* Added type `LROPoller` and supporting types for basic polling on long running operations. +* rename poller param and added doc comment + +### Bugs Fixed +* Fixed content type detection bug in logging. + + +## 0.14.3 (2021-03-29) +### Features Added +* Add support for multi-part form data +* Added method `WriteMultipartFormData()` to Request. + + +## 0.14.2 (2021-03-17) +### Features Added +* Add support for encoding JSON null values +* Adds `NullValue()` and `IsNullValue()` functions for setting and detecting sentinel values used for encoding a JSON null. +* Documentation fixes + +### Bugs Fixed +* Fixed improper error wrapping + + +## 0.14.1 (2021-02-08) +### Features Added +* Add `Pager` and `Poller` interfaces to azcore + + +## 0.14.0 (2021-01-12) +### Features Added +* Accept zero-value options for default values +* Specify zero-value options structs to accept default values. +* Remove `DefaultXxxOptions()` methods. +* Do not silently change TryTimeout on negative values +* make per-try timeout opt-in + + +## 0.13.4 (2020-11-20) +### Features Added +* Include telemetry string in User Agent + + +## 0.13.3 (2020-11-20) +### Features Added +* Updating response body handling on `azcore.Response` + + +## 0.13.2 (2020-11-13) +### Features Added +* Remove implementation of stateless policies as first-class functions. + + +## 0.13.1 (2020-11-05) +### Features Added +* Add `Telemetry()` method to `azcore.Request()` + + +## 0.13.0 (2020-10-14) +### Features Added +* Rename `log` to `logger` to avoid name collision with the log package. +* Documentation improvements +* Simplified `DefaultHTTPClientTransport()` implementation + + +## 0.12.1 (2020-10-13) +### Features Added +* Update `internal` module dependence to `v0.5.0` + + +## 0.12.0 (2020-10-08) +### Features Added +* Removed storage specific content +* Removed internal content to prevent API clutter +* Refactored various policy options to conform with our options pattern + + +## 0.11.0 (2020-09-22) +### Features Added + +* Removed `LogError` and `LogSlowResponse`. +* Renamed `options` in `RequestLogOptions`. +* Updated `NewRequestLogPolicy()` to follow standard pattern for options. +* Refactored `requestLogPolicy.Do()` per above changes. +* Cleaned up/added logging in retry policy. +* Export `NewResponseError()` +* Fix `RequestLogOptions` comment + + +## 0.10.1 (2020-09-17) +### Features Added +* Add default console logger +* Default console logger writes to stderr. To enable it, set env var `AZURE_SDK_GO_LOGGING` to the value 'all'. +* Added `Logger.Writef()` to reduce the need for `ShouldLog()` checks. +* Add `LogLongRunningOperation` + + +## 0.10.0 (2020-09-10) +### Features Added +* The `request` and `transport` interfaces have been refactored to align with the patterns in the standard library. +* `NewRequest()` now uses `http.NewRequestWithContext()` and performs additional validation, it also requires a context parameter. +* The `Policy` and `Transport` interfaces have had their context parameter removed as the context is associated with the underlying `http.Request`. +* `Pipeline.Do()` will validate the HTTP request before sending it through the pipeline, avoiding retries on a malformed request. +* The `Retrier` interface has been replaced with the `NonRetriableError` interface, and the retry policy updated to test for this. +* `Request.SetBody()` now requires a content type parameter for setting the request's MIME type. +* moved path concatenation into `JoinPaths()` func + + +## 0.9.6 (2020-08-18) +### Features Added +* Improvements to body download policy +* Always download the response body for error responses, i.e. HTTP status codes >= 400. +* Simplify variable declarations + + +## 0.9.5 (2020-08-11) +### Features Added +* Set the Content-Length header in `Request.SetBody` + + +## 0.9.4 (2020-08-03) +### Features Added +* Fix cancellation of per try timeout +* Per try timeout is used to ensure that an HTTP operation doesn't take too long, e.g. that a GET on some URL doesn't take an inordinant amount of time. +* Once the HTTP request returns, the per try timeout should be cancelled, not when the response has been read to completion. +* Do not drain response body if there are no more retries +* Do not retry non-idempotent operations when body download fails + + +## 0.9.3 (2020-07-28) +### Features Added +* Add support for custom HTTP request headers +* Inserts an internal policy into the pipeline that can extract HTTP header values from the caller's context, adding them to the request. +* Use `azcore.WithHTTPHeader` to add HTTP headers to a context. +* Remove method specific to Go 1.14 + + +## 0.9.2 (2020-07-28) +### Features Added +* Omit read-only content from request payloads +* If any field in a payload's object graph contains `azure:"ro"`, make a clone of the object graph, omitting all fields with this annotation. +* Verify no fields were dropped +* Handle embedded struct types +* Added test for cloning by value +* Add messages to failures + + +## 0.9.1 (2020-07-22) +### Features Added +* Updated dependency on internal module to fix race condition. + + +## 0.9.0 (2020-07-09) +### Features Added +* Add `HTTPResponse` interface to be used by callers to access the raw HTTP response from an error in the event of an API call failure. +* Updated `sdk/internal` dependency to latest version. +* Rename package alias + + +## 0.8.2 (2020-06-29) +### Features Added +* Added missing documentation comments + +### Bugs Fixed +* Fixed a bug in body download policy. + + +## 0.8.1 (2020-06-26) +### Features Added +* Miscellaneous clean-up reported by linters + + +## 0.8.0 (2020-06-01) +### Features Added +* Differentiate between standard and URL encoding. + + +## 0.7.1 (2020-05-27) +### Features Added +* Add support for for base64 encoding and decoding of payloads. + + +## 0.7.0 (2020-05-12) +### Features Added +* Change `RetryAfter()` to a function. + + +## 0.6.0 (2020-04-29) +### Features Added +* Updating `RetryAfter` to only return the detaion in the RetryAfter header + + +## 0.5.0 (2020-03-23) +### Features Added +* Export `TransportFunc` + +### Breaking Changes +* Removed `IterationDone` + + +## 0.4.1 (2020-02-25) +### Features Added +* Ensure per-try timeout is properly cancelled +* Explicitly call cancel the per-try timeout when the response body has been read/closed by the body download policy. +* When the response body is returned to the caller for reading/closing, wrap it in a `responseBodyReader` that will cancel the timeout when the body is closed. +* `Logger.Should()` will return false if no listener is set. + + +## 0.4.0 (2020-02-18) +### Features Added +* Enable custom `RetryOptions` to be specified per API call +* Added `WithRetryOptions()` that adds a custom `RetryOptions` to the provided context, allowing custom settings per API call. +* Remove 429 from the list of default HTTP status codes for retry. +* Change StatusCodesForRetry to a slice so consumers can append to it. +* Added support for retry-after in HTTP-date format. +* Cleaned up some comments specific to storage. +* Remove `Request.SetQueryParam()` +* Renamed `MaxTries` to `MaxRetries` + +## 0.3.0 (2020-01-16) +### Features Added +* Added `DefaultRetryOptions` to create initialized default options. + +### Breaking Changes +* Removed `Response.CheckStatusCode()` + + +## 0.2.0 (2020-01-15) +### Features Added +* Add support for marshalling and unmarshalling JSON +* Removed `Response.Payload` field +* Exit early when unmarsahlling if there is no payload + + +## 0.1.0 (2020-01-10) +### Features Added +* Initial release diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/LICENSE.txt new file mode 100644 index 000000000..48ea6616b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/README.md new file mode 100644 index 000000000..35a74e18d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/README.md @@ -0,0 +1,39 @@ +# Azure Core Client Module for Go + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/azcore)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore) +[![Build Status](https://dev.azure.com/azure-sdk/public/_apis/build/status/go/go%20-%20azcore%20-%20ci?branchName=main)](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=1843&branchName=main) +[![Code Coverage](https://img.shields.io/azure-devops/coverage/azure-sdk/public/1843/main)](https://img.shields.io/azure-devops/coverage/azure-sdk/public/1843/main) + +The `azcore` module provides a set of common interfaces and types for Go SDK client modules. +These modules follow the [Azure SDK Design Guidelines for Go](https://azure.github.io/azure-sdk/golang_introduction.html). + +## Getting started + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Typically, you will not need to explicitly install `azcore` as it will be installed as a client module dependency. +To add the latest version to your `go.mod` file, execute the following command. + +```bash +go get github.com/Azure/azure-sdk-for-go/sdk/azcore +``` + +General documentation and examples can be found on [pkg.go.dev](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore). + +## Contributing +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. +For details, visit [https://cla.microsoft.com](https://cla.microsoft.com). + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only +need to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information, see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go new file mode 100644 index 000000000..c373cc43f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/client.go @@ -0,0 +1,72 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package arm + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + armruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +// ClientOptions contains configuration settings for a client's pipeline. +type ClientOptions = armpolicy.ClientOptions + +// Client is a HTTP client for use with ARM endpoints. It consists of an endpoint, pipeline, and tracing provider. +type Client struct { + ep string + pl runtime.Pipeline + tr tracing.Tracer +} + +// NewClient creates a new Client instance with the provided values. +// This client is intended to be used with Azure Resource Manager endpoints. +// - moduleName - the fully qualified name of the module where the client is defined; used by the telemetry policy and tracing provider. +// - moduleVersion - the semantic version of the module; used by the telemetry policy and tracing provider. +// - cred - the TokenCredential used to authenticate the request +// - options - optional client configurations; pass nil to accept the default values +func NewClient(moduleName, moduleVersion string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) { + if options == nil { + options = &ClientOptions{} + } + + if !options.Telemetry.Disabled { + if err := shared.ValidateModVer(moduleVersion); err != nil { + return nil, err + } + } + + ep := cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint + if c, ok := options.Cloud.Services[cloud.ResourceManager]; ok { + ep = c.Endpoint + } + pl, err := armruntime.NewPipeline(moduleName, moduleVersion, cred, runtime.PipelineOptions{}, options) + if err != nil { + return nil, err + } + + tr := options.TracingProvider.NewTracer(moduleName, moduleVersion) + return &Client{ep: ep, pl: pl, tr: tr}, nil +} + +// Endpoint returns the service's base URL for this client. +func (c *Client) Endpoint() string { + return c.ep +} + +// Pipeline returns the pipeline for this client. +func (c *Client) Pipeline() runtime.Pipeline { + return c.pl +} + +// Tracer returns the tracer for this client. +func (c *Client) Tracer() tracing.Tracer { + return c.tr +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go new file mode 100644 index 000000000..1bdd16a3d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/doc.go @@ -0,0 +1,9 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package arm contains functionality specific to Azure Resource Manager clients. +package arm diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go new file mode 100644 index 000000000..b8348b7d8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_identifier.go @@ -0,0 +1,242 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package resource + +import ( + "fmt" + "strings" +) + +const ( + providersKey = "providers" + subscriptionsKey = "subscriptions" + resourceGroupsLowerKey = "resourcegroups" + locationsKey = "locations" + builtInResourceNamespace = "Microsoft.Resources" +) + +// RootResourceID defines the tenant as the root parent of all other ResourceID. +var RootResourceID = &ResourceID{ + Parent: nil, + ResourceType: TenantResourceType, + Name: "", +} + +// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`. +// Don't create this type directly, use [ParseResourceID] instead. Fields are considered immutable and shouldn't be +// modified after creation. +type ResourceID struct { + // Parent is the parent ResourceID of this instance. + // Can be nil if there is no parent. + Parent *ResourceID + + // SubscriptionID is the subscription ID in this resource ID. + // The value can be empty if the resource ID does not contain a subscription ID. + SubscriptionID string + + // ResourceGroupName is the resource group name in this resource ID. + // The value can be empty if the resource ID does not contain a resource group name. + ResourceGroupName string + + // Provider represents the provider name in this resource ID. + // This is only valid when the resource ID represents a resource provider. + // Example: `/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Insights` + Provider string + + // Location is the location in this resource ID. + // The value can be empty if the resource ID does not contain a location name. + Location string + + // ResourceType represents the type of this resource ID. + ResourceType ResourceType + + // Name is the resource name of this resource ID. + Name string + + isChild bool + stringValue string +} + +// ParseResourceID parses a string to an instance of ResourceID +func ParseResourceID(id string) (*ResourceID, error) { + if len(id) == 0 { + return nil, fmt.Errorf("invalid resource ID: id cannot be empty") + } + + if !strings.HasPrefix(id, "/") { + return nil, fmt.Errorf("invalid resource ID: resource id '%s' must start with '/'", id) + } + + parts := splitStringAndOmitEmpty(id, "/") + + if len(parts) < 2 { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + if !strings.EqualFold(parts[0], subscriptionsKey) && !strings.EqualFold(parts[0], providersKey) { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + return appendNext(RootResourceID, parts, id) +} + +// String returns the string of the ResourceID +func (id *ResourceID) String() string { + return id.stringValue +} + +// MarshalText returns a textual representation of the ResourceID +func (id *ResourceID) MarshalText() ([]byte, error) { + return []byte(id.String()), nil +} + +// UnmarshalText decodes the textual representation of a ResourceID +func (id *ResourceID) UnmarshalText(text []byte) error { + newId, err := ParseResourceID(string(text)) + if err != nil { + return err + } + *id = *newId + return nil +} + +func newResourceID(parent *ResourceID, resourceTypeName string, resourceName string) *ResourceID { + id := &ResourceID{} + id.init(parent, chooseResourceType(resourceTypeName, parent), resourceName, true) + return id +} + +func newResourceIDWithResourceType(parent *ResourceID, resourceType ResourceType, resourceName string) *ResourceID { + id := &ResourceID{} + id.init(parent, resourceType, resourceName, true) + return id +} + +func newResourceIDWithProvider(parent *ResourceID, providerNamespace, resourceTypeName, resourceName string) *ResourceID { + id := &ResourceID{} + id.init(parent, NewResourceType(providerNamespace, resourceTypeName), resourceName, false) + return id +} + +func chooseResourceType(resourceTypeName string, parent *ResourceID) ResourceType { + if strings.EqualFold(resourceTypeName, resourceGroupsLowerKey) && isSubscriptionResource(parent) { + return ResourceGroupResourceType + } else if strings.EqualFold(resourceTypeName, subscriptionsKey) && isTenantResource(parent) { + return SubscriptionResourceType + } + + return parent.ResourceType.AppendChild(resourceTypeName) +} + +func (id *ResourceID) init(parent *ResourceID, resourceType ResourceType, name string, isChild bool) { + if parent != nil { + id.Provider = parent.Provider + id.SubscriptionID = parent.SubscriptionID + id.ResourceGroupName = parent.ResourceGroupName + id.Location = parent.Location + } + + if resourceType.String() == SubscriptionResourceType.String() { + id.SubscriptionID = name + } + + if resourceType.lastType() == locationsKey { + id.Location = name + } + + if resourceType.String() == ResourceGroupResourceType.String() { + id.ResourceGroupName = name + } + + if resourceType.String() == ProviderResourceType.String() { + id.Provider = name + } + + if parent == nil { + id.Parent = RootResourceID + } else { + id.Parent = parent + } + id.isChild = isChild + id.ResourceType = resourceType + id.Name = name + id.stringValue = id.Parent.String() + if id.isChild { + id.stringValue += "/" + id.ResourceType.lastType() + if id.Name != "" { + id.stringValue += "/" + id.Name + } + } else { + id.stringValue += fmt.Sprintf("/providers/%s/%s/%s", id.ResourceType.Namespace, id.ResourceType.Type, id.Name) + } +} + +func appendNext(parent *ResourceID, parts []string, id string) (*ResourceID, error) { + if len(parts) == 0 { + return parent, nil + } + + if len(parts) == 1 { + // subscriptions and resourceGroups are not valid ids without their names + if strings.EqualFold(parts[0], subscriptionsKey) && isTenantResource(parent) || strings.EqualFold(parts[0], resourceGroupsLowerKey) && isSubscriptionResource(parent) { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + // resourceGroup must contain either child or provider resource type + if isResourceGroupResource(parent) { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + return newResourceID(parent, parts[0], ""), nil + } + + if strings.EqualFold(parts[0], providersKey) && (len(parts) == 2 || strings.EqualFold(parts[2], providersKey)) { + // provider resource can only be on a tenant or a subscription parent + if !isSubscriptionResource(parent) && !isTenantResource(parent) { + return nil, fmt.Errorf("invalid resource ID: %s", id) + } + + return appendNext(newResourceIDWithResourceType(parent, ProviderResourceType, parts[1]), parts[2:], id) + } + + if len(parts) > 3 && strings.EqualFold(parts[0], providersKey) { + return appendNext(newResourceIDWithProvider(parent, parts[1], parts[2], parts[3]), parts[4:], id) + } + + if len(parts) > 1 && !strings.EqualFold(parts[0], providersKey) { + return appendNext(newResourceID(parent, parts[0], parts[1]), parts[2:], id) + } + + return nil, fmt.Errorf("invalid resource ID: %s", id) +} + +func splitStringAndOmitEmpty(v, sep string) []string { + r := make([]string, 0) + for _, s := range strings.Split(v, sep) { + if len(s) == 0 { + continue + } + r = append(r, s) + } + + return r +} + +// isTenantResource returns true if the resourceID represents a tenant resource. The condition is resource ID matched with TenantResourceType and has no parent. +func isTenantResource(resourceID *ResourceID) bool { + return resourceID != nil && strings.EqualFold(resourceID.ResourceType.String(), TenantResourceType.String()) && resourceID.Parent == nil +} + +// isSubscriptionResource returns true if the resourceID represents a subscription resource. The condition is resource ID matched with SubscriptionResourceType and its parent is a tenant resource. +func isSubscriptionResource(resourceID *ResourceID) bool { + return resourceID != nil && strings.EqualFold(resourceID.ResourceType.String(), SubscriptionResourceType.String()) && isTenantResource(resourceID.Parent) +} + +// isResourceGroupResource returns true if the resourceID represents a resource group resource. The condition is resource ID matched with ResourceGroupResourceType and its parent is a subscription resource. +func isResourceGroupResource(resourceID *ResourceID) bool { + return resourceID != nil && strings.EqualFold(resourceID.ResourceType.String(), ResourceGroupResourceType.String()) && isSubscriptionResource(resourceID.Parent) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go new file mode 100644 index 000000000..ca03ac971 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource/resource_type.go @@ -0,0 +1,114 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package resource + +import ( + "fmt" + "strings" +) + +// SubscriptionResourceType is the ResourceType of a subscription +var SubscriptionResourceType = NewResourceType(builtInResourceNamespace, "subscriptions") + +// ResourceGroupResourceType is the ResourceType of a resource group +var ResourceGroupResourceType = NewResourceType(builtInResourceNamespace, "resourceGroups") + +// TenantResourceType is the ResourceType of a tenant +var TenantResourceType = NewResourceType(builtInResourceNamespace, "tenants") + +// ProviderResourceType is the ResourceType of a provider +var ProviderResourceType = NewResourceType(builtInResourceNamespace, "providers") + +// ResourceType represents an Azure resource type, e.g. "Microsoft.Network/virtualNetworks/subnets". +// Don't create this type directly, use ParseResourceType or NewResourceType instead. +type ResourceType struct { + // Namespace is the namespace of the resource type. + // e.g. "Microsoft.Network" in resource type "Microsoft.Network/virtualNetworks/subnets" + Namespace string + + // Type is the full type name of the resource type. + // e.g. "virtualNetworks/subnets" in resource type "Microsoft.Network/virtualNetworks/subnets" + Type string + + // Types is the slice of all the sub-types of this resource type. + // e.g. ["virtualNetworks", "subnets"] in resource type "Microsoft.Network/virtualNetworks/subnets" + Types []string + + stringValue string +} + +// String returns the string of the ResourceType +func (t ResourceType) String() string { + return t.stringValue +} + +// IsParentOf returns true when the receiver is the parent resource type of the child. +func (t ResourceType) IsParentOf(child ResourceType) bool { + if !strings.EqualFold(t.Namespace, child.Namespace) { + return false + } + if len(t.Types) >= len(child.Types) { + return false + } + for i := range t.Types { + if !strings.EqualFold(t.Types[i], child.Types[i]) { + return false + } + } + + return true +} + +// AppendChild creates an instance of ResourceType using the receiver as the parent with childType appended to it. +func (t ResourceType) AppendChild(childType string) ResourceType { + return NewResourceType(t.Namespace, fmt.Sprintf("%s/%s", t.Type, childType)) +} + +// NewResourceType creates an instance of ResourceType using a provider namespace +// such as "Microsoft.Network" and type such as "virtualNetworks/subnets". +func NewResourceType(providerNamespace, typeName string) ResourceType { + return ResourceType{ + Namespace: providerNamespace, + Type: typeName, + Types: splitStringAndOmitEmpty(typeName, "/"), + stringValue: fmt.Sprintf("%s/%s", providerNamespace, typeName), + } +} + +// ParseResourceType parses the ResourceType from a resource type string (e.g. Microsoft.Network/virtualNetworks/subsets) +// or a resource identifier string. +// e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mySubnet) +func ParseResourceType(resourceIDOrType string) (ResourceType, error) { + // split the path into segments + parts := splitStringAndOmitEmpty(resourceIDOrType, "/") + + // There must be at least a namespace and type name + if len(parts) < 1 { + return ResourceType{}, fmt.Errorf("invalid resource ID or type: %s", resourceIDOrType) + } + + // if the type is just subscriptions, it is a built-in type in the Microsoft.Resources namespace + if len(parts) == 1 { + // Simple resource type + return NewResourceType(builtInResourceNamespace, parts[0]), nil + } else if strings.Contains(parts[0], ".") { + // Handle resource types (Microsoft.Compute/virtualMachines, Microsoft.Network/virtualNetworks/subnets) + // it is a full type name + return NewResourceType(parts[0], strings.Join(parts[1:], "/")), nil + } else { + // Check if ResourceID + id, err := ParseResourceID(resourceIDOrType) + if err != nil { + return ResourceType{}, err + } + return NewResourceType(id.ResourceType.Namespace, id.ResourceType.Type), nil + } +} + +func (t ResourceType) lastType() string { + return t.Types[len(t.Types)-1] +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go new file mode 100644 index 000000000..f18caf848 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy/policy.go @@ -0,0 +1,108 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package policy + +import ( + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// BearerTokenOptions configures the bearer token policy's behavior. +type BearerTokenOptions struct { + // AuxiliaryTenants are additional tenant IDs for authenticating cross-tenant requests. + // The policy will add a token from each of these tenants to every request. The + // authenticating user or service principal must be a guest in these tenants, and the + // policy's credential must support multitenant authentication. + AuxiliaryTenants []string + + // InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP. + // By default, authenticated requests to an HTTP endpoint are rejected by the client. + // WARNING: setting this to true will allow sending the authentication key in clear text. Use with caution. + InsecureAllowCredentialWithHTTP bool + + // Scopes contains the list of permission scopes required for the token. + Scopes []string +} + +// RegistrationOptions configures the registration policy's behavior. +// All zero-value fields will be initialized with their default values. +type RegistrationOptions struct { + policy.ClientOptions + + // MaxAttempts is the total number of times to attempt automatic registration + // in the event that an attempt fails. + // The default value is 3. + // Set to a value less than zero to disable the policy. + MaxAttempts int + + // PollingDelay is the amount of time to sleep between polling intervals. + // The default value is 15 seconds. + // A value less than zero means no delay between polling intervals (not recommended). + PollingDelay time.Duration + + // PollingDuration is the amount of time to wait before abandoning polling. + // The default valule is 5 minutes. + // NOTE: Setting this to a small value might cause the policy to prematurely fail. + PollingDuration time.Duration + + // StatusCodes contains the slice of custom HTTP status codes to use instead + // of the default http.StatusConflict. This should only be set if a service + // returns a non-standard HTTP status code when unregistered. + StatusCodes []int +} + +// ClientOptions contains configuration settings for a client's pipeline. +type ClientOptions struct { + policy.ClientOptions + + // AuxiliaryTenants are additional tenant IDs for authenticating cross-tenant requests. + // The client will add a token from each of these tenants to every request. The + // authenticating user or service principal must be a guest in these tenants, and the + // client's credential must support multitenant authentication. + AuxiliaryTenants []string + + // DisableRPRegistration disables the auto-RP registration policy. Defaults to false. + DisableRPRegistration bool +} + +// Clone return a deep copy of the current options. +func (o *ClientOptions) Clone() *ClientOptions { + if o == nil { + return nil + } + copiedOptions := *o + copiedOptions.Cloud.Services = copyMap(copiedOptions.Cloud.Services) + copiedOptions.Logging.AllowedHeaders = copyArray(copiedOptions.Logging.AllowedHeaders) + copiedOptions.Logging.AllowedQueryParams = copyArray(copiedOptions.Logging.AllowedQueryParams) + copiedOptions.Retry.StatusCodes = copyArray(copiedOptions.Retry.StatusCodes) + copiedOptions.PerRetryPolicies = copyArray(copiedOptions.PerRetryPolicies) + copiedOptions.PerCallPolicies = copyArray(copiedOptions.PerCallPolicies) + return &copiedOptions +} + +// copyMap return a new map with all the key value pair in the src map +func copyMap[K comparable, V any](src map[K]V) map[K]V { + if src == nil { + return nil + } + copiedMap := make(map[K]V) + for k, v := range src { + copiedMap[k] = v + } + return copiedMap +} + +// copyMap return a new array with all the elements in the src array +func copyArray[T any](src []T) []T { + if src == nil { + return nil + } + copiedArray := make([]T, len(src)) + copy(copiedArray, src) + return copiedArray +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go new file mode 100644 index 000000000..d1c3191f2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_identifier.go @@ -0,0 +1,24 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package arm + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource" +) + +// RootResourceID defines the tenant as the root parent of all other ResourceID. +var RootResourceID = resource.RootResourceID + +// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`. +// Don't create this type directly, use [ParseResourceID] instead. Fields are considered immutable and shouldn't be +// modified after creation. +type ResourceID = resource.ResourceID + +// ParseResourceID parses a string to an instance of ResourceID +func ParseResourceID(id string) (*ResourceID, error) { + return resource.ParseResourceID(id) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go new file mode 100644 index 000000000..fc7fbffd2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/resource_type.go @@ -0,0 +1,40 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package arm + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource" +) + +// SubscriptionResourceType is the ResourceType of a subscription +var SubscriptionResourceType = resource.SubscriptionResourceType + +// ResourceGroupResourceType is the ResourceType of a resource group +var ResourceGroupResourceType = resource.ResourceGroupResourceType + +// TenantResourceType is the ResourceType of a tenant +var TenantResourceType = resource.TenantResourceType + +// ProviderResourceType is the ResourceType of a provider +var ProviderResourceType = resource.ProviderResourceType + +// ResourceType represents an Azure resource type, e.g. "Microsoft.Network/virtualNetworks/subnets". +// Don't create this type directly, use ParseResourceType or NewResourceType instead. +type ResourceType = resource.ResourceType + +// NewResourceType creates an instance of ResourceType using a provider namespace +// such as "Microsoft.Network" and type such as "virtualNetworks/subnets". +func NewResourceType(providerNamespace, typeName string) ResourceType { + return resource.NewResourceType(providerNamespace, typeName) +} + +// ParseResourceType parses the ResourceType from a resource type string (e.g. Microsoft.Network/virtualNetworks/subsets) +// or a resource identifier string. +// e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mySubnet) +func ParseResourceType(resourceIDOrType string) (ResourceType, error) { + return resource.ParseResourceType(resourceIDOrType) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go new file mode 100644 index 000000000..6a7c916b4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/pipeline.go @@ -0,0 +1,70 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "errors" + "reflect" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" +) + +// NewPipeline creates a pipeline from connection options. Policies from ClientOptions are +// placed after policies from PipelineOptions. The telemetry policy, when enabled, will +// use the specified module and version info. +func NewPipeline(module, version string, cred azcore.TokenCredential, plOpts azruntime.PipelineOptions, options *armpolicy.ClientOptions) (azruntime.Pipeline, error) { + if options == nil { + options = &armpolicy.ClientOptions{} + } + conf, err := getConfiguration(&options.ClientOptions) + if err != nil { + return azruntime.Pipeline{}, err + } + authPolicy := NewBearerTokenPolicy(cred, &armpolicy.BearerTokenOptions{ + AuxiliaryTenants: options.AuxiliaryTenants, + InsecureAllowCredentialWithHTTP: options.InsecureAllowCredentialWithHTTP, + Scopes: []string{conf.Audience + "/.default"}, + }) + // we don't want to modify the underlying array in plOpts.PerRetry + perRetry := make([]azpolicy.Policy, len(plOpts.PerRetry), len(plOpts.PerRetry)+1) + copy(perRetry, plOpts.PerRetry) + perRetry = append(perRetry, authPolicy, exported.PolicyFunc(httpTraceNamespacePolicy)) + plOpts.PerRetry = perRetry + if !options.DisableRPRegistration { + regRPOpts := armpolicy.RegistrationOptions{ClientOptions: options.ClientOptions} + regPolicy, err := NewRPRegistrationPolicy(cred, ®RPOpts) + if err != nil { + return azruntime.Pipeline{}, err + } + // we don't want to modify the underlying array in plOpts.PerCall + perCall := make([]azpolicy.Policy, len(plOpts.PerCall), len(plOpts.PerCall)+1) + copy(perCall, plOpts.PerCall) + perCall = append(perCall, regPolicy) + plOpts.PerCall = perCall + } + if plOpts.APIVersion.Name == "" { + plOpts.APIVersion.Name = "api-version" + } + return azruntime.NewPipeline(module, version, plOpts, &options.ClientOptions), nil +} + +func getConfiguration(o *azpolicy.ClientOptions) (cloud.ServiceConfiguration, error) { + c := cloud.AzurePublic + if !reflect.ValueOf(o.Cloud).IsZero() { + c = o.Cloud + } + if conf, ok := c.Services[cloud.ResourceManager]; ok && conf.Endpoint != "" && conf.Audience != "" { + return conf, nil + } else { + return conf, errors.New("provided Cloud field is missing Azure Resource Manager configuration") + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go new file mode 100644 index 000000000..8ad3d5400 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_bearer_token.go @@ -0,0 +1,102 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/internal/temporal" +) + +const headerAuxiliaryAuthorization = "x-ms-authorization-auxiliary" + +// acquiringResourceState holds data for an auxiliary token request +type acquiringResourceState struct { + ctx context.Context + p *BearerTokenPolicy + tenant string +} + +// acquireAuxToken acquires a token from an auxiliary tenant. Only one thread/goroutine at a time ever calls this function. +func acquireAuxToken(state acquiringResourceState) (newResource azcore.AccessToken, newExpiration time.Time, err error) { + tk, err := state.p.cred.GetToken(state.ctx, azpolicy.TokenRequestOptions{ + EnableCAE: true, + Scopes: state.p.scopes, + TenantID: state.tenant, + }) + if err != nil { + return azcore.AccessToken{}, time.Time{}, err + } + return tk, tk.ExpiresOn, nil +} + +// BearerTokenPolicy authorizes requests with bearer tokens acquired from a TokenCredential. +type BearerTokenPolicy struct { + auxResources map[string]*temporal.Resource[azcore.AccessToken, acquiringResourceState] + btp *azruntime.BearerTokenPolicy + cred azcore.TokenCredential + scopes []string +} + +// NewBearerTokenPolicy creates a policy object that authorizes requests with bearer tokens. +// cred: an azcore.TokenCredential implementation such as a credential object from azidentity +// opts: optional settings. Pass nil to accept default values; this is the same as passing a zero-value options. +func NewBearerTokenPolicy(cred azcore.TokenCredential, opts *armpolicy.BearerTokenOptions) *BearerTokenPolicy { + if opts == nil { + opts = &armpolicy.BearerTokenOptions{} + } + p := &BearerTokenPolicy{cred: cred} + p.auxResources = make(map[string]*temporal.Resource[azcore.AccessToken, acquiringResourceState], len(opts.AuxiliaryTenants)) + for _, t := range opts.AuxiliaryTenants { + p.auxResources[t] = temporal.NewResource(acquireAuxToken) + } + p.scopes = make([]string, len(opts.Scopes)) + copy(p.scopes, opts.Scopes) + p.btp = azruntime.NewBearerTokenPolicy(cred, opts.Scopes, &azpolicy.BearerTokenOptions{ + InsecureAllowCredentialWithHTTP: opts.InsecureAllowCredentialWithHTTP, + AuthorizationHandler: azpolicy.AuthorizationHandler{ + OnRequest: p.onRequest, + }, + }) + return p +} + +// onRequest authorizes requests with one or more bearer tokens +func (b *BearerTokenPolicy) onRequest(req *azpolicy.Request, authNZ func(azpolicy.TokenRequestOptions) error) error { + // authorize the request with a token for the primary tenant + err := authNZ(azpolicy.TokenRequestOptions{Scopes: b.scopes}) + if err != nil || len(b.auxResources) == 0 { + return err + } + // add tokens for auxiliary tenants + as := acquiringResourceState{ + ctx: req.Raw().Context(), + p: b, + } + auxTokens := make([]string, 0, len(b.auxResources)) + for tenant, er := range b.auxResources { + as.tenant = tenant + auxTk, err := er.Get(as) + if err != nil { + return err + } + auxTokens = append(auxTokens, fmt.Sprintf("%s%s", shared.BearerTokenPrefix, auxTk.Token)) + } + req.Raw().Header.Set(headerAuxiliaryAuthorization, strings.Join(auxTokens, ", ")) + return nil +} + +// Do authorizes a request with a bearer token +func (b *BearerTokenPolicy) Do(req *azpolicy.Request) (*http.Response, error) { + return b.btp.Do(req) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go new file mode 100644 index 000000000..810ac9d9f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_register_rp.go @@ -0,0 +1,322 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource" + armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/internal/log" +) + +const ( + // LogRPRegistration entries contain information specific to the automatic registration of an RP. + // Entries of this classification are written IFF the policy needs to take any action. + LogRPRegistration log.Event = "RPRegistration" +) + +// init sets any default values +func setDefaults(r *armpolicy.RegistrationOptions) { + if r.MaxAttempts == 0 { + r.MaxAttempts = 3 + } else if r.MaxAttempts < 0 { + r.MaxAttempts = 0 + } + if r.PollingDelay == 0 { + r.PollingDelay = 15 * time.Second + } else if r.PollingDelay < 0 { + r.PollingDelay = 0 + } + if r.PollingDuration == 0 { + r.PollingDuration = 5 * time.Minute + } + if len(r.StatusCodes) == 0 { + r.StatusCodes = []int{http.StatusConflict} + } +} + +// NewRPRegistrationPolicy creates a policy object configured using the specified options. +// The policy controls whether an unregistered resource provider should automatically be +// registered. See https://aka.ms/rps-not-found for more information. +func NewRPRegistrationPolicy(cred azcore.TokenCredential, o *armpolicy.RegistrationOptions) (azpolicy.Policy, error) { + if o == nil { + o = &armpolicy.RegistrationOptions{} + } + conf, err := getConfiguration(&o.ClientOptions) + if err != nil { + return nil, err + } + authPolicy := NewBearerTokenPolicy(cred, &armpolicy.BearerTokenOptions{Scopes: []string{conf.Audience + "/.default"}}) + p := &rpRegistrationPolicy{ + endpoint: conf.Endpoint, + pipeline: runtime.NewPipeline(shared.Module, shared.Version, runtime.PipelineOptions{PerRetry: []azpolicy.Policy{authPolicy}}, &o.ClientOptions), + options: *o, + } + // init the copy + setDefaults(&p.options) + return p, nil +} + +type rpRegistrationPolicy struct { + endpoint string + pipeline runtime.Pipeline + options armpolicy.RegistrationOptions +} + +func (r *rpRegistrationPolicy) Do(req *azpolicy.Request) (*http.Response, error) { + if r.options.MaxAttempts == 0 { + // policy is disabled + return req.Next() + } + const registeredState = "Registered" + var rp string + var resp *http.Response + for attempts := 0; attempts < r.options.MaxAttempts; attempts++ { + var err error + // make the original request + resp, err = req.Next() + // getting a 409 is the first indication that the RP might need to be registered, check error response + if err != nil || !runtime.HasStatusCode(resp, r.options.StatusCodes...) { + return resp, err + } + var reqErr requestError + if err = runtime.UnmarshalAsJSON(resp, &reqErr); err != nil { + return resp, err + } + if reqErr.ServiceError == nil { + // missing service error info. just return the response + // to the caller so its error unmarshalling will kick in + return resp, err + } + if !isUnregisteredRPCode(reqErr.ServiceError.Code) { + // not a 409 due to unregistered RP. just return the response + // to the caller so its error unmarshalling will kick in + return resp, err + } + res, err := resource.ParseResourceID(req.Raw().URL.Path) + if err != nil { + return resp, err + } + rp = res.ResourceType.Namespace + logRegistrationExit := func(v any) { + log.Writef(LogRPRegistration, "END registration for %s: %v", rp, v) + } + log.Writef(LogRPRegistration, "BEGIN registration for %s", rp) + // create client and make the registration request + // we use the scheme and host from the original request + rpOps := &providersOperations{ + p: r.pipeline, + u: r.endpoint, + subID: res.SubscriptionID, + } + if _, err = rpOps.Register(&shared.ContextWithDeniedValues{Context: req.Raw().Context()}, rp); err != nil { + logRegistrationExit(err) + return resp, err + } + + // RP was registered, however we need to wait for the registration to complete + pollCtx, pollCancel := context.WithTimeout(&shared.ContextWithDeniedValues{Context: req.Raw().Context()}, r.options.PollingDuration) + var lastRegState string + for { + // get the current registration state + getResp, err := rpOps.Get(pollCtx, rp) + if err != nil { + pollCancel() + logRegistrationExit(err) + return resp, err + } + if getResp.Provider.RegistrationState != nil && !strings.EqualFold(*getResp.Provider.RegistrationState, lastRegState) { + // registration state has changed, or was updated for the first time + lastRegState = *getResp.Provider.RegistrationState + log.Writef(LogRPRegistration, "registration state is %s", lastRegState) + } + if strings.EqualFold(lastRegState, registeredState) { + // registration complete + pollCancel() + logRegistrationExit(lastRegState) + break + } + // wait before trying again + select { + case <-time.After(r.options.PollingDelay): + // continue polling + case <-pollCtx.Done(): + pollCancel() + logRegistrationExit(pollCtx.Err()) + return resp, pollCtx.Err() + } + } + // RP was successfully registered, retry the original request + err = req.RewindBody() + if err != nil { + return resp, err + } + } + // if we get here it means we exceeded the number of attempts + return resp, fmt.Errorf("exceeded attempts to register %s", rp) +} + +var unregisteredRPCodes = []string{ + "MissingSubscriptionRegistration", + "MissingRegistrationForResourceProvider", + "Subscription Not Registered", + "SubscriptionNotRegistered", +} + +func isUnregisteredRPCode(errorCode string) bool { + for _, code := range unregisteredRPCodes { + if strings.EqualFold(errorCode, code) { + return true + } + } + return false +} + +// minimal error definitions to simplify detection +type requestError struct { + ServiceError *serviceError `json:"error"` +} + +type serviceError struct { + Code string `json:"code"` +} + +/////////////////////////////////////////////////////////////////////////////////////////////// +// the following code was copied from module armresources, providers.go and models.go +// only the minimum amount of code was copied to get this working and some edits were made. +/////////////////////////////////////////////////////////////////////////////////////////////// + +type providersOperations struct { + p runtime.Pipeline + u string + subID string +} + +// Get - Gets the specified resource provider. +func (client *providersOperations) Get(ctx context.Context, resourceProviderNamespace string) (providerResponse, error) { + req, err := client.getCreateRequest(ctx, resourceProviderNamespace) + if err != nil { + return providerResponse{}, err + } + resp, err := client.p.Do(req) + if err != nil { + return providerResponse{}, err + } + result, err := client.getHandleResponse(resp) + if err != nil { + return providerResponse{}, err + } + return result, nil +} + +// getCreateRequest creates the Get request. +func (client *providersOperations) getCreateRequest(ctx context.Context, resourceProviderNamespace string) (*azpolicy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}" + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.u, urlPath)) + if err != nil { + return nil, err + } + query := req.Raw().URL.Query() + query.Set("api-version", "2019-05-01") + req.Raw().URL.RawQuery = query.Encode() + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *providersOperations) getHandleResponse(resp *http.Response) (providerResponse, error) { + if !runtime.HasStatusCode(resp, http.StatusOK) { + return providerResponse{}, exported.NewResponseError(resp) + } + result := providerResponse{RawResponse: resp} + err := runtime.UnmarshalAsJSON(resp, &result.Provider) + if err != nil { + return providerResponse{}, err + } + return result, err +} + +// Register - Registers a subscription with a resource provider. +func (client *providersOperations) Register(ctx context.Context, resourceProviderNamespace string) (providerResponse, error) { + req, err := client.registerCreateRequest(ctx, resourceProviderNamespace) + if err != nil { + return providerResponse{}, err + } + resp, err := client.p.Do(req) + if err != nil { + return providerResponse{}, err + } + result, err := client.registerHandleResponse(resp) + if err != nil { + return providerResponse{}, err + } + return result, nil +} + +// registerCreateRequest creates the Register request. +func (client *providersOperations) registerCreateRequest(ctx context.Context, resourceProviderNamespace string) (*azpolicy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register" + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.u, urlPath)) + if err != nil { + return nil, err + } + query := req.Raw().URL.Query() + query.Set("api-version", "2019-05-01") + req.Raw().URL.RawQuery = query.Encode() + return req, nil +} + +// registerHandleResponse handles the Register response. +func (client *providersOperations) registerHandleResponse(resp *http.Response) (providerResponse, error) { + if !runtime.HasStatusCode(resp, http.StatusOK) { + return providerResponse{}, exported.NewResponseError(resp) + } + result := providerResponse{RawResponse: resp} + err := runtime.UnmarshalAsJSON(resp, &result.Provider) + if err != nil { + return providerResponse{}, err + } + return result, err +} + +// ProviderResponse is the response envelope for operations that return a Provider type. +type providerResponse struct { + // Resource provider information. + Provider *provider + + // RawResponse contains the underlying HTTP response. + RawResponse *http.Response +} + +// Provider - Resource provider information. +type provider struct { + // The provider ID. + ID *string `json:"id,omitempty"` + + // The namespace of the resource provider. + Namespace *string `json:"namespace,omitempty"` + + // The registration policy of the resource provider. + RegistrationPolicy *string `json:"registrationPolicy,omitempty"` + + // The registration state of the resource provider. + RegistrationState *string `json:"registrationState,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_trace_namespace.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_trace_namespace.go new file mode 100644 index 000000000..6cea18424 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/policy_trace_namespace.go @@ -0,0 +1,30 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +// httpTraceNamespacePolicy is a policy that adds the az.namespace attribute to the current Span +func httpTraceNamespacePolicy(req *policy.Request) (resp *http.Response, err error) { + rawTracer := req.Raw().Context().Value(shared.CtxWithTracingTracer{}) + if tracer, ok := rawTracer.(tracing.Tracer); ok && tracer.Enabled() { + rt, err := resource.ParseResourceType(req.Raw().URL.Path) + if err == nil { + // add the namespace attribute to the current span + span := tracer.SpanFromContext(req.Raw().Context()) + span.SetAttributes(tracing.Attribute{Key: shared.TracingNamespaceAttrName, Value: rt.Namespace}) + } + } + return req.Next() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go new file mode 100644 index 000000000..1400d4379 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime/runtime.go @@ -0,0 +1,24 @@ +//go:build go1.16 +// +build go1.16 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + +func init() { + cloud.AzureChina.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{ + Audience: "https://management.core.chinacloudapi.cn", + Endpoint: "https://management.chinacloudapi.cn", + } + cloud.AzureGovernment.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{ + Audience: "https://management.core.usgovcloudapi.net", + Endpoint: "https://management.usgovcloudapi.net", + } + cloud.AzurePublic.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{ + Audience: "https://management.core.windows.net/", + Endpoint: "https://management.azure.com", + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml new file mode 100644 index 000000000..b81b62103 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/ci.yml @@ -0,0 +1,31 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/azcore/ + - eng/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/azcore/ + - eng/ + +extends: + template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + ServiceDirectory: azcore + TriggeringPaths: + - /eng/ diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/cloud.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/cloud.go new file mode 100644 index 000000000..9d077a3e1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/cloud.go @@ -0,0 +1,44 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package cloud + +var ( + // AzureChina contains configuration for Azure China. + AzureChina = Configuration{ + ActiveDirectoryAuthorityHost: "https://login.chinacloudapi.cn/", Services: map[ServiceName]ServiceConfiguration{}, + } + // AzureGovernment contains configuration for Azure Government. + AzureGovernment = Configuration{ + ActiveDirectoryAuthorityHost: "https://login.microsoftonline.us/", Services: map[ServiceName]ServiceConfiguration{}, + } + // AzurePublic contains configuration for Azure Public Cloud. + AzurePublic = Configuration{ + ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com/", Services: map[ServiceName]ServiceConfiguration{}, + } +) + +// ServiceName identifies a cloud service. +type ServiceName string + +// ResourceManager is a global constant identifying Azure Resource Manager. +const ResourceManager ServiceName = "resourceManager" + +// ServiceConfiguration configures a specific cloud service such as Azure Resource Manager. +type ServiceConfiguration struct { + // Audience is the audience the client will request for its access tokens. + Audience string + // Endpoint is the service's base URL. + Endpoint string +} + +// Configuration configures a cloud. +type Configuration struct { + // ActiveDirectoryAuthorityHost is the base URL of the cloud's Azure Active Directory. + ActiveDirectoryAuthorityHost string + // Services contains configuration for the cloud's services. + Services map[ServiceName]ServiceConfiguration +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/doc.go new file mode 100644 index 000000000..985b1bde2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud/doc.go @@ -0,0 +1,53 @@ +//go:build go1.16 +// +build go1.16 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/* +Package cloud implements a configuration API for applications deployed to sovereign or private Azure clouds. + +Azure SDK client configuration defaults are appropriate for Azure Public Cloud (sometimes referred to as +"Azure Commercial" or simply "Microsoft Azure"). This package enables applications deployed to other +Azure Clouds to configure clients appropriately. + +This package contains predefined configuration for well-known sovereign clouds such as Azure Government and +Azure China. Azure SDK clients accept this configuration via the Cloud field of azcore.ClientOptions. For +example, configuring a credential and ARM client for Azure Government: + + opts := azcore.ClientOptions{Cloud: cloud.AzureGovernment} + cred, err := azidentity.NewDefaultAzureCredential( + &azidentity.DefaultAzureCredentialOptions{ClientOptions: opts}, + ) + handle(err) + + client, err := armsubscription.NewClient( + cred, &arm.ClientOptions{ClientOptions: opts}, + ) + handle(err) + +Applications deployed to a private cloud such as Azure Stack create a Configuration object with +appropriate values: + + c := cloud.Configuration{ + ActiveDirectoryAuthorityHost: "https://...", + Services: map[cloud.ServiceName]cloud.ServiceConfiguration{ + cloud.ResourceManager: { + Audience: "...", + Endpoint: "https://...", + }, + }, + } + opts := azcore.ClientOptions{Cloud: c} + + cred, err := azidentity.NewDefaultAzureCredential( + &azidentity.DefaultAzureCredentialOptions{ClientOptions: opts}, + ) + handle(err) + + client, err := armsubscription.NewClient( + cred, &arm.ClientOptions{ClientOptions: opts}, + ) + handle(err) +*/ +package cloud diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go new file mode 100644 index 000000000..9d1c2f0c0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go @@ -0,0 +1,173 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azcore + +import ( + "reflect" + "sync" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +// AccessToken represents an Azure service bearer access token with expiry information. +type AccessToken = exported.AccessToken + +// TokenCredential represents a credential capable of providing an OAuth token. +type TokenCredential = exported.TokenCredential + +// KeyCredential contains an authentication key used to authenticate to an Azure service. +type KeyCredential = exported.KeyCredential + +// NewKeyCredential creates a new instance of [KeyCredential] with the specified values. +// - key is the authentication key +func NewKeyCredential(key string) *KeyCredential { + return exported.NewKeyCredential(key) +} + +// SASCredential contains a shared access signature used to authenticate to an Azure service. +type SASCredential = exported.SASCredential + +// NewSASCredential creates a new instance of [SASCredential] with the specified values. +// - sas is the shared access signature +func NewSASCredential(sas string) *SASCredential { + return exported.NewSASCredential(sas) +} + +// holds sentinel values used to send nulls +var nullables map[reflect.Type]any = map[reflect.Type]any{} +var nullablesMu sync.RWMutex + +// NullValue is used to send an explicit 'null' within a request. +// This is typically used in JSON-MERGE-PATCH operations to delete a value. +func NullValue[T any]() T { + t := shared.TypeOfT[T]() + + nullablesMu.RLock() + v, found := nullables[t] + nullablesMu.RUnlock() + + if found { + // return the sentinel object + return v.(T) + } + + // promote to exclusive lock and check again (double-checked locking pattern) + nullablesMu.Lock() + defer nullablesMu.Unlock() + v, found = nullables[t] + + if !found { + var o reflect.Value + if k := t.Kind(); k == reflect.Map { + o = reflect.MakeMap(t) + } else if k == reflect.Slice { + // empty slices appear to all point to the same data block + // which causes comparisons to become ambiguous. so we create + // a slice with len/cap of one which ensures a unique address. + o = reflect.MakeSlice(t, 1, 1) + } else { + o = reflect.New(t.Elem()) + } + v = o.Interface() + nullables[t] = v + } + // return the sentinel object + return v.(T) +} + +// IsNullValue returns true if the field contains a null sentinel value. +// This is used by custom marshallers to properly encode a null value. +func IsNullValue[T any](v T) bool { + // see if our map has a sentinel object for this *T + t := reflect.TypeOf(v) + nullablesMu.RLock() + defer nullablesMu.RUnlock() + + if o, found := nullables[t]; found { + o1 := reflect.ValueOf(o) + v1 := reflect.ValueOf(v) + // we found it; return true if v points to the sentinel object. + // NOTE: maps and slices can only be compared to nil, else you get + // a runtime panic. so we compare addresses instead. + return o1.Pointer() == v1.Pointer() + } + // no sentinel object for this *t + return false +} + +// ClientOptions contains optional settings for a client's pipeline. +// Instances can be shared across calls to SDK client constructors when uniform configuration is desired. +// Zero-value fields will have their specified default values applied during use. +type ClientOptions = policy.ClientOptions + +// Client is a basic HTTP client. It consists of a pipeline and tracing provider. +type Client struct { + pl runtime.Pipeline + tr tracing.Tracer + + // cached on the client to support shallow copying with new values + tp tracing.Provider + modVer string + namespace string +} + +// NewClient creates a new Client instance with the provided values. +// - moduleName - the fully qualified name of the module where the client is defined; used by the telemetry policy and tracing provider. +// - moduleVersion - the semantic version of the module; used by the telemetry policy and tracing provider. +// - plOpts - pipeline configuration options; can be the zero-value +// - options - optional client configurations; pass nil to accept the default values +func NewClient(moduleName, moduleVersion string, plOpts runtime.PipelineOptions, options *ClientOptions) (*Client, error) { + if options == nil { + options = &ClientOptions{} + } + + if !options.Telemetry.Disabled { + if err := shared.ValidateModVer(moduleVersion); err != nil { + return nil, err + } + } + + pl := runtime.NewPipeline(moduleName, moduleVersion, plOpts, options) + + tr := options.TracingProvider.NewTracer(moduleName, moduleVersion) + if tr.Enabled() && plOpts.Tracing.Namespace != "" { + tr.SetAttributes(tracing.Attribute{Key: shared.TracingNamespaceAttrName, Value: plOpts.Tracing.Namespace}) + } + + return &Client{ + pl: pl, + tr: tr, + tp: options.TracingProvider, + modVer: moduleVersion, + namespace: plOpts.Tracing.Namespace, + }, nil +} + +// Pipeline returns the pipeline for this client. +func (c *Client) Pipeline() runtime.Pipeline { + return c.pl +} + +// Tracer returns the tracer for this client. +func (c *Client) Tracer() tracing.Tracer { + return c.tr +} + +// WithClientName returns a shallow copy of the Client with its tracing client name changed to clientName. +// Note that the values for module name and version will be preserved from the source Client. +// - clientName - the fully qualified name of the client ("package.Client"); this is used by the tracing provider when creating spans +func (c *Client) WithClientName(clientName string) *Client { + tr := c.tp.NewTracer(clientName, c.modVer) + if tr.Enabled() && c.namespace != "" { + tr.SetAttributes(tracing.Attribute{Key: shared.TracingNamespaceAttrName, Value: c.namespace}) + } + return &Client{pl: c.pl, tr: tr, tp: c.tp, modVer: c.modVer, namespace: c.namespace} +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go new file mode 100644 index 000000000..654a5f404 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go @@ -0,0 +1,264 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +/* +Package azcore implements an HTTP request/response middleware pipeline used by Azure SDK clients. + +The middleware consists of three components. + + - One or more Policy instances. + - A Transporter instance. + - A Pipeline instance that combines the Policy and Transporter instances. + +# Implementing the Policy Interface + +A Policy can be implemented in two ways; as a first-class function for a stateless Policy, or as +a method on a type for a stateful Policy. Note that HTTP requests made via the same pipeline share +the same Policy instances, so if a Policy mutates its state it MUST be properly synchronized to +avoid race conditions. + +A Policy's Do method is called when an HTTP request wants to be sent over the network. The Do method can +perform any operation(s) it desires. For example, it can log the outgoing request, mutate the URL, headers, +and/or query parameters, inject a failure, etc. Once the Policy has successfully completed its request +work, it must call the Next() method on the *policy.Request instance in order to pass the request to the +next Policy in the chain. + +When an HTTP response comes back, the Policy then gets a chance to process the response/error. The Policy instance +can log the response, retry the operation if it failed due to a transient error or timeout, unmarshal the response +body, etc. Once the Policy has successfully completed its response work, it must return the *http.Response +and error instances to its caller. + +Template for implementing a stateless Policy: + + type policyFunc func(*policy.Request) (*http.Response, error) + + // Do implements the Policy interface on policyFunc. + func (pf policyFunc) Do(req *policy.Request) (*http.Response, error) { + return pf(req) + } + + func NewMyStatelessPolicy() policy.Policy { + return policyFunc(func(req *policy.Request) (*http.Response, error) { + // TODO: mutate/process Request here + + // forward Request to next Policy & get Response/error + resp, err := req.Next() + + // TODO: mutate/process Response/error here + + // return Response/error to previous Policy + return resp, err + }) + } + +Template for implementing a stateful Policy: + + type MyStatefulPolicy struct { + // TODO: add configuration/setting fields here + } + + // TODO: add initialization args to NewMyStatefulPolicy() + func NewMyStatefulPolicy() policy.Policy { + return &MyStatefulPolicy{ + // TODO: initialize configuration/setting fields here + } + } + + func (p *MyStatefulPolicy) Do(req *policy.Request) (resp *http.Response, err error) { + // TODO: mutate/process Request here + + // forward Request to next Policy & get Response/error + resp, err := req.Next() + + // TODO: mutate/process Response/error here + + // return Response/error to previous Policy + return resp, err + } + +# Implementing the Transporter Interface + +The Transporter interface is responsible for sending the HTTP request and returning the corresponding +HTTP response or error. The Transporter is invoked by the last Policy in the chain. The default Transporter +implementation uses a shared http.Client from the standard library. + +The same stateful/stateless rules for Policy implementations apply to Transporter implementations. + +# Using Policy and Transporter Instances Via a Pipeline + +To use the Policy and Transporter instances, an application passes them to the runtime.NewPipeline function. + + func NewPipeline(transport Transporter, policies ...Policy) Pipeline + +The specified Policy instances form a chain and are invoked in the order provided to NewPipeline +followed by the Transporter. + +Once the Pipeline has been created, create a runtime.Request instance and pass it to Pipeline's Do method. + + func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error) + + func (p Pipeline) Do(req *Request) (*http.Request, error) + +The Pipeline.Do method sends the specified Request through the chain of Policy and Transporter +instances. The response/error is then sent through the same chain of Policy instances in reverse +order. For example, assuming there are Policy types PolicyA, PolicyB, and PolicyC along with +TransportA. + + pipeline := NewPipeline(TransportA, PolicyA, PolicyB, PolicyC) + +The flow of Request and Response looks like the following: + + policy.Request -> PolicyA -> PolicyB -> PolicyC -> TransportA -----+ + | + HTTP(S) endpoint + | + caller <--------- PolicyA <- PolicyB <- PolicyC <- http.Response-+ + +# Creating a Request Instance + +The Request instance passed to Pipeline's Do method is a wrapper around an *http.Request. It also +contains some internal state and provides various convenience methods. You create a Request instance +by calling the runtime.NewRequest function: + + func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error) + +If the Request should contain a body, call the SetBody method. + + func (req *Request) SetBody(body ReadSeekCloser, contentType string) error + +A seekable stream is required so that upon retry, the retry Policy instance can seek the stream +back to the beginning before retrying the network request and re-uploading the body. + +# Sending an Explicit Null + +Operations like JSON-MERGE-PATCH send a JSON null to indicate a value should be deleted. + + { + "delete-me": null + } + +This requirement conflicts with the SDK's default marshalling that specifies "omitempty" as +a means to resolve the ambiguity between a field to be excluded and its zero-value. + + type Widget struct { + Name *string `json:",omitempty"` + Count *int `json:",omitempty"` + } + +In the above example, Name and Count are defined as pointer-to-type to disambiguate between +a missing value (nil) and a zero-value (0) which might have semantic differences. + +In a PATCH operation, any fields left as nil are to have their values preserved. When updating +a Widget's count, one simply specifies the new value for Count, leaving Name nil. + +To fulfill the requirement for sending a JSON null, the NullValue() function can be used. + + w := Widget{ + Count: azcore.NullValue[*int](), + } + +This sends an explict "null" for Count, indicating that any current value for Count should be deleted. + +# Processing the Response + +When the HTTP response is received, the *http.Response is returned directly. Each Policy instance +can inspect/mutate the *http.Response. + +# Built-in Logging + +To enable logging, set environment variable AZURE_SDK_GO_LOGGING to "all" before executing your program. + +By default the logger writes to stderr. This can be customized by calling log.SetListener, providing +a callback that writes to the desired location. Any custom logging implementation MUST provide its +own synchronization to handle concurrent invocations. + +See the docs for the log package for further details. + +# Pageable Operations + +Pageable operations return potentially large data sets spread over multiple GET requests. The result of +each GET is a "page" of data consisting of a slice of items. + +Pageable operations can be identified by their New*Pager naming convention and return type of *runtime.Pager[T]. + + func (c *WidgetClient) NewListWidgetsPager(o *Options) *runtime.Pager[PageResponse] + +The call to WidgetClient.NewListWidgetsPager() returns an instance of *runtime.Pager[T] for fetching pages +and determining if there are more pages to fetch. No IO calls are made until the NextPage() method is invoked. + + pager := widgetClient.NewListWidgetsPager(nil) + for pager.More() { + page, err := pager.NextPage(context.TODO()) + // handle err + for _, widget := range page.Values { + // process widget + } + } + +# Long-Running Operations + +Long-running operations (LROs) are operations consisting of an initial request to start the operation followed +by polling to determine when the operation has reached a terminal state. An LRO's terminal state is one +of the following values. + + - Succeeded - the LRO completed successfully + - Failed - the LRO failed to complete + - Canceled - the LRO was canceled + +LROs can be identified by their Begin* prefix and their return type of *runtime.Poller[T]. + + func (c *WidgetClient) BeginCreateOrUpdate(ctx context.Context, w Widget, o *Options) (*runtime.Poller[Response], error) + +When a call to WidgetClient.BeginCreateOrUpdate() returns a nil error, it means that the LRO has started. +It does _not_ mean that the widget has been created or updated (or failed to be created/updated). + +The *runtime.Poller[T] provides APIs for determining the state of the LRO. To wait for the LRO to complete, +call the PollUntilDone() method. + + poller, err := widgetClient.BeginCreateOrUpdate(context.TODO(), Widget{}, nil) + // handle err + result, err := poller.PollUntilDone(context.TODO(), nil) + // handle err + // use result + +The call to PollUntilDone() will block the current goroutine until the LRO has reached a terminal state or the +context is canceled/timed out. + +Note that LROs can take anywhere from several seconds to several minutes. The duration is operation-dependent. Due to +this variant behavior, pollers do _not_ have a preconfigured time-out. Use a context with the appropriate cancellation +mechanism as required. + +# Resume Tokens + +Pollers provide the ability to serialize their state into a "resume token" which can be used by another process to +recreate the poller. This is achieved via the runtime.Poller[T].ResumeToken() method. + + token, err := poller.ResumeToken() + // handle error + +Note that a token can only be obtained for a poller that's in a non-terminal state. Also note that any subsequent calls +to poller.Poll() might change the poller's state. In this case, a new token should be created. + +After the token has been obtained, it can be used to recreate an instance of the originating poller. + + poller, err := widgetClient.BeginCreateOrUpdate(nil, Widget{}, &Options{ + ResumeToken: token, + }) + +When resuming a poller, no IO is performed, and zero-value arguments can be used for everything but the Options.ResumeToken. + +Resume tokens are unique per service client and operation. Attempting to resume a poller for LRO BeginB() with a token from LRO +BeginA() will result in an error. + +# Fakes + +The fake package contains types used for constructing in-memory fake servers used in unit tests. +This allows writing tests to cover various success/error conditions without the need for connecting to a live service. + +Please see https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/samples/fakes for details and examples on how to use fakes. +*/ +package azcore diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/errors.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/errors.go new file mode 100644 index 000000000..03cb227d0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/errors.go @@ -0,0 +1,17 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azcore + +import "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + +// ResponseError is returned when a request is made to a service and +// the service returns a non-success HTTP status code. +// Use errors.As() to access this type in the error chain. +// +// When marshaling instances, the RawResponse field will be omitted. +// However, the contents returned by Error() will be preserved. +type ResponseError = exported.ResponseError diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/etag.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/etag.go new file mode 100644 index 000000000..2b19d01f7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/etag.go @@ -0,0 +1,57 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azcore + +import ( + "strings" +) + +// ETag is a property used for optimistic concurrency during updates +// ETag is a validator based on https://tools.ietf.org/html/rfc7232#section-2.3.2 +// An ETag can be empty (""). +type ETag string + +// ETagAny is an ETag that represents everything, the value is "*" +const ETagAny ETag = "*" + +// Equals does a strong comparison of two ETags. Equals returns true when both +// ETags are not weak and the values of the underlying strings are equal. +func (e ETag) Equals(other ETag) bool { + return !e.IsWeak() && !other.IsWeak() && e == other +} + +// WeakEquals does a weak comparison of two ETags. Two ETags are equivalent if their opaque-tags match +// character-by-character, regardless of either or both being tagged as "weak". +func (e ETag) WeakEquals(other ETag) bool { + getStart := func(e1 ETag) int { + if e1.IsWeak() { + return 2 + } + return 0 + } + aStart := getStart(e) + bStart := getStart(other) + + aVal := e[aStart:] + bVal := other[bStart:] + + return aVal == bVal +} + +// IsWeak specifies whether the ETag is strong or weak. +func (e ETag) IsWeak() bool { + return len(e) >= 4 && strings.HasPrefix(string(e), "W/\"") && strings.HasSuffix(string(e), "\"") +} + +// MatchConditions specifies HTTP options for conditional requests. +type MatchConditions struct { + // Optionally limit requests to resources that have a matching ETag. + IfMatch *ETag + + // Optionally limit requests to resources that do not match the ETag. + IfNoneMatch *ETag +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go new file mode 100644 index 000000000..460170034 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go @@ -0,0 +1,180 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package exported + +import ( + "context" + "encoding/base64" + "fmt" + "io" + "net/http" + "sync/atomic" + "time" +) + +type nopCloser struct { + io.ReadSeeker +} + +func (n nopCloser) Close() error { + return nil +} + +// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker. +// Exported as streaming.NopCloser(). +func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser { + return nopCloser{rs} +} + +// HasStatusCode returns true if the Response's status code is one of the specified values. +// Exported as runtime.HasStatusCode(). +func HasStatusCode(resp *http.Response, statusCodes ...int) bool { + if resp == nil { + return false + } + for _, sc := range statusCodes { + if resp.StatusCode == sc { + return true + } + } + return false +} + +// AccessToken represents an Azure service bearer access token with expiry information. +// Exported as azcore.AccessToken. +type AccessToken struct { + // Token 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. +// Exported as policy.TokenRequestOptions. +type TokenRequestOptions struct { + // Claims are any additional claims required for the token to satisfy a conditional access policy, such as a + // service may return in a claims challenge following an authorization failure. If a service returned the + // claims value base64 encoded, it must be decoded before setting this field. + Claims string + + // EnableCAE indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. When true, + // azidentity credentials request CAE tokens for resource APIs supporting CAE. Clients are responsible for + // handling CAE challenges. If a client that doesn't handle CAE challenges receives a CAE token, it may end up + // in a loop retrying an API call with a token that has been revoked due to CAE. + EnableCAE bool + + // Scopes contains the list of permission scopes required for the token. + Scopes []string + + // TenantID identifies the tenant from which to request the token. azidentity credentials authenticate in + // their configured default tenants when this field isn't set. + TenantID string +} + +// TokenCredential represents a credential capable of providing an OAuth token. +// Exported as azcore.TokenCredential. +type TokenCredential interface { + // GetToken requests an access token for the specified set of scopes. + GetToken(ctx context.Context, options TokenRequestOptions) (AccessToken, error) +} + +// DecodeByteArray will base-64 decode the provided string into v. +// Exported as runtime.DecodeByteArray() +func DecodeByteArray(s string, v *[]byte, format Base64Encoding) error { + if len(s) == 0 { + return nil + } + payload := string(s) + if payload[0] == '"' { + // remove surrounding quotes + payload = payload[1 : len(payload)-1] + } + switch format { + case Base64StdFormat: + decoded, err := base64.StdEncoding.DecodeString(payload) + if err == nil { + *v = decoded + return nil + } + return err + case Base64URLFormat: + // use raw encoding as URL format should not contain any '=' characters + decoded, err := base64.RawURLEncoding.DecodeString(payload) + if err == nil { + *v = decoded + return nil + } + return err + default: + return fmt.Errorf("unrecognized byte array format: %d", format) + } +} + +// KeyCredential contains an authentication key used to authenticate to an Azure service. +// Exported as azcore.KeyCredential. +type KeyCredential struct { + cred *keyCredential +} + +// NewKeyCredential creates a new instance of [KeyCredential] with the specified values. +// - key is the authentication key +func NewKeyCredential(key string) *KeyCredential { + return &KeyCredential{cred: newKeyCredential(key)} +} + +// Update replaces the existing key with the specified value. +func (k *KeyCredential) Update(key string) { + k.cred.Update(key) +} + +// SASCredential contains a shared access signature used to authenticate to an Azure service. +// Exported as azcore.SASCredential. +type SASCredential struct { + cred *keyCredential +} + +// NewSASCredential creates a new instance of [SASCredential] with the specified values. +// - sas is the shared access signature +func NewSASCredential(sas string) *SASCredential { + return &SASCredential{cred: newKeyCredential(sas)} +} + +// Update replaces the existing shared access signature with the specified value. +func (k *SASCredential) Update(sas string) { + k.cred.Update(sas) +} + +// KeyCredentialGet returns the key for cred. +func KeyCredentialGet(cred *KeyCredential) string { + return cred.cred.Get() +} + +// SASCredentialGet returns the shared access sig for cred. +func SASCredentialGet(cred *SASCredential) string { + return cred.cred.Get() +} + +type keyCredential struct { + key atomic.Value // string +} + +func newKeyCredential(key string) *keyCredential { + keyCred := keyCredential{} + keyCred.key.Store(key) + return &keyCred +} + +func (k *keyCredential) Get() string { + return k.key.Load().(string) +} + +func (k *keyCredential) Update(key string) { + k.key.Store(key) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/pipeline.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/pipeline.go new file mode 100644 index 000000000..e45f831ed --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/pipeline.go @@ -0,0 +1,77 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package exported + +import ( + "errors" + "net/http" +) + +// Policy represents an extensibility point for the Pipeline that can mutate the specified +// Request and react to the received Response. +// Exported as policy.Policy. +type Policy interface { + // Do applies the policy to the specified Request. When implementing a Policy, mutate the + // request before calling req.Next() to move on to the next policy, and respond to the result + // before returning to the caller. + Do(req *Request) (*http.Response, error) +} + +// Pipeline represents a primitive for sending HTTP requests and receiving responses. +// Its behavior can be extended by specifying policies during construction. +// Exported as runtime.Pipeline. +type Pipeline struct { + policies []Policy +} + +// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses. +// Exported as policy.Transporter. +type Transporter interface { + // Do sends the HTTP request and returns the HTTP response or error. + Do(req *http.Request) (*http.Response, error) +} + +// used to adapt a TransportPolicy to a Policy +type transportPolicy struct { + trans Transporter +} + +func (tp transportPolicy) Do(req *Request) (*http.Response, error) { + if tp.trans == nil { + return nil, errors.New("missing transporter") + } + resp, err := tp.trans.Do(req.Raw()) + if err != nil { + return nil, err + } else if resp == nil { + // there was no response and no error (rare but can happen) + // this ensures the retry policy will retry the request + return nil, errors.New("received nil response") + } + return resp, nil +} + +// NewPipeline creates a new Pipeline object from the specified Policies. +// Not directly exported, but used as part of runtime.NewPipeline(). +func NewPipeline(transport Transporter, policies ...Policy) Pipeline { + // transport policy must always be the last in the slice + policies = append(policies, transportPolicy{trans: transport}) + return Pipeline{ + policies: policies, + } +} + +// Do is called for each and every HTTP request. It passes the request through all +// the Policy objects (which can transform the Request's URL/query parameters/headers) +// and ultimately sends the transformed HTTP request over the network. +func (p Pipeline) Do(req *Request) (*http.Response, error) { + if req == nil { + return nil, errors.New("request cannot be nil") + } + req.policies = p.policies + return req.Next() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go new file mode 100644 index 000000000..9b3f5badb --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/request.go @@ -0,0 +1,262 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package exported + +import ( + "bytes" + "context" + "encoding/base64" + "errors" + "fmt" + "io" + "net/http" + "reflect" + "strconv" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" +) + +// Base64Encoding is usesd to specify which base-64 encoder/decoder to use when +// encoding/decoding a slice of bytes to/from a string. +// Exported as runtime.Base64Encoding +type Base64Encoding int + +const ( + // Base64StdFormat uses base64.StdEncoding for encoding and decoding payloads. + Base64StdFormat Base64Encoding = 0 + + // Base64URLFormat uses base64.RawURLEncoding for encoding and decoding payloads. + Base64URLFormat Base64Encoding = 1 +) + +// EncodeByteArray will base-64 encode the byte slice v. +// Exported as runtime.EncodeByteArray() +func EncodeByteArray(v []byte, format Base64Encoding) string { + if format == Base64URLFormat { + return base64.RawURLEncoding.EncodeToString(v) + } + return base64.StdEncoding.EncodeToString(v) +} + +// Request is an abstraction over the creation of an HTTP request as it passes through the pipeline. +// Don't use this type directly, use NewRequest() instead. +// Exported as policy.Request. +type Request struct { + req *http.Request + body io.ReadSeekCloser + policies []Policy + values opValues +} + +type opValues map[reflect.Type]any + +// Set adds/changes a value +func (ov opValues) set(value any) { + ov[reflect.TypeOf(value)] = value +} + +// Get looks for a value set by SetValue first +func (ov opValues) get(value any) bool { + v, ok := ov[reflect.ValueOf(value).Elem().Type()] + if ok { + reflect.ValueOf(value).Elem().Set(reflect.ValueOf(v)) + } + return ok +} + +// NewRequestFromRequest creates a new policy.Request with an existing *http.Request +// Exported as runtime.NewRequestFromRequest(). +func NewRequestFromRequest(req *http.Request) (*Request, error) { + // populate values so that the same instance is propagated across policies + policyReq := &Request{req: req, values: opValues{}} + + if req.Body != nil { + // we can avoid a body copy here if the underlying stream is already a + // ReadSeekCloser. + readSeekCloser, isReadSeekCloser := req.Body.(io.ReadSeekCloser) + + if !isReadSeekCloser { + // since this is an already populated http.Request we want to copy + // over its body, if it has one. + bodyBytes, err := io.ReadAll(req.Body) + + if err != nil { + return nil, err + } + + if err := req.Body.Close(); err != nil { + return nil, err + } + + readSeekCloser = NopCloser(bytes.NewReader(bodyBytes)) + } + + // SetBody also takes care of updating the http.Request's body + // as well, so they should stay in-sync from this point. + if err := policyReq.SetBody(readSeekCloser, req.Header.Get("Content-Type")); err != nil { + return nil, err + } + } + + return policyReq, nil +} + +// NewRequest creates a new Request with the specified input. +// Exported as runtime.NewRequest(). +func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error) { + req, err := http.NewRequestWithContext(ctx, httpMethod, endpoint, nil) + if err != nil { + return nil, err + } + if req.URL.Host == "" { + return nil, errors.New("no Host in request URL") + } + if !(req.URL.Scheme == "http" || req.URL.Scheme == "https") { + return nil, fmt.Errorf("unsupported protocol scheme %s", req.URL.Scheme) + } + // populate values so that the same instance is propagated across policies + return &Request{req: req, values: opValues{}}, nil +} + +// Body returns the original body specified when the Request was created. +func (req *Request) Body() io.ReadSeekCloser { + return req.body +} + +// Raw returns the underlying HTTP request. +func (req *Request) Raw() *http.Request { + return req.req +} + +// Next calls the next policy in the pipeline. +// If there are no more policies, nil and an error are returned. +// This method is intended to be called from pipeline policies. +// To send a request through a pipeline call Pipeline.Do(). +func (req *Request) Next() (*http.Response, error) { + if len(req.policies) == 0 { + return nil, errors.New("no more policies") + } + nextPolicy := req.policies[0] + nextReq := *req + nextReq.policies = nextReq.policies[1:] + return nextPolicy.Do(&nextReq) +} + +// SetOperationValue adds/changes a mutable key/value associated with a single operation. +func (req *Request) SetOperationValue(value any) { + if req.values == nil { + req.values = opValues{} + } + req.values.set(value) +} + +// OperationValue looks for a value set by SetOperationValue(). +func (req *Request) OperationValue(value any) bool { + if req.values == nil { + return false + } + return req.values.get(value) +} + +// SetBody sets the specified ReadSeekCloser as the HTTP request body, and sets Content-Type and Content-Length +// accordingly. If the ReadSeekCloser is nil or empty, Content-Length won't be set. If contentType is "", +// Content-Type won't be set, and if it was set, will be deleted. +// Use streaming.NopCloser to turn an io.ReadSeeker into an io.ReadSeekCloser. +func (req *Request) SetBody(body io.ReadSeekCloser, contentType string) error { + // clobber the existing Content-Type to preserve behavior + return SetBody(req, body, contentType, true) +} + +// RewindBody seeks the request's Body stream back to the beginning so it can be resent when retrying an operation. +func (req *Request) RewindBody() error { + if req.body != nil { + // Reset the stream back to the beginning and restore the body + _, err := req.body.Seek(0, io.SeekStart) + req.req.Body = req.body + return err + } + return nil +} + +// Close closes the request body. +func (req *Request) Close() error { + if req.body == nil { + return nil + } + return req.body.Close() +} + +// Clone returns a deep copy of the request with its context changed to ctx. +func (req *Request) Clone(ctx context.Context) *Request { + r2 := *req + r2.req = req.req.Clone(ctx) + return &r2 +} + +// WithContext returns a shallow copy of the request with its context changed to ctx. +func (req *Request) WithContext(ctx context.Context) *Request { + r2 := new(Request) + *r2 = *req + r2.req = r2.req.WithContext(ctx) + return r2 +} + +// not exported but dependent on Request + +// PolicyFunc is a type that implements the Policy interface. +// Use this type when implementing a stateless policy as a first-class function. +type PolicyFunc func(*Request) (*http.Response, error) + +// Do implements the Policy interface on policyFunc. +func (pf PolicyFunc) Do(req *Request) (*http.Response, error) { + return pf(req) +} + +// SetBody sets the specified ReadSeekCloser as the HTTP request body, and sets Content-Type and Content-Length accordingly. +// - req is the request to modify +// - body is the request body; if nil or empty, Content-Length won't be set +// - contentType is the value for the Content-Type header; if empty, Content-Type will be deleted +// - clobberContentType when true, will overwrite the existing value of Content-Type with contentType +func SetBody(req *Request, body io.ReadSeekCloser, contentType string, clobberContentType bool) error { + var err error + var size int64 + if body != nil { + size, err = body.Seek(0, io.SeekEnd) // Seek to the end to get the stream's size + if err != nil { + return err + } + } + if size == 0 { + // treat an empty stream the same as a nil one: assign req a nil body + body = nil + // RFC 9110 specifies a client shouldn't set Content-Length on a request containing no content + // (Del is a no-op when the header has no value) + req.req.Header.Del(shared.HeaderContentLength) + } else { + _, err = body.Seek(0, io.SeekStart) + if err != nil { + return err + } + req.req.Header.Set(shared.HeaderContentLength, strconv.FormatInt(size, 10)) + req.Raw().GetBody = func() (io.ReadCloser, error) { + _, err := body.Seek(0, io.SeekStart) // Seek back to the beginning of the stream + return body, err + } + } + // keep a copy of the body argument. this is to handle cases + // where req.Body is replaced, e.g. httputil.DumpRequest and friends. + req.body = body + req.req.Body = body + req.req.ContentLength = size + if contentType == "" { + // Del is a no-op when the header has no value + req.req.Header.Del(shared.HeaderContentType) + } else if req.req.Header.Get(shared.HeaderContentType) == "" || clobberContentType { + req.req.Header.Set(shared.HeaderContentType, contentType) + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/response_error.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/response_error.go new file mode 100644 index 000000000..8aec256bd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/response_error.go @@ -0,0 +1,201 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package exported + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "regexp" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/internal/exported" +) + +// NewResponseError creates a new *ResponseError from the provided HTTP response. +// Exported as runtime.NewResponseError(). +func NewResponseError(resp *http.Response) error { + // prefer the error code in the response header + if ec := resp.Header.Get(shared.HeaderXMSErrorCode); ec != "" { + return NewResponseErrorWithErrorCode(resp, ec) + } + + // if we didn't get x-ms-error-code, check in the response body + body, err := exported.Payload(resp, nil) + if err != nil { + // since we're not returning the ResponseError in this + // case we also don't want to write it to the log. + return err + } + + var errorCode string + if len(body) > 0 { + if fromJSON := extractErrorCodeJSON(body); fromJSON != "" { + errorCode = fromJSON + } else if fromXML := extractErrorCodeXML(body); fromXML != "" { + errorCode = fromXML + } + } + + return NewResponseErrorWithErrorCode(resp, errorCode) +} + +// NewResponseErrorWithErrorCode creates an *azcore.ResponseError from the provided HTTP response and errorCode. +// Exported as runtime.NewResponseErrorWithErrorCode(). +func NewResponseErrorWithErrorCode(resp *http.Response, errorCode string) error { + respErr := &ResponseError{ + ErrorCode: errorCode, + StatusCode: resp.StatusCode, + RawResponse: resp, + } + log.Write(log.EventResponseError, respErr.Error()) + return respErr +} + +func extractErrorCodeJSON(body []byte) string { + var rawObj map[string]any + if err := json.Unmarshal(body, &rawObj); err != nil { + // not a JSON object + return "" + } + + // check if this is a wrapped error, i.e. { "error": { ... } } + // if so then unwrap it + if wrapped, ok := rawObj["error"]; ok { + unwrapped, ok := wrapped.(map[string]any) + if !ok { + return "" + } + rawObj = unwrapped + } else if wrapped, ok := rawObj["odata.error"]; ok { + // check if this a wrapped odata error, i.e. { "odata.error": { ... } } + unwrapped, ok := wrapped.(map[string]any) + if !ok { + return "" + } + rawObj = unwrapped + } + + // now check for the error code + code, ok := rawObj["code"] + if !ok { + return "" + } + codeStr, ok := code.(string) + if !ok { + return "" + } + return codeStr +} + +func extractErrorCodeXML(body []byte) string { + // regular expression is much easier than dealing with the XML parser + rx := regexp.MustCompile(`<(?:\w+:)?[c|C]ode>\s*(\w+)\s*<\/(?:\w+:)?[c|C]ode>`) + res := rx.FindStringSubmatch(string(body)) + if len(res) != 2 { + return "" + } + // first submatch is the entire thing, second one is the captured error code + return res[1] +} + +// ResponseError is returned when a request is made to a service and +// the service returns a non-success HTTP status code. +// Use errors.As() to access this type in the error chain. +// Exported as azcore.ResponseError. +type ResponseError struct { + // ErrorCode is the error code returned by the resource provider if available. + ErrorCode string + + // StatusCode is the HTTP status code as defined in https://pkg.go.dev/net/http#pkg-constants. + StatusCode int + + // RawResponse is the underlying HTTP response. + RawResponse *http.Response `json:"-"` + + errMsg string +} + +// Error implements the error interface for type ResponseError. +// Note that the message contents are not contractual and can change over time. +func (e *ResponseError) Error() string { + if e.errMsg != "" { + return e.errMsg + } + + const separator = "--------------------------------------------------------------------------------" + // write the request method and URL with response status code + msg := &bytes.Buffer{} + if e.RawResponse != nil { + if e.RawResponse.Request != nil { + fmt.Fprintf(msg, "%s %s://%s%s\n", e.RawResponse.Request.Method, e.RawResponse.Request.URL.Scheme, e.RawResponse.Request.URL.Host, e.RawResponse.Request.URL.Path) + } else { + fmt.Fprintln(msg, "Request information not available") + } + fmt.Fprintln(msg, separator) + fmt.Fprintf(msg, "RESPONSE %d: %s\n", e.RawResponse.StatusCode, e.RawResponse.Status) + } else { + fmt.Fprintln(msg, "Missing RawResponse") + fmt.Fprintln(msg, separator) + } + if e.ErrorCode != "" { + fmt.Fprintf(msg, "ERROR CODE: %s\n", e.ErrorCode) + } else { + fmt.Fprintln(msg, "ERROR CODE UNAVAILABLE") + } + if e.RawResponse != nil { + fmt.Fprintln(msg, separator) + body, err := exported.Payload(e.RawResponse, nil) + if err != nil { + // this really shouldn't fail at this point as the response + // body is already cached (it was read in NewResponseError) + fmt.Fprintf(msg, "Error reading response body: %v", err) + } else if len(body) > 0 { + if err := json.Indent(msg, body, "", " "); err != nil { + // failed to pretty-print so just dump it verbatim + fmt.Fprint(msg, string(body)) + } + // the standard library doesn't have a pretty-printer for XML + fmt.Fprintln(msg) + } else { + fmt.Fprintln(msg, "Response contained no body") + } + } + fmt.Fprintln(msg, separator) + + e.errMsg = msg.String() + return e.errMsg +} + +// internal type used for marshaling/unmarshaling +type responseError struct { + ErrorCode string `json:"errorCode"` + StatusCode int `json:"statusCode"` + ErrorMessage string `json:"errorMessage"` +} + +func (e ResponseError) MarshalJSON() ([]byte, error) { + return json.Marshal(responseError{ + ErrorCode: e.ErrorCode, + StatusCode: e.StatusCode, + ErrorMessage: e.Error(), + }) +} + +func (e *ResponseError) UnmarshalJSON(data []byte) error { + re := responseError{} + if err := json.Unmarshal(data, &re); err != nil { + return err + } + + e.ErrorCode = re.ErrorCode + e.StatusCode = re.StatusCode + e.errMsg = re.ErrorMessage + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log/log.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log/log.go new file mode 100644 index 000000000..6fc6d1400 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log/log.go @@ -0,0 +1,50 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// This is an internal helper package to combine the complete logging APIs. +package log + +import ( + azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log" + "github.com/Azure/azure-sdk-for-go/sdk/internal/log" +) + +type Event = log.Event + +const ( + EventRequest = azlog.EventRequest + EventResponse = azlog.EventResponse + EventResponseError = azlog.EventResponseError + EventRetryPolicy = azlog.EventRetryPolicy + EventLRO = azlog.EventLRO +) + +// Write invokes the underlying listener with the specified event and message. +// If the event shouldn't be logged or there is no listener then Write does nothing. +func Write(cls log.Event, msg string) { + log.Write(cls, msg) +} + +// Writef invokes the underlying listener with the specified event and formatted message. +// If the event shouldn't be logged or there is no listener then Writef does nothing. +func Writef(cls log.Event, format string, a ...any) { + log.Writef(cls, format, a...) +} + +// SetListener will set the Logger to write to the specified listener. +func SetListener(lst func(Event, string)) { + log.SetListener(lst) +} + +// Should returns true if the specified log event should be written to the log. +// By default all log events will be logged. Call SetEvents() to limit +// the log events for logging. +// If no listener has been set this will return false. +// Calling this method is useful when the message to log is computationally expensive +// and you want to avoid the overhead if its log event is not enabled. +func Should(cls log.Event) bool { + return log.Should(cls) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async/async.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async/async.go new file mode 100644 index 000000000..a53462760 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async/async.go @@ -0,0 +1,159 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package async + +import ( + "context" + "errors" + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/async-api-reference.md + +// Applicable returns true if the LRO is using Azure-AsyncOperation. +func Applicable(resp *http.Response) bool { + return resp.Header.Get(shared.HeaderAzureAsync) != "" +} + +// CanResume returns true if the token can rehydrate this poller type. +func CanResume(token map[string]any) bool { + _, ok := token["asyncURL"] + return ok +} + +// Poller is an LRO poller that uses the Azure-AsyncOperation pattern. +type Poller[T any] struct { + pl exported.Pipeline + + resp *http.Response + + // The URL from Azure-AsyncOperation header. + AsyncURL string `json:"asyncURL"` + + // The URL from Location header. + LocURL string `json:"locURL"` + + // The URL from the initial LRO request. + OrigURL string `json:"origURL"` + + // The HTTP method from the initial LRO request. + Method string `json:"method"` + + // The value of final-state-via from swagger, can be the empty string. + FinalState pollers.FinalStateVia `json:"finalState"` + + // The LRO's current state. + CurState string `json:"state"` +} + +// New creates a new Poller from the provided initial response and final-state type. +// Pass nil for response to create an empty Poller for rehydration. +func New[T any](pl exported.Pipeline, resp *http.Response, finalState pollers.FinalStateVia) (*Poller[T], error) { + if resp == nil { + log.Write(log.EventLRO, "Resuming Azure-AsyncOperation poller.") + return &Poller[T]{pl: pl}, nil + } + log.Write(log.EventLRO, "Using Azure-AsyncOperation poller.") + asyncURL := resp.Header.Get(shared.HeaderAzureAsync) + if asyncURL == "" { + return nil, errors.New("response is missing Azure-AsyncOperation header") + } + if !poller.IsValidURL(asyncURL) { + return nil, fmt.Errorf("invalid polling URL %s", asyncURL) + } + // check for provisioning state. if the operation is a RELO + // and terminates synchronously this will prevent extra polling. + // it's ok if there's no provisioning state. + state, _ := poller.GetProvisioningState(resp) + if state == "" { + state = poller.StatusInProgress + } + p := &Poller[T]{ + pl: pl, + resp: resp, + AsyncURL: asyncURL, + LocURL: resp.Header.Get(shared.HeaderLocation), + OrigURL: resp.Request.URL.String(), + Method: resp.Request.Method, + FinalState: finalState, + CurState: state, + } + return p, nil +} + +// Done returns true if the LRO is in a terminal state. +func (p *Poller[T]) Done() bool { + return poller.IsTerminalState(p.CurState) +} + +// Poll retrieves the current state of the LRO. +func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) { + err := pollers.PollHelper(ctx, p.AsyncURL, p.pl, func(resp *http.Response) (string, error) { + if !poller.StatusCodeValid(resp) { + p.resp = resp + return "", exported.NewResponseError(resp) + } + state, err := poller.GetStatus(resp) + if err != nil { + return "", err + } else if state == "" { + return "", errors.New("the response did not contain a status") + } + p.resp = resp + p.CurState = state + return p.CurState, nil + }) + if err != nil { + return nil, err + } + return p.resp, nil +} + +func (p *Poller[T]) Result(ctx context.Context, out *T) error { + if p.resp.StatusCode == http.StatusNoContent { + return nil + } else if poller.Failed(p.CurState) { + return exported.NewResponseError(p.resp) + } + var req *exported.Request + var err error + if p.Method == http.MethodPatch || p.Method == http.MethodPut { + // for PATCH and PUT, the final GET is on the original resource URL + req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL) + } else if p.Method == http.MethodPost { + if p.FinalState == pollers.FinalStateViaAzureAsyncOp { + // no final GET required + } else if p.FinalState == pollers.FinalStateViaOriginalURI { + req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL) + } else if p.LocURL != "" { + // ideally FinalState would be set to "location" but it isn't always. + // must check last due to more permissive condition. + req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL) + } + } + if err != nil { + return err + } + + // if a final GET request has been created, execute it + if req != nil { + resp, err := p.pl.Do(req) + if err != nil { + return err + } + p.resp = resp + } + + return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), "", out) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body/body.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body/body.go new file mode 100644 index 000000000..8751b0514 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body/body.go @@ -0,0 +1,135 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package body + +import ( + "context" + "errors" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// Kind is the identifier of this type in a resume token. +const kind = "body" + +// Applicable returns true if the LRO is using no headers, just provisioning state. +// This is only applicable to PATCH and PUT methods and assumes no polling headers. +func Applicable(resp *http.Response) bool { + // we can't check for absense of headers due to some misbehaving services + // like redis that return a Location header but don't actually use that protocol + return resp.Request.Method == http.MethodPatch || resp.Request.Method == http.MethodPut +} + +// CanResume returns true if the token can rehydrate this poller type. +func CanResume(token map[string]any) bool { + t, ok := token["type"] + if !ok { + return false + } + tt, ok := t.(string) + if !ok { + return false + } + return tt == kind +} + +// Poller is an LRO poller that uses the Body pattern. +type Poller[T any] struct { + pl exported.Pipeline + + resp *http.Response + + // The poller's type, used for resume token processing. + Type string `json:"type"` + + // The URL for polling. + PollURL string `json:"pollURL"` + + // The LRO's current state. + CurState string `json:"state"` +} + +// New creates a new Poller from the provided initial response. +// Pass nil for response to create an empty Poller for rehydration. +func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) { + if resp == nil { + log.Write(log.EventLRO, "Resuming Body poller.") + return &Poller[T]{pl: pl}, nil + } + log.Write(log.EventLRO, "Using Body poller.") + p := &Poller[T]{ + pl: pl, + resp: resp, + Type: kind, + PollURL: resp.Request.URL.String(), + } + // default initial state to InProgress. depending on the HTTP + // status code and provisioning state, we might change the value. + curState := poller.StatusInProgress + provState, err := poller.GetProvisioningState(resp) + if err != nil && !errors.Is(err, poller.ErrNoBody) { + return nil, err + } + if resp.StatusCode == http.StatusCreated && provState != "" { + // absense of provisioning state is ok for a 201, means the operation is in progress + curState = provState + } else if resp.StatusCode == http.StatusOK { + if provState != "" { + curState = provState + } else if provState == "" { + // for a 200, absense of provisioning state indicates success + curState = poller.StatusSucceeded + } + } else if resp.StatusCode == http.StatusNoContent { + curState = poller.StatusSucceeded + } + p.CurState = curState + return p, nil +} + +func (p *Poller[T]) Done() bool { + return poller.IsTerminalState(p.CurState) +} + +func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) { + err := pollers.PollHelper(ctx, p.PollURL, p.pl, func(resp *http.Response) (string, error) { + if !poller.StatusCodeValid(resp) { + p.resp = resp + return "", exported.NewResponseError(resp) + } + if resp.StatusCode == http.StatusNoContent { + p.resp = resp + p.CurState = poller.StatusSucceeded + return p.CurState, nil + } + state, err := poller.GetProvisioningState(resp) + if errors.Is(err, poller.ErrNoBody) { + // a missing response body in non-204 case is an error + return "", err + } else if state == "" { + // a response body without provisioning state is considered terminal success + state = poller.StatusSucceeded + } else if err != nil { + return "", err + } + p.resp = resp + p.CurState = state + return p.CurState, nil + }) + if err != nil { + return nil, err + } + return p.resp, nil +} + +func (p *Poller[T]) Result(ctx context.Context, out *T) error { + return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), "", out) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/fake/fake.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/fake/fake.go new file mode 100644 index 000000000..7f8d11b8b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/fake/fake.go @@ -0,0 +1,133 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package fake + +import ( + "context" + "errors" + "fmt" + "net/http" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// Applicable returns true if the LRO is a fake. +func Applicable(resp *http.Response) bool { + return resp.Header.Get(shared.HeaderFakePollerStatus) != "" +} + +// CanResume returns true if the token can rehydrate this poller type. +func CanResume(token map[string]any) bool { + _, ok := token["fakeURL"] + return ok +} + +// Poller is an LRO poller that uses the Core-Fake-Poller pattern. +type Poller[T any] struct { + pl exported.Pipeline + + resp *http.Response + + // The API name from CtxAPINameKey + APIName string `json:"apiName"` + + // The URL from Core-Fake-Poller header. + FakeURL string `json:"fakeURL"` + + // The LRO's current state. + FakeStatus string `json:"status"` +} + +// lroStatusURLSuffix is the URL path suffix for a faked LRO. +const lroStatusURLSuffix = "/get/fake/status" + +// New creates a new Poller from the provided initial response. +// Pass nil for response to create an empty Poller for rehydration. +func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) { + if resp == nil { + log.Write(log.EventLRO, "Resuming Core-Fake-Poller poller.") + return &Poller[T]{pl: pl}, nil + } + + log.Write(log.EventLRO, "Using Core-Fake-Poller poller.") + fakeStatus := resp.Header.Get(shared.HeaderFakePollerStatus) + if fakeStatus == "" { + return nil, errors.New("response is missing Fake-Poller-Status header") + } + + ctxVal := resp.Request.Context().Value(shared.CtxAPINameKey{}) + if ctxVal == nil { + return nil, errors.New("missing value for CtxAPINameKey") + } + + apiName, ok := ctxVal.(string) + if !ok { + return nil, fmt.Errorf("expected string for CtxAPINameKey, the type was %T", ctxVal) + } + + qp := "" + if resp.Request.URL.RawQuery != "" { + qp = "?" + resp.Request.URL.RawQuery + } + + p := &Poller[T]{ + pl: pl, + resp: resp, + APIName: apiName, + // NOTE: any changes to this path format MUST be reflected in SanitizePollerPath() + FakeURL: fmt.Sprintf("%s://%s%s%s%s", resp.Request.URL.Scheme, resp.Request.URL.Host, resp.Request.URL.Path, lroStatusURLSuffix, qp), + FakeStatus: fakeStatus, + } + return p, nil +} + +// Done returns true if the LRO is in a terminal state. +func (p *Poller[T]) Done() bool { + return poller.IsTerminalState(p.FakeStatus) +} + +// Poll retrieves the current state of the LRO. +func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) { + ctx = context.WithValue(ctx, shared.CtxAPINameKey{}, p.APIName) + err := pollers.PollHelper(ctx, p.FakeURL, p.pl, func(resp *http.Response) (string, error) { + if !poller.StatusCodeValid(resp) { + p.resp = resp + return "", exported.NewResponseError(resp) + } + fakeStatus := resp.Header.Get(shared.HeaderFakePollerStatus) + if fakeStatus == "" { + return "", errors.New("response is missing Fake-Poller-Status header") + } + p.resp = resp + p.FakeStatus = fakeStatus + return p.FakeStatus, nil + }) + if err != nil { + return nil, err + } + return p.resp, nil +} + +func (p *Poller[T]) Result(ctx context.Context, out *T) error { + if p.resp.StatusCode == http.StatusNoContent { + return nil + } else if poller.Failed(p.FakeStatus) { + return exported.NewResponseError(p.resp) + } + + return pollers.ResultHelper(p.resp, poller.Failed(p.FakeStatus), "", out) +} + +// SanitizePollerPath removes any fake-appended suffix from a URL's path. +func SanitizePollerPath(path string) string { + return strings.TrimSuffix(path, lroStatusURLSuffix) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc/loc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc/loc.go new file mode 100644 index 000000000..048285275 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc/loc.go @@ -0,0 +1,123 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package loc + +import ( + "context" + "errors" + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// Kind is the identifier of this type in a resume token. +const kind = "loc" + +// Applicable returns true if the LRO is using Location. +func Applicable(resp *http.Response) bool { + return resp.Header.Get(shared.HeaderLocation) != "" +} + +// CanResume returns true if the token can rehydrate this poller type. +func CanResume(token map[string]any) bool { + t, ok := token["type"] + if !ok { + return false + } + tt, ok := t.(string) + if !ok { + return false + } + return tt == kind +} + +// Poller is an LRO poller that uses the Location pattern. +type Poller[T any] struct { + pl exported.Pipeline + resp *http.Response + + Type string `json:"type"` + PollURL string `json:"pollURL"` + CurState string `json:"state"` +} + +// New creates a new Poller from the provided initial response. +// Pass nil for response to create an empty Poller for rehydration. +func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) { + if resp == nil { + log.Write(log.EventLRO, "Resuming Location poller.") + return &Poller[T]{pl: pl}, nil + } + log.Write(log.EventLRO, "Using Location poller.") + locURL := resp.Header.Get(shared.HeaderLocation) + if locURL == "" { + return nil, errors.New("response is missing Location header") + } + if !poller.IsValidURL(locURL) { + return nil, fmt.Errorf("invalid polling URL %s", locURL) + } + // check for provisioning state. if the operation is a RELO + // and terminates synchronously this will prevent extra polling. + // it's ok if there's no provisioning state. + state, _ := poller.GetProvisioningState(resp) + if state == "" { + state = poller.StatusInProgress + } + return &Poller[T]{ + pl: pl, + resp: resp, + Type: kind, + PollURL: locURL, + CurState: state, + }, nil +} + +func (p *Poller[T]) Done() bool { + return poller.IsTerminalState(p.CurState) +} + +func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) { + err := pollers.PollHelper(ctx, p.PollURL, p.pl, func(resp *http.Response) (string, error) { + // location polling can return an updated polling URL + if h := resp.Header.Get(shared.HeaderLocation); h != "" { + p.PollURL = h + } + // if provisioning state is available, use that. this is only + // for some ARM LRO scenarios (e.g. DELETE with a Location header) + // so if it's missing then use HTTP status code. + provState, _ := poller.GetProvisioningState(resp) + p.resp = resp + if provState != "" { + p.CurState = provState + } else if resp.StatusCode == http.StatusAccepted { + p.CurState = poller.StatusInProgress + } else if resp.StatusCode > 199 && resp.StatusCode < 300 { + // any 2xx other than a 202 indicates success + p.CurState = poller.StatusSucceeded + } else if pollers.IsNonTerminalHTTPStatusCode(resp) { + // the request timed out or is being throttled. + // DO NOT include this as a terminal failure. preserve + // the existing state and return the response. + } else { + p.CurState = poller.StatusFailed + } + return p.CurState, nil + }) + if err != nil { + return nil, err + } + return p.resp, nil +} + +func (p *Poller[T]) Result(ctx context.Context, out *T) error { + return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), "", out) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op/op.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op/op.go new file mode 100644 index 000000000..f49633189 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op/op.go @@ -0,0 +1,148 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package op + +import ( + "context" + "errors" + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// Applicable returns true if the LRO is using Operation-Location. +func Applicable(resp *http.Response) bool { + return resp.Header.Get(shared.HeaderOperationLocation) != "" +} + +// CanResume returns true if the token can rehydrate this poller type. +func CanResume(token map[string]any) bool { + _, ok := token["oplocURL"] + return ok +} + +// Poller is an LRO poller that uses the Operation-Location pattern. +type Poller[T any] struct { + pl exported.Pipeline + resp *http.Response + + OpLocURL string `json:"oplocURL"` + LocURL string `json:"locURL"` + OrigURL string `json:"origURL"` + Method string `json:"method"` + FinalState pollers.FinalStateVia `json:"finalState"` + ResultPath string `json:"resultPath"` + CurState string `json:"state"` +} + +// New creates a new Poller from the provided initial response. +// Pass nil for response to create an empty Poller for rehydration. +func New[T any](pl exported.Pipeline, resp *http.Response, finalState pollers.FinalStateVia, resultPath string) (*Poller[T], error) { + if resp == nil { + log.Write(log.EventLRO, "Resuming Operation-Location poller.") + return &Poller[T]{pl: pl}, nil + } + log.Write(log.EventLRO, "Using Operation-Location poller.") + opURL := resp.Header.Get(shared.HeaderOperationLocation) + if opURL == "" { + return nil, errors.New("response is missing Operation-Location header") + } + if !poller.IsValidURL(opURL) { + return nil, fmt.Errorf("invalid Operation-Location URL %s", opURL) + } + locURL := resp.Header.Get(shared.HeaderLocation) + // Location header is optional + if locURL != "" && !poller.IsValidURL(locURL) { + return nil, fmt.Errorf("invalid Location URL %s", locURL) + } + // default initial state to InProgress. if the + // service sent us a status then use that instead. + curState := poller.StatusInProgress + status, err := poller.GetStatus(resp) + if err != nil && !errors.Is(err, poller.ErrNoBody) { + return nil, err + } + if status != "" { + curState = status + } + + return &Poller[T]{ + pl: pl, + resp: resp, + OpLocURL: opURL, + LocURL: locURL, + OrigURL: resp.Request.URL.String(), + Method: resp.Request.Method, + FinalState: finalState, + ResultPath: resultPath, + CurState: curState, + }, nil +} + +func (p *Poller[T]) Done() bool { + return poller.IsTerminalState(p.CurState) +} + +func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) { + err := pollers.PollHelper(ctx, p.OpLocURL, p.pl, func(resp *http.Response) (string, error) { + if !poller.StatusCodeValid(resp) { + p.resp = resp + return "", exported.NewResponseError(resp) + } + state, err := poller.GetStatus(resp) + if err != nil { + return "", err + } else if state == "" { + return "", errors.New("the response did not contain a status") + } + p.resp = resp + p.CurState = state + return p.CurState, nil + }) + if err != nil { + return nil, err + } + return p.resp, nil +} + +func (p *Poller[T]) Result(ctx context.Context, out *T) error { + var req *exported.Request + var err error + + if p.FinalState == pollers.FinalStateViaLocation && p.LocURL != "" { + req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL) + } else if rl, rlErr := poller.GetResourceLocation(p.resp); rlErr != nil && !errors.Is(rlErr, poller.ErrNoBody) { + return rlErr + } else if rl != "" { + req, err = exported.NewRequest(ctx, http.MethodGet, rl) + } else if p.Method == http.MethodPatch || p.Method == http.MethodPut { + req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL) + } else if p.Method == http.MethodPost && p.LocURL != "" { + req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL) + } + if err != nil { + return err + } + + // if a final GET request has been created, execute it + if req != nil { + // no JSON path when making a final GET request + p.ResultPath = "" + resp, err := p.pl.Do(req) + if err != nil { + return err + } + p.resp = resp + } + + return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), p.ResultPath, out) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/poller.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/poller.go new file mode 100644 index 000000000..37ed647f4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/poller.go @@ -0,0 +1,24 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package pollers + +// FinalStateVia is the enumerated type for the possible final-state-via values. +type FinalStateVia string + +const ( + // FinalStateViaAzureAsyncOp indicates the final payload comes from the Azure-AsyncOperation URL. + FinalStateViaAzureAsyncOp FinalStateVia = "azure-async-operation" + + // FinalStateViaLocation indicates the final payload comes from the Location URL. + FinalStateViaLocation FinalStateVia = "location" + + // FinalStateViaOriginalURI indicates the final payload comes from the original URL. + FinalStateViaOriginalURI FinalStateVia = "original-uri" + + // FinalStateViaOpLocation indicates the final payload comes from the Operation-Location URL. + FinalStateViaOpLocation FinalStateVia = "operation-location" +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/util.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/util.go new file mode 100644 index 000000000..6a7a32e03 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/util.go @@ -0,0 +1,212 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package pollers + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "reflect" + + azexported "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// getTokenTypeName creates a type name from the type parameter T. +func getTokenTypeName[T any]() (string, error) { + tt := shared.TypeOfT[T]() + var n string + if tt.Kind() == reflect.Pointer { + n = "*" + tt = tt.Elem() + } + n += tt.Name() + if n == "" { + return "", errors.New("nameless types are not allowed") + } + return n, nil +} + +type resumeTokenWrapper[T any] struct { + Type string `json:"type"` + Token T `json:"token"` +} + +// NewResumeToken creates a resume token from the specified type. +// An error is returned if the generic type has no name (e.g. struct{}). +func NewResumeToken[TResult, TSource any](from TSource) (string, error) { + n, err := getTokenTypeName[TResult]() + if err != nil { + return "", err + } + b, err := json.Marshal(resumeTokenWrapper[TSource]{ + Type: n, + Token: from, + }) + if err != nil { + return "", err + } + return string(b), nil +} + +// ExtractToken returns the poller-specific token information from the provided token value. +func ExtractToken(token string) ([]byte, error) { + raw := map[string]json.RawMessage{} + if err := json.Unmarshal([]byte(token), &raw); err != nil { + return nil, err + } + // this is dependent on the type resumeTokenWrapper[T] + tk, ok := raw["token"] + if !ok { + return nil, errors.New("missing token value") + } + return tk, nil +} + +// IsTokenValid returns an error if the specified token isn't applicable for generic type T. +func IsTokenValid[T any](token string) error { + raw := map[string]any{} + if err := json.Unmarshal([]byte(token), &raw); err != nil { + return err + } + t, ok := raw["type"] + if !ok { + return errors.New("missing type value") + } + tt, ok := t.(string) + if !ok { + return fmt.Errorf("invalid type format %T", t) + } + n, err := getTokenTypeName[T]() + if err != nil { + return err + } + if tt != n { + return fmt.Errorf("cannot resume from this poller token. token is for type %s, not %s", tt, n) + } + return nil +} + +// used if the operation synchronously completed +type NopPoller[T any] struct { + resp *http.Response + result T +} + +// NewNopPoller creates a NopPoller from the provided response. +// It unmarshals the response body into an instance of T. +func NewNopPoller[T any](resp *http.Response) (*NopPoller[T], error) { + np := &NopPoller[T]{resp: resp} + if resp.StatusCode == http.StatusNoContent { + return np, nil + } + payload, err := exported.Payload(resp, nil) + if err != nil { + return nil, err + } + if len(payload) == 0 { + return np, nil + } + if err = json.Unmarshal(payload, &np.result); err != nil { + return nil, err + } + return np, nil +} + +func (*NopPoller[T]) Done() bool { + return true +} + +func (p *NopPoller[T]) Poll(context.Context) (*http.Response, error) { + return p.resp, nil +} + +func (p *NopPoller[T]) Result(ctx context.Context, out *T) error { + *out = p.result + return nil +} + +// PollHelper creates and executes the request, calling update() with the response. +// If the request fails, the update func is not called. +// The update func returns the state of the operation for logging purposes or an error +// if it fails to extract the required state from the response. +func PollHelper(ctx context.Context, endpoint string, pl azexported.Pipeline, update func(resp *http.Response) (string, error)) error { + req, err := azexported.NewRequest(ctx, http.MethodGet, endpoint) + if err != nil { + return err + } + resp, err := pl.Do(req) + if err != nil { + return err + } + state, err := update(resp) + if err != nil { + return err + } + log.Writef(log.EventLRO, "State %s", state) + return nil +} + +// ResultHelper processes the response as success or failure. +// In the success case, it unmarshals the payload into either a new instance of T or out. +// In the failure case, it creates an *azcore.Response error from the response. +func ResultHelper[T any](resp *http.Response, failed bool, jsonPath string, out *T) error { + // short-circuit the simple success case with no response body to unmarshal + if resp.StatusCode == http.StatusNoContent { + return nil + } + + defer resp.Body.Close() + if !poller.StatusCodeValid(resp) || failed { + // the LRO failed. unmarshall the error and update state + return azexported.NewResponseError(resp) + } + + // success case + payload, err := exported.Payload(resp, nil) + if err != nil { + return err + } + + if jsonPath != "" && len(payload) > 0 { + // extract the payload from the specified JSON path. + // do this before the zero-length check in case there + // is no payload. + jsonBody := map[string]json.RawMessage{} + if err = json.Unmarshal(payload, &jsonBody); err != nil { + return err + } + payload = jsonBody[jsonPath] + } + + if len(payload) == 0 { + return nil + } + + if err = json.Unmarshal(payload, out); err != nil { + return err + } + return nil +} + +// IsNonTerminalHTTPStatusCode returns true if the HTTP status code should be +// considered non-terminal thus eligible for retry. +func IsNonTerminalHTTPStatusCode(resp *http.Response) bool { + return exported.HasStatusCode(resp, + http.StatusRequestTimeout, // 408 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + ) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go new file mode 100644 index 000000000..8aebe5ce5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go @@ -0,0 +1,44 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package shared + +const ( + ContentTypeAppJSON = "application/json" + ContentTypeAppXML = "application/xml" + ContentTypeTextPlain = "text/plain" +) + +const ( + HeaderAuthorization = "Authorization" + HeaderAuxiliaryAuthorization = "x-ms-authorization-auxiliary" + HeaderAzureAsync = "Azure-AsyncOperation" + HeaderContentLength = "Content-Length" + HeaderContentType = "Content-Type" + HeaderFakePollerStatus = "Fake-Poller-Status" + HeaderLocation = "Location" + HeaderOperationLocation = "Operation-Location" + HeaderRetryAfter = "Retry-After" + HeaderRetryAfterMS = "Retry-After-Ms" + HeaderUserAgent = "User-Agent" + HeaderWWWAuthenticate = "WWW-Authenticate" + HeaderXMSClientRequestID = "x-ms-client-request-id" + HeaderXMSRequestID = "x-ms-request-id" + HeaderXMSErrorCode = "x-ms-error-code" + HeaderXMSRetryAfterMS = "x-ms-retry-after-ms" +) + +const BearerTokenPrefix = "Bearer " + +const TracingNamespaceAttrName = "az.namespace" + +const ( + // Module is the name of the calling module used in telemetry data. + Module = "azcore" + + // Version is the semantic version (see http://semver.org) of this module. + Version = "v1.19.1" +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/shared.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/shared.go new file mode 100644 index 000000000..d3da2c5fd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/shared.go @@ -0,0 +1,149 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package shared + +import ( + "context" + "fmt" + "net/http" + "reflect" + "regexp" + "strconv" + "time" +) + +// NOTE: when adding a new context key type, it likely needs to be +// added to the deny-list of key types in ContextWithDeniedValues + +// CtxWithHTTPHeaderKey is used as a context key for adding/retrieving http.Header. +type CtxWithHTTPHeaderKey struct{} + +// CtxWithRetryOptionsKey is used as a context key for adding/retrieving RetryOptions. +type CtxWithRetryOptionsKey struct{} + +// CtxWithCaptureResponse is used as a context key for retrieving the raw response. +type CtxWithCaptureResponse struct{} + +// CtxWithTracingTracer is used as a context key for adding/retrieving tracing.Tracer. +type CtxWithTracingTracer struct{} + +// CtxAPINameKey is used as a context key for adding/retrieving the API name. +type CtxAPINameKey struct{} + +// Delay waits for the duration to elapse or the context to be cancelled. +func Delay(ctx context.Context, delay time.Duration) error { + select { + case <-time.After(delay): + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +// RetryAfter returns non-zero if the response contains one of the headers with a "retry after" value. +// Headers are checked in the following order: retry-after-ms, x-ms-retry-after-ms, retry-after +func RetryAfter(resp *http.Response) time.Duration { + if resp == nil { + return 0 + } + + type retryData struct { + header string + units time.Duration + + // custom is used when the regular algorithm failed and is optional. + // the returned duration is used verbatim (units is not applied). + custom func(string) time.Duration + } + + nop := func(string) time.Duration { return 0 } + + // the headers are listed in order of preference + retries := []retryData{ + { + header: HeaderRetryAfterMS, + units: time.Millisecond, + custom: nop, + }, + { + header: HeaderXMSRetryAfterMS, + units: time.Millisecond, + custom: nop, + }, + { + header: HeaderRetryAfter, + units: time.Second, + + // retry-after values are expressed in either number of + // seconds or an HTTP-date indicating when to try again + custom: func(ra string) time.Duration { + t, err := time.Parse(time.RFC1123, ra) + if err != nil { + return 0 + } + return time.Until(t) + }, + }, + } + + for _, retry := range retries { + v := resp.Header.Get(retry.header) + if v == "" { + continue + } + if retryAfter, _ := strconv.Atoi(v); retryAfter > 0 { + return time.Duration(retryAfter) * retry.units + } else if d := retry.custom(v); d > 0 { + return d + } + } + + return 0 +} + +// TypeOfT returns the type of the generic type param. +func TypeOfT[T any]() reflect.Type { + // you can't, at present, obtain the type of + // a type parameter, so this is the trick + return reflect.TypeOf((*T)(nil)).Elem() +} + +// TransportFunc is a helper to use a first-class func to satisfy the Transporter interface. +type TransportFunc func(*http.Request) (*http.Response, error) + +// Do implements the Transporter interface for the TransportFunc type. +func (pf TransportFunc) Do(req *http.Request) (*http.Response, error) { + return pf(req) +} + +// ValidateModVer verifies that moduleVersion is a valid semver 2.0 string. +func ValidateModVer(moduleVersion string) error { + modVerRegx := regexp.MustCompile(`^v\d+\.\d+\.\d+(?:-[a-zA-Z0-9_.-]+)?$`) + if !modVerRegx.MatchString(moduleVersion) { + return fmt.Errorf("malformed moduleVersion param value %s", moduleVersion) + } + return nil +} + +// ContextWithDeniedValues wraps an existing [context.Context], denying access to certain context values. +// Pipeline policies that create new requests to be sent down their own pipeline MUST wrap the caller's +// context with an instance of this type. This is to prevent context values from flowing across disjoint +// requests which can have unintended side-effects. +type ContextWithDeniedValues struct { + context.Context +} + +// Value implements part of the [context.Context] interface. +// It acts as a deny-list for certain context keys. +func (c *ContextWithDeniedValues) Value(key any) any { + switch key.(type) { + case CtxAPINameKey, CtxWithCaptureResponse, CtxWithHTTPHeaderKey, CtxWithRetryOptionsKey, CtxWithTracingTracer: + return nil + default: + return c.Context.Value(key) + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/doc.go new file mode 100644 index 000000000..2f3901bff --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/doc.go @@ -0,0 +1,10 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package log contains functionality for configuring logging behavior. +// Default logging to stderr can be enabled by setting environment variable AZURE_SDK_GO_LOGGING to "all". +package log diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/log.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/log.go new file mode 100644 index 000000000..f260dac36 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/log/log.go @@ -0,0 +1,55 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// Package log provides functionality for configuring logging facilities. +package log + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/internal/log" +) + +// Event is used to group entries. Each group can be toggled on or off. +type Event = log.Event + +const ( + // EventRequest entries contain information about HTTP requests. + // This includes information like the URL, query parameters, and headers. + EventRequest Event = "Request" + + // EventResponse entries contain information about HTTP responses. + // This includes information like the HTTP status code, headers, and request URL. + EventResponse Event = "Response" + + // EventResponseError entries contain information about HTTP responses that returned + // an *azcore.ResponseError (i.e. responses with a non 2xx HTTP status code). + // This includes the contents of ResponseError.Error(). + EventResponseError Event = "ResponseError" + + // EventRetryPolicy entries contain information specific to the retry policy in use. + EventRetryPolicy Event = "Retry" + + // EventLRO entries contain information specific to long-running operations. + // This includes information like polling location, operation state, and sleep intervals. + EventLRO Event = "LongRunningOperation" +) + +// SetEvents is used to control which events are written to +// the log. By default all log events are writen. +// NOTE: this is not goroutine safe and should be called before using SDK clients. +func SetEvents(cls ...Event) { + log.SetEvents(cls...) +} + +// SetListener will set the Logger to write to the specified Listener. +// NOTE: this is not goroutine safe and should be called before using SDK clients. +func SetListener(lst func(Event, string)) { + log.SetListener(lst) +} + +// for testing purposes +func resetEvents() { + log.TestResetEvents() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/doc.go new file mode 100644 index 000000000..fad2579ed --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/doc.go @@ -0,0 +1,10 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package policy contains the definitions needed for configuring in-box pipeline policies +// and creating custom policies. +package policy diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go new file mode 100644 index 000000000..368a2199e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/policy/policy.go @@ -0,0 +1,198 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package policy + +import ( + "context" + "net/http" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +// Policy represents an extensibility point for the Pipeline that can mutate the specified +// Request and react to the received Response. +type Policy = exported.Policy + +// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses. +type Transporter = exported.Transporter + +// Request is an abstraction over the creation of an HTTP request as it passes through the pipeline. +// Don't use this type directly, use runtime.NewRequest() instead. +type Request = exported.Request + +// ClientOptions contains optional settings for a client's pipeline. +// Instances can be shared across calls to SDK client constructors when uniform configuration is desired. +// Zero-value fields will have their specified default values applied during use. +type ClientOptions struct { + // APIVersion overrides the default version requested of the service. + // Set with caution as this package version has not been tested with arbitrary service versions. + APIVersion string + + // Cloud specifies a cloud for the client. The default is Azure Public Cloud. + Cloud cloud.Configuration + + // InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP. + // By default, authenticated requests to an HTTP endpoint are rejected by the client. + // WARNING: setting this to true will allow sending the credential in clear text. Use with caution. + InsecureAllowCredentialWithHTTP bool + + // Logging configures the built-in logging policy. + Logging LogOptions + + // Retry configures the built-in retry policy. + Retry RetryOptions + + // Telemetry configures the built-in telemetry policy. + Telemetry TelemetryOptions + + // TracingProvider configures the tracing provider. + // It defaults to a no-op tracer. + TracingProvider tracing.Provider + + // Transport sets the transport for HTTP requests. + Transport Transporter + + // PerCallPolicies contains custom policies to inject into the pipeline. + // Each policy is executed once per request. + PerCallPolicies []Policy + + // PerRetryPolicies contains custom policies to inject into the pipeline. + // Each policy is executed once per request, and for each retry of that request. + PerRetryPolicies []Policy +} + +// LogOptions configures the logging policy's behavior. +type LogOptions struct { + // IncludeBody indicates if request and response bodies should be included in logging. + // The default value is false. + // NOTE: enabling this can lead to disclosure of sensitive information, use with care. + IncludeBody bool + + // AllowedHeaders is the slice of headers to log with their values intact. + // All headers not in the slice will have their values REDACTED. + // Applies to request and response headers. + AllowedHeaders []string + + // AllowedQueryParams is the slice of query parameters to log with their values intact. + // All query parameters not in the slice will have their values REDACTED. + AllowedQueryParams []string +} + +// RetryOptions configures the retry policy's behavior. +// Zero-value fields will have their specified default values applied during use. +// This allows for modification of a subset of fields. +type RetryOptions struct { + // MaxRetries specifies the maximum number of attempts a failed operation will be retried + // before producing an error. + // The default value is three. A value less than zero means one try and no retries. + MaxRetries int32 + + // TryTimeout indicates the maximum time allowed for any single try of an HTTP request. + // This is disabled by default. Specify a value greater than zero to enable. + // NOTE: Setting this to a small value might cause premature HTTP request time-outs. + TryTimeout time.Duration + + // RetryDelay specifies the initial amount of delay to use before retrying an operation. + // The value is used only if the HTTP response does not contain a Retry-After header. + // The delay increases exponentially with each retry up to the maximum specified by MaxRetryDelay. + // The default value is 800 milliseconds. A value less than zero means no delay between retries. + RetryDelay time.Duration + + // MaxRetryDelay specifies the maximum delay allowed before retrying an operation. + // Typically the value is greater than or equal to the value specified in RetryDelay. + // The default Value is 60 seconds. A value less than zero means there is no cap. + MaxRetryDelay time.Duration + + // StatusCodes specifies the HTTP status codes that indicate the operation should be retried. + // A nil slice will use the following values. + // http.StatusRequestTimeout 408 + // http.StatusTooManyRequests 429 + // http.StatusInternalServerError 500 + // http.StatusBadGateway 502 + // http.StatusServiceUnavailable 503 + // http.StatusGatewayTimeout 504 + // Specifying values will replace the default values. + // Specifying an empty slice will disable retries for HTTP status codes. + StatusCodes []int + + // ShouldRetry evaluates if the retry policy should retry the request. + // When specified, the function overrides comparison against the list of + // HTTP status codes and error checking within the retry policy. Context + // and NonRetriable errors remain evaluated before calling ShouldRetry. + // The *http.Response and error parameters are mutually exclusive, i.e. + // if one is nil, the other is not nil. + // A return value of true means the retry policy should retry. + ShouldRetry func(*http.Response, error) bool +} + +// TelemetryOptions configures the telemetry policy's behavior. +type TelemetryOptions struct { + // ApplicationID is an application-specific identification string to add to the User-Agent. + // It has a maximum length of 24 characters and must not contain any spaces. + ApplicationID string + + // Disabled will prevent the addition of any telemetry data to the User-Agent. + Disabled bool +} + +// TokenRequestOptions contain specific parameter that may be used by credentials types when attempting to get a token. +type TokenRequestOptions = exported.TokenRequestOptions + +// BearerTokenOptions configures the bearer token policy's behavior. +type BearerTokenOptions struct { + // AuthorizationHandler allows SDK developers to run client-specific logic when BearerTokenPolicy must authorize a request. + // When this field isn't set, the policy follows its default behavior of authorizing every request with a bearer token from + // its given credential. + AuthorizationHandler AuthorizationHandler + + // InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP. + // By default, authenticated requests to an HTTP endpoint are rejected by the client. + // WARNING: setting this to true will allow sending the bearer token in clear text. Use with caution. + InsecureAllowCredentialWithHTTP bool +} + +// AuthorizationHandler allows SDK developers to insert custom logic that runs when BearerTokenPolicy must authorize a request. +type AuthorizationHandler struct { + // OnRequest provides TokenRequestOptions the policy can use to acquire a token for a request. The policy calls OnRequest + // whenever it needs a token and may call it multiple times for the same request. Its func parameter authorizes the request + // with a token from the policy's credential. Implementations that need to perform I/O should use the Request's context, + // available from Request.Raw().Context(). When OnRequest returns an error, the policy propagates that error and doesn't send + // the request. When OnRequest is nil, the policy follows its default behavior, which is to authorize the request with a token + // from its credential according to its configuration. + OnRequest func(*Request, func(TokenRequestOptions) error) error + + // OnChallenge allows clients to implement custom HTTP authentication challenge handling. BearerTokenPolicy calls it upon + // receiving a 401 response containing multiple Bearer challenges or a challenge BearerTokenPolicy itself can't handle. + // OnChallenge is responsible for parsing challenge(s) (the Response's WWW-Authenticate header) and reauthorizing the + // Request accordingly. Its func argument authorizes the Request with a token from the policy's credential using the given + // TokenRequestOptions. OnChallenge should honor the Request's context, available from Request.Raw().Context(). When + // OnChallenge returns nil, the policy will send the Request again. + OnChallenge func(*Request, *http.Response, func(TokenRequestOptions) error) error +} + +// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context. +// The resp parameter will contain the HTTP response after the request has completed. +func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context { + return context.WithValue(parent, shared.CtxWithCaptureResponse{}, resp) +} + +// WithHTTPHeader adds the specified http.Header to the parent context. +// Use this to specify custom HTTP headers at the API-call level. +// Any overlapping headers will have their values replaced with the values specified here. +func WithHTTPHeader(parent context.Context, header http.Header) context.Context { + return context.WithValue(parent, shared.CtxWithHTTPHeaderKey{}, header) +} + +// WithRetryOptions adds the specified RetryOptions to the parent context. +// Use this to specify custom RetryOptions at the API-call level. +func WithRetryOptions(parent context.Context, options RetryOptions) context.Context { + return context.WithValue(parent, shared.CtxWithRetryOptionsKey{}, options) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/doc.go new file mode 100644 index 000000000..c9cfa438c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/doc.go @@ -0,0 +1,10 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package runtime contains various facilities for creating requests and handling responses. +// The content is intended for SDK authors. +package runtime diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/errors.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/errors.go new file mode 100644 index 000000000..c0d56158e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/errors.go @@ -0,0 +1,27 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" +) + +// NewResponseError creates an *azcore.ResponseError from the provided HTTP response. +// Call this when a service request returns a non-successful status code. +// The error code will be extracted from the *http.Response, either from the x-ms-error-code +// header (preferred) or attempted to be parsed from the response body. +func NewResponseError(resp *http.Response) error { + return exported.NewResponseError(resp) +} + +// NewResponseErrorWithErrorCode creates an *azcore.ResponseError from the provided HTTP response and errorCode. +// Use this variant when the error code is in a non-standard location. +func NewResponseErrorWithErrorCode(resp *http.Response, errorCode string) error { + return exported.NewResponseErrorWithErrorCode(resp, errorCode) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pager.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pager.go new file mode 100644 index 000000000..c66fc0a90 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pager.go @@ -0,0 +1,138 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "reflect" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +// PagingHandler contains the required data for constructing a Pager. +type PagingHandler[T any] struct { + // More returns a boolean indicating if there are more pages to fetch. + // It uses the provided page to make the determination. + More func(T) bool + + // Fetcher fetches the first and subsequent pages. + Fetcher func(context.Context, *T) (T, error) + + // Tracer contains the Tracer from the client that's creating the Pager. + Tracer tracing.Tracer +} + +// Pager provides operations for iterating over paged responses. +// Methods on this type are not safe for concurrent use. +type Pager[T any] struct { + current *T + handler PagingHandler[T] + tracer tracing.Tracer + firstPage bool +} + +// NewPager creates an instance of Pager using the specified PagingHandler. +// Pass a non-nil T for firstPage if the first page has already been retrieved. +func NewPager[T any](handler PagingHandler[T]) *Pager[T] { + return &Pager[T]{ + handler: handler, + tracer: handler.Tracer, + firstPage: true, + } +} + +// More returns true if there are more pages to retrieve. +func (p *Pager[T]) More() bool { + if p.current != nil { + return p.handler.More(*p.current) + } + return true +} + +// NextPage advances the pager to the next page. +func (p *Pager[T]) NextPage(ctx context.Context) (T, error) { + if p.current != nil { + if p.firstPage { + // we get here if it's an LRO-pager, we already have the first page + p.firstPage = false + return *p.current, nil + } else if !p.handler.More(*p.current) { + return *new(T), errors.New("no more pages") + } + } else { + // non-LRO case, first page + p.firstPage = false + } + + var err error + ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.NextPage", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil) + defer func() { endSpan(err) }() + + resp, err := p.handler.Fetcher(ctx, p.current) + if err != nil { + return *new(T), err + } + p.current = &resp + return *p.current, nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for Pager[T]. +func (p *Pager[T]) UnmarshalJSON(data []byte) error { + return json.Unmarshal(data, &p.current) +} + +// FetcherForNextLinkOptions contains the optional values for [FetcherForNextLink]. +type FetcherForNextLinkOptions struct { + // NextReq is the func to be called when requesting subsequent pages. + // Used for paged operations that have a custom next link operation. + NextReq func(context.Context, string) (*policy.Request, error) + + // StatusCodes contains additional HTTP status codes indicating success. + // The default value is http.StatusOK. + StatusCodes []int +} + +// FetcherForNextLink is a helper containing boilerplate code to simplify creating a PagingHandler[T].Fetcher from a next link URL. +// - ctx is the [context.Context] controlling the lifetime of the HTTP operation +// - pl is the [Pipeline] used to dispatch the HTTP request +// - nextLink is the URL used to fetch the next page. the empty string indicates the first page is to be requested +// - firstReq is the func to be called when creating the request for the first page +// - options contains any optional parameters, pass nil to accept the default values +func FetcherForNextLink(ctx context.Context, pl Pipeline, nextLink string, firstReq func(context.Context) (*policy.Request, error), options *FetcherForNextLinkOptions) (*http.Response, error) { + var req *policy.Request + var err error + if options == nil { + options = &FetcherForNextLinkOptions{} + } + if nextLink == "" { + req, err = firstReq(ctx) + } else if nextLink, err = EncodeQueryParams(nextLink); err == nil { + if options.NextReq != nil { + req, err = options.NextReq(ctx, nextLink) + } else { + req, err = NewRequest(ctx, http.MethodGet, nextLink) + } + } + if err != nil { + return nil, err + } + resp, err := pl.Do(req) + if err != nil { + return nil, err + } + successCodes := []int{http.StatusOK} + successCodes = append(successCodes, options.StatusCodes...) + if !HasStatusCode(resp, successCodes...) { + return nil, NewResponseError(resp) + } + return resp, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pipeline.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pipeline.go new file mode 100644 index 000000000..6b1f5c083 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pipeline.go @@ -0,0 +1,94 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// PipelineOptions contains Pipeline options for SDK developers +type PipelineOptions struct { + // AllowedHeaders is the slice of headers to log with their values intact. + // All headers not in the slice will have their values REDACTED. + // Applies to request and response headers. + AllowedHeaders []string + + // AllowedQueryParameters is the slice of query parameters to log with their values intact. + // All query parameters not in the slice will have their values REDACTED. + AllowedQueryParameters []string + + // APIVersion overrides the default version requested of the service. + // Set with caution as this package version has not been tested with arbitrary service versions. + APIVersion APIVersionOptions + + // PerCall contains custom policies to inject into the pipeline. + // Each policy is executed once per request. + PerCall []policy.Policy + + // PerRetry contains custom policies to inject into the pipeline. + // Each policy is executed once per request, and for each retry of that request. + PerRetry []policy.Policy + + // Tracing contains options used to configure distributed tracing. + Tracing TracingOptions +} + +// TracingOptions contains tracing options for SDK developers. +type TracingOptions struct { + // Namespace contains the value to use for the az.namespace span attribute. + Namespace string +} + +// Pipeline represents a primitive for sending HTTP requests and receiving responses. +// Its behavior can be extended by specifying policies during construction. +type Pipeline = exported.Pipeline + +// NewPipeline creates a pipeline from connection options, with any additional policies as specified. +// Policies from ClientOptions are placed after policies from PipelineOptions. +// The module and version parameters are used by the telemetry policy, when enabled. +func NewPipeline(module, version string, plOpts PipelineOptions, options *policy.ClientOptions) Pipeline { + cp := policy.ClientOptions{} + if options != nil { + cp = *options + } + if len(plOpts.AllowedHeaders) > 0 { + headers := make([]string, len(plOpts.AllowedHeaders)+len(cp.Logging.AllowedHeaders)) + copy(headers, plOpts.AllowedHeaders) + headers = append(headers, cp.Logging.AllowedHeaders...) + cp.Logging.AllowedHeaders = headers + } + if len(plOpts.AllowedQueryParameters) > 0 { + qp := make([]string, len(plOpts.AllowedQueryParameters)+len(cp.Logging.AllowedQueryParams)) + copy(qp, plOpts.AllowedQueryParameters) + qp = append(qp, cp.Logging.AllowedQueryParams...) + cp.Logging.AllowedQueryParams = qp + } + // we put the includeResponsePolicy at the very beginning so that the raw response + // is populated with the final response (some policies might mutate the response) + policies := []policy.Policy{exported.PolicyFunc(includeResponsePolicy)} + if cp.APIVersion != "" { + policies = append(policies, newAPIVersionPolicy(cp.APIVersion, &plOpts.APIVersion)) + } + if !cp.Telemetry.Disabled { + policies = append(policies, NewTelemetryPolicy(module, version, &cp.Telemetry)) + } + policies = append(policies, plOpts.PerCall...) + policies = append(policies, cp.PerCallPolicies...) + policies = append(policies, NewRetryPolicy(&cp.Retry)) + policies = append(policies, plOpts.PerRetry...) + policies = append(policies, cp.PerRetryPolicies...) + policies = append(policies, exported.PolicyFunc(httpHeaderPolicy)) + policies = append(policies, newHTTPTracePolicy(cp.Logging.AllowedQueryParams)) + policies = append(policies, NewLogPolicy(&cp.Logging)) + policies = append(policies, exported.PolicyFunc(bodyDownloadPolicy)) + transport := cp.Transport + if transport == nil { + transport = defaultHTTPClient + } + return exported.NewPipeline(transport, policies...) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go new file mode 100644 index 000000000..c3646feb5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_api_version.go @@ -0,0 +1,81 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "errors" + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// APIVersionOptions contains options for API versions +type APIVersionOptions struct { + // Location indicates where to set the version on a request, for example in a header or query param. + Location APIVersionLocation + // Name is the name of the header or query parameter, for example "api-version". + // For [APIVersionLocationPath] the value is not used. + Name string +} + +// APIVersionLocation indicates which part of a request identifies the service version +type APIVersionLocation int + +const ( + // APIVersionLocationQueryParam indicates a query parameter + APIVersionLocationQueryParam = 0 + // APIVersionLocationHeader indicates a header + APIVersionLocationHeader = 1 + // APIVersionLocationPath indicates a path segment + APIVersionLocationPath = 2 +) + +// newAPIVersionPolicy constructs an APIVersionPolicy. If version is "", Do will be a no-op. If version +// isn't empty and opts.Name is empty, Do will return an error. +func newAPIVersionPolicy(version string, opts *APIVersionOptions) *apiVersionPolicy { + if opts == nil { + opts = &APIVersionOptions{} + } + return &apiVersionPolicy{location: opts.Location, name: opts.Name, version: version} +} + +// apiVersionPolicy enables users to set the API version of every request a client sends. +type apiVersionPolicy struct { + // location indicates whether "name" refers to a query parameter or header. + location APIVersionLocation + + // name of the query param or header whose value should be overridden; provided by the client. + name string + + // version is the value (provided by the user) that replaces the default version value. + version string +} + +// Do sets the request's API version, if the policy is configured to do so, replacing any prior value. +func (a *apiVersionPolicy) Do(req *policy.Request) (*http.Response, error) { + // for API versions in the path, the client is responsible for + // setting the correct path segment with the version. so, if the + // location is path the policy is effectively a no-op. + if a.location != APIVersionLocationPath && a.version != "" { + if a.name == "" { + // user set ClientOptions.APIVersion but the client ctor didn't set PipelineOptions.APIVersionOptions + return nil, errors.New("this client doesn't support overriding its API version") + } + switch a.location { + case APIVersionLocationHeader: + req.Raw().Header.Set(a.name, a.version) + case APIVersionLocationQueryParam: + q := req.Raw().URL.Query() + q.Set(a.name, a.version) + req.Raw().URL.RawQuery = q.Encode() + default: + return nil, fmt.Errorf("unknown APIVersionLocation %d", a.location) + } + } + return req.Next() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go new file mode 100644 index 000000000..547e5a327 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go @@ -0,0 +1,250 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "encoding/base64" + "errors" + "net/http" + "regexp" + "strings" + "sync" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo" + "github.com/Azure/azure-sdk-for-go/sdk/internal/temporal" +) + +// BearerTokenPolicy authorizes requests with bearer tokens acquired from a TokenCredential. +// It handles [Continuous Access Evaluation] (CAE) challenges. Clients needing to handle +// additional authentication challenges, or needing more control over authorization, should +// provide a [policy.AuthorizationHandler] in [policy.BearerTokenOptions]. +// +// [Continuous Access Evaluation]: https://learn.microsoft.com/entra/identity/conditional-access/concept-continuous-access-evaluation +type BearerTokenPolicy struct { + // mainResource is the resource to be retreived using the tenant specified in the credential + mainResource *temporal.Resource[exported.AccessToken, acquiringResourceState] + // the following fields are read-only + authzHandler policy.AuthorizationHandler + cred exported.TokenCredential + scopes []string + allowHTTP bool +} + +type acquiringResourceState struct { + req *policy.Request + p *BearerTokenPolicy + tro policy.TokenRequestOptions +} + +// acquire acquires or updates the resource; only one +// thread/goroutine at a time ever calls this function +func acquire(state acquiringResourceState) (newResource exported.AccessToken, newExpiration time.Time, err error) { + tk, err := state.p.cred.GetToken(&shared.ContextWithDeniedValues{Context: state.req.Raw().Context()}, state.tro) + if err != nil { + return exported.AccessToken{}, time.Time{}, err + } + return tk, tk.ExpiresOn, nil +} + +// 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. +// opts: optional settings. Pass nil to accept default values; this is the same as passing a zero-value options. +func NewBearerTokenPolicy(cred exported.TokenCredential, scopes []string, opts *policy.BearerTokenOptions) *BearerTokenPolicy { + if opts == nil { + opts = &policy.BearerTokenOptions{} + } + ah := opts.AuthorizationHandler + if ah.OnRequest == nil { + // Set a default OnRequest that simply requests a token with the given scopes. OnChallenge + // doesn't get a default so the policy can use a nil check to determine whether the caller + // provided an implementation. + ah.OnRequest = func(_ *policy.Request, authNZ func(policy.TokenRequestOptions) error) error { + // authNZ sets EnableCAE: true in all cases, no need to duplicate that here + return authNZ(policy.TokenRequestOptions{Scopes: scopes}) + } + } + mr := temporal.NewResourceWithOptions(acquire, temporal.ResourceOptions[exported.AccessToken, acquiringResourceState]{ + ShouldRefresh: shouldRefresh, + }) + return &BearerTokenPolicy{ + authzHandler: ah, + cred: cred, + scopes: scopes, + mainResource: mr, + allowHTTP: opts.InsecureAllowCredentialWithHTTP, + } +} + +// authenticateAndAuthorize returns a function which authorizes req with a token from the policy's credential +func (b *BearerTokenPolicy) authenticateAndAuthorize(req *policy.Request) func(policy.TokenRequestOptions) error { + return func(tro policy.TokenRequestOptions) error { + tro.EnableCAE = true + as := acquiringResourceState{p: b, req: req, tro: tro} + tk, err := b.mainResource.Get(as) + if err != nil { + // consider this error non-retriable because if it could be resolved by + // retrying authentication, the credential would have done so already + return errorinfo.NonRetriableError(err) + } + req.Raw().Header.Set(shared.HeaderAuthorization, shared.BearerTokenPrefix+tk.Token) + return nil + } +} + +// Do authorizes a request with a bearer token +func (b *BearerTokenPolicy) Do(req *policy.Request) (*http.Response, error) { + // skip adding the authorization header if no TokenCredential was provided. + // this prevents a panic that might be hard to diagnose and allows testing + // against http endpoints that don't require authentication. + if b.cred == nil { + return req.Next() + } + + if err := checkHTTPSForAuth(req, b.allowHTTP); err != nil { + return nil, err + } + + err := b.authzHandler.OnRequest(req, b.authenticateAndAuthorize(req)) + if err != nil { + return nil, errorinfo.NonRetriableError(err) + } + + res, err := req.Next() + if err != nil { + return nil, err + } + + res, err = b.handleChallenge(req, res, false) + return res, err +} + +// handleChallenge handles authentication challenges either directly (for CAE challenges) or by calling +// the AuthorizationHandler. It's a no-op when the response doesn't include an authentication challenge. +// It will recurse at most once, to handle a CAE challenge following a non-CAE challenge handled by the +// AuthorizationHandler. +func (b *BearerTokenPolicy) handleChallenge(req *policy.Request, res *http.Response, recursed bool) (*http.Response, error) { + var err error + if res.StatusCode == http.StatusUnauthorized { + b.mainResource.Expire() + if res.Header.Get(shared.HeaderWWWAuthenticate) != "" { + caeChallenge, parseErr := parseCAEChallenge(res) + if parseErr != nil { + return res, parseErr + } + switch { + case caeChallenge != nil: + authNZ := func(tro policy.TokenRequestOptions) error { + // Take the TokenRequestOptions provided by OnRequest and add the challenge claims. The value + // will be empty at time of writing because CAE is the only feature involving claims. If in + // the future some client needs to specify unrelated claims, this function may need to merge + // them with the challenge claims. + tro.Claims = caeChallenge.params["claims"] + return b.authenticateAndAuthorize(req)(tro) + } + if err = b.authzHandler.OnRequest(req, authNZ); err == nil { + if err = req.RewindBody(); err == nil { + res, err = req.Next() + } + } + case b.authzHandler.OnChallenge != nil && !recursed: + if err = b.authzHandler.OnChallenge(req, res, b.authenticateAndAuthorize(req)); err == nil { + if err = req.RewindBody(); err == nil { + if res, err = req.Next(); err == nil { + res, err = b.handleChallenge(req, res, true) + } + } + } else { + // don't retry challenge handling errors + err = errorinfo.NonRetriableError(err) + } + default: + // return the response to the pipeline + } + } + } + return res, err +} + +func checkHTTPSForAuth(req *policy.Request, allowHTTP bool) error { + if strings.ToLower(req.Raw().URL.Scheme) != "https" && !allowHTTP { + return errorinfo.NonRetriableError(errors.New("authenticated requests are not permitted for non TLS protected (https) endpoints")) + } + return nil +} + +// parseCAEChallenge returns a *authChallenge representing Response's CAE challenge (nil when Response has none). +// If Response includes a CAE challenge having invalid claims, it returns a NonRetriableError. +func parseCAEChallenge(res *http.Response) (*authChallenge, error) { + var ( + caeChallenge *authChallenge + err error + ) + for _, c := range parseChallenges(res) { + if c.scheme == "Bearer" { + if claims := c.params["claims"]; claims != "" && c.params["error"] == "insufficient_claims" { + if b, de := base64.StdEncoding.DecodeString(claims); de == nil { + c.params["claims"] = string(b) + caeChallenge = &c + } else { + // don't include the decoding error because it's something + // unhelpful like "illegal base64 data at input byte 42" + err = errorinfo.NonRetriableError(errors.New("authentication challenge contains invalid claims: " + claims)) + } + break + } + } + } + return caeChallenge, err +} + +var ( + challenge, challengeParams *regexp.Regexp + once = &sync.Once{} +) + +type authChallenge struct { + scheme string + params map[string]string +} + +// parseChallenges assumes authentication challenges have quoted parameter values +func parseChallenges(res *http.Response) []authChallenge { + once.Do(func() { + // matches challenges having quoted parameters, capturing scheme and parameters + challenge = regexp.MustCompile(`(?:(\w+) ((?:\w+="[^"]*",?\s*)+))`) + // captures parameter names and values in a match of the above expression + challengeParams = regexp.MustCompile(`(\w+)="([^"]*)"`) + }) + parsed := []authChallenge{} + // WWW-Authenticate can have multiple values, each containing multiple challenges + for _, h := range res.Header.Values(shared.HeaderWWWAuthenticate) { + for _, sm := range challenge.FindAllStringSubmatch(h, -1) { + // sm is [challenge, scheme, params] (see regexp documentation on submatches) + c := authChallenge{ + params: make(map[string]string), + scheme: sm[1], + } + for _, sm := range challengeParams.FindAllStringSubmatch(sm[2], -1) { + // sm is [key="value", key, value] (see regexp documentation on submatches) + c.params[sm[1]] = sm[2] + } + parsed = append(parsed, c) + } + } + return parsed +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_body_download.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_body_download.go new file mode 100644 index 000000000..99dc029f0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_body_download.go @@ -0,0 +1,72 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "fmt" + "net/http" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo" +) + +// bodyDownloadPolicy creates a policy object that downloads the response's body to a []byte. +func bodyDownloadPolicy(req *policy.Request) (*http.Response, error) { + resp, err := req.Next() + if err != nil { + return resp, err + } + var opValues bodyDownloadPolicyOpValues + // don't skip downloading error response bodies + if req.OperationValue(&opValues); opValues.Skip && resp.StatusCode < 400 { + return resp, err + } + // Either bodyDownloadPolicyOpValues was not specified (so skip is false) + // or it was specified and skip is false: don't skip downloading the body + _, err = Payload(resp) + if err != nil { + return resp, newBodyDownloadError(err, req) + } + return resp, err +} + +// bodyDownloadPolicyOpValues is the struct containing the per-operation values +type bodyDownloadPolicyOpValues struct { + Skip bool +} + +type bodyDownloadError struct { + err error +} + +func newBodyDownloadError(err error, req *policy.Request) error { + // on failure, only retry the request for idempotent operations. + // we currently identify them as DELETE, GET, and PUT requests. + if m := strings.ToUpper(req.Raw().Method); m == http.MethodDelete || m == http.MethodGet || m == http.MethodPut { + // error is safe for retry + return err + } + // wrap error to avoid retries + return &bodyDownloadError{ + err: err, + } +} + +func (b *bodyDownloadError) Error() string { + return fmt.Sprintf("body download policy: %s", b.err.Error()) +} + +func (b *bodyDownloadError) NonRetriable() { + // marker method +} + +func (b *bodyDownloadError) Unwrap() error { + return b.err +} + +var _ errorinfo.NonRetriable = (*bodyDownloadError)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_header.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_header.go new file mode 100644 index 000000000..c230af0af --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_header.go @@ -0,0 +1,40 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// newHTTPHeaderPolicy creates a policy object that adds custom HTTP headers to a request +func httpHeaderPolicy(req *policy.Request) (*http.Response, error) { + // check if any custom HTTP headers have been specified + if header := req.Raw().Context().Value(shared.CtxWithHTTPHeaderKey{}); header != nil { + for k, v := range header.(http.Header) { + // use Set to replace any existing value + // it also canonicalizes the header key + req.Raw().Header.Set(k, v[0]) + // add any remaining values + for i := 1; i < len(v); i++ { + req.Raw().Header.Add(k, v[i]) + } + } + } + return req.Next() +} + +// WithHTTPHeader adds the specified http.Header to the parent context. +// Use this to specify custom HTTP headers at the API-call level. +// Any overlapping headers will have their values replaced with the values specified here. +// Deprecated: use [policy.WithHTTPHeader] instead. +func WithHTTPHeader(parent context.Context, header http.Header) context.Context { + return policy.WithHTTPHeader(parent, header) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_trace.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_trace.go new file mode 100644 index 000000000..f375195c4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_http_trace.go @@ -0,0 +1,154 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" +) + +const ( + attrHTTPMethod = "http.method" + attrHTTPURL = "http.url" + attrHTTPUserAgent = "http.user_agent" + attrHTTPStatusCode = "http.status_code" + + attrAZClientReqID = "az.client_request_id" + attrAZServiceReqID = "az.service_request_id" + + attrNetPeerName = "net.peer.name" +) + +// newHTTPTracePolicy creates a new instance of the httpTracePolicy. +// - allowedQueryParams contains the user-specified query parameters that don't need to be redacted from the trace +func newHTTPTracePolicy(allowedQueryParams []string) exported.Policy { + return &httpTracePolicy{allowedQP: getAllowedQueryParams(allowedQueryParams)} +} + +// httpTracePolicy is a policy that creates a trace for the HTTP request and its response +type httpTracePolicy struct { + allowedQP map[string]struct{} +} + +// Do implements the pipeline.Policy interfaces for the httpTracePolicy type. +func (h *httpTracePolicy) Do(req *policy.Request) (resp *http.Response, err error) { + rawTracer := req.Raw().Context().Value(shared.CtxWithTracingTracer{}) + if tracer, ok := rawTracer.(tracing.Tracer); ok && tracer.Enabled() { + attributes := []tracing.Attribute{ + {Key: attrHTTPMethod, Value: req.Raw().Method}, + {Key: attrHTTPURL, Value: getSanitizedURL(*req.Raw().URL, h.allowedQP)}, + {Key: attrNetPeerName, Value: req.Raw().URL.Host}, + } + + if ua := req.Raw().Header.Get(shared.HeaderUserAgent); ua != "" { + attributes = append(attributes, tracing.Attribute{Key: attrHTTPUserAgent, Value: ua}) + } + if reqID := req.Raw().Header.Get(shared.HeaderXMSClientRequestID); reqID != "" { + attributes = append(attributes, tracing.Attribute{Key: attrAZClientReqID, Value: reqID}) + } + + ctx := req.Raw().Context() + ctx, span := tracer.Start(ctx, "HTTP "+req.Raw().Method, &tracing.SpanOptions{ + Kind: tracing.SpanKindClient, + Attributes: attributes, + }) + + defer func() { + if resp != nil { + span.SetAttributes(tracing.Attribute{Key: attrHTTPStatusCode, Value: resp.StatusCode}) + if resp.StatusCode > 399 { + span.SetStatus(tracing.SpanStatusError, resp.Status) + } + if reqID := resp.Header.Get(shared.HeaderXMSRequestID); reqID != "" { + span.SetAttributes(tracing.Attribute{Key: attrAZServiceReqID, Value: reqID}) + } + } else if err != nil { + var urlErr *url.Error + if errors.As(err, &urlErr) { + // calling *url.Error.Error() will include the unsanitized URL + // which we don't want. in addition, we already have the HTTP verb + // and sanitized URL in the trace so we aren't losing any info + err = urlErr.Err + } + span.SetStatus(tracing.SpanStatusError, err.Error()) + } + span.End() + }() + + req = req.WithContext(ctx) + } + resp, err = req.Next() + return +} + +// StartSpanOptions contains the optional values for StartSpan. +type StartSpanOptions struct { + // Kind indicates the kind of Span. + Kind tracing.SpanKind + // Attributes contains key-value pairs of attributes for the span. + Attributes []tracing.Attribute +} + +// StartSpan starts a new tracing span. +// You must call the returned func to terminate the span. Pass the applicable error +// if the span will exit with an error condition. +// - ctx is the parent context of the newly created context +// - name is the name of the span. this is typically the fully qualified name of an API ("Client.Method") +// - tracer is the client's Tracer for creating spans +// - options contains optional values. pass nil to accept any default values +func StartSpan(ctx context.Context, name string, tracer tracing.Tracer, options *StartSpanOptions) (context.Context, func(error)) { + if !tracer.Enabled() { + return ctx, func(err error) {} + } + + // we MUST propagate the active tracer before returning so that the trace policy can access it + ctx = context.WithValue(ctx, shared.CtxWithTracingTracer{}, tracer) + + if activeSpan := ctx.Value(ctxActiveSpan{}); activeSpan != nil { + // per the design guidelines, if a SDK method Foo() calls SDK method Bar(), + // then the span for Bar() must be suppressed. however, if Bar() makes a REST + // call, then Bar's HTTP span must be a child of Foo's span. + // however, there is an exception to this rule. if the SDK method Foo() is a + // messaging producer/consumer, and it takes a callback that's a SDK method + // Bar(), then the span for Bar() must _not_ be suppressed. + if kind := activeSpan.(tracing.SpanKind); kind == tracing.SpanKindClient || kind == tracing.SpanKindInternal { + return ctx, func(err error) {} + } + } + + if options == nil { + options = &StartSpanOptions{} + } + if options.Kind == 0 { + options.Kind = tracing.SpanKindInternal + } + + ctx, span := tracer.Start(ctx, name, &tracing.SpanOptions{ + Kind: options.Kind, + Attributes: options.Attributes, + }) + ctx = context.WithValue(ctx, ctxActiveSpan{}, options.Kind) + return ctx, func(err error) { + if err != nil { + errType := strings.Replace(fmt.Sprintf("%T", err), "*exported.", "*azcore.", 1) + span.SetStatus(tracing.SpanStatusError, fmt.Sprintf("%s:\n%s", errType, err.Error())) + } + span.End() + } +} + +// ctxActiveSpan is used as a context key for indicating a SDK client span is in progress. +type ctxActiveSpan struct{} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_include_response.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_include_response.go new file mode 100644 index 000000000..bb00f6c2f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_include_response.go @@ -0,0 +1,35 @@ +//go:build go1.16 +// +build go1.16 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// includeResponsePolicy creates a policy that retrieves the raw HTTP response upon request +func includeResponsePolicy(req *policy.Request) (*http.Response, error) { + resp, err := req.Next() + if resp == nil { + return resp, err + } + if httpOutRaw := req.Raw().Context().Value(shared.CtxWithCaptureResponse{}); httpOutRaw != nil { + httpOut := httpOutRaw.(**http.Response) + *httpOut = resp + } + return resp, err +} + +// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context. +// The resp parameter will contain the HTTP response after the request has completed. +// Deprecated: use [policy.WithCaptureResponse] instead. +func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context { + return policy.WithCaptureResponse(parent, resp) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_key_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_key_credential.go new file mode 100644 index 000000000..eeb1c09cc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_key_credential.go @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// KeyCredentialPolicy authorizes requests with a [azcore.KeyCredential]. +type KeyCredentialPolicy struct { + cred *exported.KeyCredential + header string + prefix string + allowHTTP bool +} + +// KeyCredentialPolicyOptions contains the optional values configuring [KeyCredentialPolicy]. +type KeyCredentialPolicyOptions struct { + // InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP. + // By default, authenticated requests to an HTTP endpoint are rejected by the client. + // WARNING: setting this to true will allow sending the authentication key in clear text. Use with caution. + InsecureAllowCredentialWithHTTP bool + + // Prefix is used if the key requires a prefix before it's inserted into the HTTP request. + Prefix string +} + +// NewKeyCredentialPolicy creates a new instance of [KeyCredentialPolicy]. +// - cred is the [azcore.KeyCredential] used to authenticate with the service +// - header is the name of the HTTP request header in which the key is placed +// - options contains optional configuration, pass nil to accept the default values +func NewKeyCredentialPolicy(cred *exported.KeyCredential, header string, options *KeyCredentialPolicyOptions) *KeyCredentialPolicy { + if options == nil { + options = &KeyCredentialPolicyOptions{} + } + return &KeyCredentialPolicy{ + cred: cred, + header: header, + prefix: options.Prefix, + allowHTTP: options.InsecureAllowCredentialWithHTTP, + } +} + +// Do implementes the Do method on the [policy.Polilcy] interface. +func (k *KeyCredentialPolicy) Do(req *policy.Request) (*http.Response, error) { + // skip adding the authorization header if no KeyCredential was provided. + // this prevents a panic that might be hard to diagnose and allows testing + // against http endpoints that don't require authentication. + if k.cred != nil { + if err := checkHTTPSForAuth(req, k.allowHTTP); err != nil { + return nil, err + } + val := exported.KeyCredentialGet(k.cred) + if k.prefix != "" { + val = k.prefix + val + } + req.Raw().Header.Add(k.header, val) + } + return req.Next() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_logging.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_logging.go new file mode 100644 index 000000000..f048d7fb5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_logging.go @@ -0,0 +1,264 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/url" + "sort" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/diag" +) + +type logPolicy struct { + includeBody bool + allowedHeaders map[string]struct{} + allowedQP map[string]struct{} +} + +// NewLogPolicy creates a request/response logging policy object configured using the specified options. +// Pass nil to accept the default values; this is the same as passing a zero-value options. +func NewLogPolicy(o *policy.LogOptions) policy.Policy { + if o == nil { + o = &policy.LogOptions{} + } + // construct default hash set of allowed headers + allowedHeaders := map[string]struct{}{ + "accept": {}, + "cache-control": {}, + "connection": {}, + "content-length": {}, + "content-type": {}, + "date": {}, + "etag": {}, + "expires": {}, + "if-match": {}, + "if-modified-since": {}, + "if-none-match": {}, + "if-unmodified-since": {}, + "last-modified": {}, + "ms-cv": {}, + "pragma": {}, + "request-id": {}, + "retry-after": {}, + "server": {}, + "traceparent": {}, + "transfer-encoding": {}, + "user-agent": {}, + "www-authenticate": {}, + "x-ms-request-id": {}, + "x-ms-client-request-id": {}, + "x-ms-return-client-request-id": {}, + } + // add any caller-specified allowed headers to the set + for _, ah := range o.AllowedHeaders { + allowedHeaders[strings.ToLower(ah)] = struct{}{} + } + // now do the same thing for query params + allowedQP := getAllowedQueryParams(o.AllowedQueryParams) + return &logPolicy{ + includeBody: o.IncludeBody, + allowedHeaders: allowedHeaders, + allowedQP: allowedQP, + } +} + +// getAllowedQueryParams merges the default set of allowed query parameters +// with a custom set (usually comes from client options). +func getAllowedQueryParams(customAllowedQP []string) map[string]struct{} { + allowedQP := map[string]struct{}{ + "api-version": {}, + } + for _, qp := range customAllowedQP { + allowedQP[strings.ToLower(qp)] = struct{}{} + } + return allowedQP +} + +// logPolicyOpValues is the struct containing the per-operation values +type logPolicyOpValues struct { + try int32 + start time.Time +} + +func (p *logPolicy) Do(req *policy.Request) (*http.Response, error) { + // Get the per-operation values. These are saved in the Message's map so that they persist across each retry calling into this policy object. + var opValues logPolicyOpValues + if req.OperationValue(&opValues); opValues.start.IsZero() { + opValues.start = time.Now() // If this is the 1st try, record this operation's start time + } + opValues.try++ // The first try is #1 (not #0) + req.SetOperationValue(opValues) + + // Log the outgoing request as informational + if log.Should(log.EventRequest) { + b := &bytes.Buffer{} + fmt.Fprintf(b, "==> OUTGOING REQUEST (Try=%d)\n", opValues.try) + p.writeRequestWithResponse(b, req, nil, nil) + var err error + if p.includeBody { + err = writeReqBody(req, b) + } + log.Write(log.EventRequest, b.String()) + if err != nil { + return nil, err + } + } + + // Set the time for this particular retry operation and then Do the operation. + tryStart := time.Now() + response, err := req.Next() // Make the request + tryEnd := time.Now() + tryDuration := tryEnd.Sub(tryStart) + opDuration := tryEnd.Sub(opValues.start) + + if log.Should(log.EventResponse) { + // We're going to log this; build the string to log + b := &bytes.Buffer{} + fmt.Fprintf(b, "==> REQUEST/RESPONSE (Try=%d/%v, OpTime=%v) -- ", opValues.try, tryDuration, opDuration) + if err != nil { // This HTTP request did not get a response from the service + fmt.Fprint(b, "REQUEST ERROR\n") + } else { + fmt.Fprint(b, "RESPONSE RECEIVED\n") + } + + p.writeRequestWithResponse(b, req, response, err) + if err != nil { + // skip frames runtime.Callers() and runtime.StackTrace() + b.WriteString(diag.StackTrace(2, 32)) + } else if p.includeBody { + err = writeRespBody(response, b) + } + log.Write(log.EventResponse, b.String()) + } + return response, err +} + +const redactedValue = "REDACTED" + +// getSanitizedURL returns a sanitized string for the provided url.URL +func getSanitizedURL(u url.URL, allowedQueryParams map[string]struct{}) string { + // redact applicable query params + qp := u.Query() + for k := range qp { + if _, ok := allowedQueryParams[strings.ToLower(k)]; !ok { + qp.Set(k, redactedValue) + } + } + u.RawQuery = qp.Encode() + return u.String() +} + +// writeRequestWithResponse appends a formatted HTTP request into a Buffer. If request and/or err are +// not nil, then these are also written into the Buffer. +func (p *logPolicy) writeRequestWithResponse(b *bytes.Buffer, req *policy.Request, resp *http.Response, err error) { + // Write the request into the buffer. + fmt.Fprint(b, " "+req.Raw().Method+" "+getSanitizedURL(*req.Raw().URL, p.allowedQP)+"\n") + p.writeHeader(b, req.Raw().Header) + if resp != nil { + fmt.Fprintln(b, " --------------------------------------------------------------------------------") + fmt.Fprint(b, " RESPONSE Status: "+resp.Status+"\n") + p.writeHeader(b, resp.Header) + } + if err != nil { + fmt.Fprintln(b, " --------------------------------------------------------------------------------") + fmt.Fprint(b, " ERROR:\n"+err.Error()+"\n") + } +} + +// formatHeaders appends an HTTP request's or response's header into a Buffer. +func (p *logPolicy) writeHeader(b *bytes.Buffer, header http.Header) { + if len(header) == 0 { + b.WriteString(" (no headers)\n") + return + } + keys := make([]string, 0, len(header)) + // Alphabetize the headers + for k := range header { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + // don't use Get() as it will canonicalize k which might cause a mismatch + value := header[k][0] + // redact all header values not in the allow-list + if _, ok := p.allowedHeaders[strings.ToLower(k)]; !ok { + value = redactedValue + } + fmt.Fprintf(b, " %s: %+v\n", k, value) + } +} + +// returns true if the request/response body should be logged. +// this is determined by looking at the content-type header value. +func shouldLogBody(b *bytes.Buffer, contentType string) bool { + contentType = strings.ToLower(contentType) + if strings.HasPrefix(contentType, "text") || + strings.Contains(contentType, "json") || + strings.Contains(contentType, "xml") { + return true + } + fmt.Fprintf(b, " Skip logging body for %s\n", contentType) + return false +} + +// writes to a buffer, used for logging purposes +func writeReqBody(req *policy.Request, b *bytes.Buffer) error { + if req.Raw().Body == nil { + fmt.Fprint(b, " Request contained no body\n") + return nil + } + if ct := req.Raw().Header.Get(shared.HeaderContentType); !shouldLogBody(b, ct) { + return nil + } + body, err := io.ReadAll(req.Raw().Body) + if err != nil { + fmt.Fprintf(b, " Failed to read request body: %s\n", err.Error()) + return err + } + if err := req.RewindBody(); err != nil { + return err + } + logBody(b, body) + return nil +} + +// writes to a buffer, used for logging purposes +func writeRespBody(resp *http.Response, b *bytes.Buffer) error { + ct := resp.Header.Get(shared.HeaderContentType) + if ct == "" { + fmt.Fprint(b, " Response contained no body\n") + return nil + } else if !shouldLogBody(b, ct) { + return nil + } + body, err := Payload(resp) + if err != nil { + fmt.Fprintf(b, " Failed to read response body: %s\n", err.Error()) + return err + } + if len(body) > 0 { + logBody(b, body) + } else { + fmt.Fprint(b, " Response contained no body\n") + } + return nil +} + +func logBody(b *bytes.Buffer, body []byte) { + fmt.Fprintln(b, " --------------------------------------------------------------------------------") + fmt.Fprintln(b, string(body)) + fmt.Fprintln(b, " --------------------------------------------------------------------------------") +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_request_id.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_request_id.go new file mode 100644 index 000000000..360a7f211 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_request_id.go @@ -0,0 +1,34 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" +) + +type requestIDPolicy struct{} + +// NewRequestIDPolicy returns a policy that add the x-ms-client-request-id header +func NewRequestIDPolicy() policy.Policy { + return &requestIDPolicy{} +} + +func (r *requestIDPolicy) Do(req *policy.Request) (*http.Response, error) { + if req.Raw().Header.Get(shared.HeaderXMSClientRequestID) == "" { + id, err := uuid.New() + if err != nil { + return nil, err + } + req.Raw().Header.Set(shared.HeaderXMSClientRequestID, id.String()) + } + + return req.Next() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_retry.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_retry.go new file mode 100644 index 000000000..4c3a31fea --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_retry.go @@ -0,0 +1,276 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "errors" + "io" + "math" + "math/rand" + "net/http" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo" + "github.com/Azure/azure-sdk-for-go/sdk/internal/exported" +) + +const ( + defaultMaxRetries = 3 +) + +func setDefaults(o *policy.RetryOptions) { + if o.MaxRetries == 0 { + o.MaxRetries = defaultMaxRetries + } else if o.MaxRetries < 0 { + o.MaxRetries = 0 + } + + // SDK guidelines specify the default MaxRetryDelay is 60 seconds + if o.MaxRetryDelay == 0 { + o.MaxRetryDelay = 60 * time.Second + } else if o.MaxRetryDelay < 0 { + // not really an unlimited cap, but sufficiently large enough to be considered as such + o.MaxRetryDelay = math.MaxInt64 + } + if o.RetryDelay == 0 { + o.RetryDelay = 800 * time.Millisecond + } else if o.RetryDelay < 0 { + o.RetryDelay = 0 + } + if o.StatusCodes == nil { + // NOTE: if you change this list, you MUST update the docs in policy/policy.go + o.StatusCodes = []int{ + http.StatusRequestTimeout, // 408 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + } + } +} + +func calcDelay(o policy.RetryOptions, try int32) time.Duration { // try is >=1; never 0 + // avoid overflow when shifting left + factor := time.Duration(math.MaxInt64) + if try < 63 { + factor = time.Duration(int64(1< float64(math.MaxInt64) { + // the jitter pushed us over MaxInt64, so just use MaxInt64 + delay = time.Duration(math.MaxInt64) + } else { + delay = time.Duration(delayFloat) + } + + if delay > o.MaxRetryDelay { // MaxRetryDelay is backfilled with non-negative value + delay = o.MaxRetryDelay + } + + return delay +} + +// NewRetryPolicy creates a policy object configured using the specified options. +// Pass nil to accept the default values; this is the same as passing a zero-value options. +func NewRetryPolicy(o *policy.RetryOptions) policy.Policy { + if o == nil { + o = &policy.RetryOptions{} + } + p := &retryPolicy{options: *o} + return p +} + +type retryPolicy struct { + options policy.RetryOptions +} + +func (p *retryPolicy) Do(req *policy.Request) (resp *http.Response, err error) { + options := p.options + // check if the retry options have been overridden for this call + if override := req.Raw().Context().Value(shared.CtxWithRetryOptionsKey{}); override != nil { + options = override.(policy.RetryOptions) + } + setDefaults(&options) + // Exponential retry algorithm: ((2 ^ attempt) - 1) * delay * random(0.8, 1.2) + // When to retry: connection failure or temporary/timeout. + var rwbody *retryableRequestBody + if req.Body() != nil { + // wrap the body so we control when it's actually closed. + // do this outside the for loop so defers don't accumulate. + rwbody = &retryableRequestBody{body: req.Body()} + defer rwbody.realClose() + } + try := int32(1) + for { + resp = nil // reset + // unfortunately we don't have access to the custom allow-list of query params, so we'll redact everything but the default allowed QPs + log.Writef(log.EventRetryPolicy, "=====> Try=%d for %s %s", try, req.Raw().Method, getSanitizedURL(*req.Raw().URL, getAllowedQueryParams(nil))) + + // For each try, seek to the beginning of the Body stream. We do this even for the 1st try because + // the stream may not be at offset 0 when we first get it and we want the same behavior for the + // 1st try as for additional tries. + err = req.RewindBody() + if err != nil { + return + } + // RewindBody() restores Raw().Body to its original state, so set our rewindable after + if rwbody != nil { + req.Raw().Body = rwbody + } + + if options.TryTimeout == 0 { + clone := req.Clone(req.Raw().Context()) + resp, err = clone.Next() + } else { + // Set the per-try time for this particular retry operation and then Do the operation. + tryCtx, tryCancel := context.WithTimeout(req.Raw().Context(), options.TryTimeout) + clone := req.Clone(tryCtx) + resp, err = clone.Next() // Make the request + // if the body was already downloaded or there was an error it's safe to cancel the context now + if err != nil { + tryCancel() + } else if exported.PayloadDownloaded(resp) { + tryCancel() + } else { + // must cancel the context after the body has been read and closed + resp.Body = &contextCancelReadCloser{cf: tryCancel, body: resp.Body} + } + } + if err == nil { + log.Writef(log.EventRetryPolicy, "response %d", resp.StatusCode) + } else { + log.Writef(log.EventRetryPolicy, "error %v", err) + } + + if ctxErr := req.Raw().Context().Err(); ctxErr != nil { + // don't retry if the parent context has been cancelled or its deadline exceeded + err = ctxErr + log.Writef(log.EventRetryPolicy, "abort due to %v", err) + return + } + + // check if the error is not retriable + var nre errorinfo.NonRetriable + if errors.As(err, &nre) { + // the error says it's not retriable so don't retry + log.Writef(log.EventRetryPolicy, "non-retriable error %T", nre) + return + } + + if options.ShouldRetry != nil { + // a non-nil ShouldRetry overrides our HTTP status code check + if !options.ShouldRetry(resp, err) { + // predicate says we shouldn't retry + log.Write(log.EventRetryPolicy, "exit due to ShouldRetry") + return + } + } else if err == nil && !HasStatusCode(resp, options.StatusCodes...) { + // if there is no error and the response code isn't in the list of retry codes then we're done. + log.Write(log.EventRetryPolicy, "exit due to non-retriable status code") + return + } + + if try == options.MaxRetries+1 { + // max number of tries has been reached, don't sleep again + log.Writef(log.EventRetryPolicy, "MaxRetries %d exceeded", options.MaxRetries) + return + } + + // use the delay from retry-after if available + delay := shared.RetryAfter(resp) + if delay <= 0 { + delay = calcDelay(options, try) + } else if delay > options.MaxRetryDelay { + // the retry-after delay exceeds the the cap so don't retry + log.Writef(log.EventRetryPolicy, "Retry-After delay %s exceeds MaxRetryDelay of %s", delay, options.MaxRetryDelay) + return + } + + // drain before retrying so nothing is leaked + Drain(resp) + + log.Writef(log.EventRetryPolicy, "End Try #%d, Delay=%v", try, delay) + select { + case <-time.After(delay): + try++ + case <-req.Raw().Context().Done(): + err = req.Raw().Context().Err() + log.Writef(log.EventRetryPolicy, "abort due to %v", err) + return + } + } +} + +// WithRetryOptions adds the specified RetryOptions to the parent context. +// Use this to specify custom RetryOptions at the API-call level. +// Deprecated: use [policy.WithRetryOptions] instead. +func WithRetryOptions(parent context.Context, options policy.RetryOptions) context.Context { + return policy.WithRetryOptions(parent, options) +} + +// ********** The following type/methods implement the retryableRequestBody (a ReadSeekCloser) + +// This struct is used when sending a body to the network +type retryableRequestBody struct { + body io.ReadSeeker // Seeking is required to support retries +} + +// Read reads a block of data from an inner stream and reports progress +func (b *retryableRequestBody) Read(p []byte) (n int, err error) { + return b.body.Read(p) +} + +func (b *retryableRequestBody) Seek(offset int64, whence int) (offsetFromStart int64, err error) { + return b.body.Seek(offset, whence) +} + +func (b *retryableRequestBody) Close() error { + // We don't want the underlying transport to close the request body on transient failures so this is a nop. + // The retry policy closes the request body upon success. + return nil +} + +func (b *retryableRequestBody) realClose() error { + if c, ok := b.body.(io.Closer); ok { + return c.Close() + } + return nil +} + +// ********** The following type/methods implement the contextCancelReadCloser + +// contextCancelReadCloser combines an io.ReadCloser with a cancel func. +// it ensures the cancel func is invoked once the body has been read and closed. +type contextCancelReadCloser struct { + cf context.CancelFunc + body io.ReadCloser +} + +func (rc *contextCancelReadCloser) Read(p []byte) (n int, err error) { + return rc.body.Read(p) +} + +func (rc *contextCancelReadCloser) Close() error { + err := rc.body.Close() + rc.cf() + return err +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_sas_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_sas_credential.go new file mode 100644 index 000000000..3964beea8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_sas_credential.go @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// SASCredentialPolicy authorizes requests with a [azcore.SASCredential]. +type SASCredentialPolicy struct { + cred *exported.SASCredential + header string + allowHTTP bool +} + +// SASCredentialPolicyOptions contains the optional values configuring [SASCredentialPolicy]. +type SASCredentialPolicyOptions struct { + // InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP. + // By default, authenticated requests to an HTTP endpoint are rejected by the client. + // WARNING: setting this to true will allow sending the authentication key in clear text. Use with caution. + InsecureAllowCredentialWithHTTP bool +} + +// NewSASCredentialPolicy creates a new instance of [SASCredentialPolicy]. +// - cred is the [azcore.SASCredential] used to authenticate with the service +// - header is the name of the HTTP request header in which the shared access signature is placed +// - options contains optional configuration, pass nil to accept the default values +func NewSASCredentialPolicy(cred *exported.SASCredential, header string, options *SASCredentialPolicyOptions) *SASCredentialPolicy { + if options == nil { + options = &SASCredentialPolicyOptions{} + } + return &SASCredentialPolicy{ + cred: cred, + header: header, + allowHTTP: options.InsecureAllowCredentialWithHTTP, + } +} + +// Do implementes the Do method on the [policy.Polilcy] interface. +func (k *SASCredentialPolicy) Do(req *policy.Request) (*http.Response, error) { + // skip adding the authorization header if no SASCredential was provided. + // this prevents a panic that might be hard to diagnose and allows testing + // against http endpoints that don't require authentication. + if k.cred != nil { + if err := checkHTTPSForAuth(req, k.allowHTTP); err != nil { + return nil, err + } + req.Raw().Header.Add(k.header, exported.SASCredentialGet(k.cred)) + } + return req.Next() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_telemetry.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_telemetry.go new file mode 100644 index 000000000..80a903546 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_telemetry.go @@ -0,0 +1,83 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "bytes" + "fmt" + "net/http" + "os" + "runtime" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +type telemetryPolicy struct { + telemetryValue string +} + +// NewTelemetryPolicy creates a telemetry policy object that adds telemetry information to outgoing HTTP requests. +// The format is [ ]azsdk-go-/ . +// Pass nil to accept the default values; this is the same as passing a zero-value options. +func NewTelemetryPolicy(mod, ver string, o *policy.TelemetryOptions) policy.Policy { + if o == nil { + o = &policy.TelemetryOptions{} + } + tp := telemetryPolicy{} + if o.Disabled { + return &tp + } + b := &bytes.Buffer{} + // normalize ApplicationID + if o.ApplicationID != "" { + o.ApplicationID = strings.ReplaceAll(o.ApplicationID, " ", "/") + if len(o.ApplicationID) > 24 { + o.ApplicationID = o.ApplicationID[:24] + } + b.WriteString(o.ApplicationID) + b.WriteRune(' ') + } + // mod might be the fully qualified name. in that case, we just want the package name + if i := strings.LastIndex(mod, "/"); i > -1 { + mod = mod[i+1:] + } + b.WriteString(formatTelemetry(mod, ver)) + b.WriteRune(' ') + b.WriteString(platformInfo) + tp.telemetryValue = b.String() + return &tp +} + +func formatTelemetry(comp, ver string) string { + return fmt.Sprintf("azsdk-go-%s/%s", comp, ver) +} + +func (p telemetryPolicy) Do(req *policy.Request) (*http.Response, error) { + if p.telemetryValue == "" { + return req.Next() + } + // preserve the existing User-Agent string + if ua := req.Raw().Header.Get(shared.HeaderUserAgent); ua != "" { + p.telemetryValue = fmt.Sprintf("%s %s", p.telemetryValue, ua) + } + req.Raw().Header.Set(shared.HeaderUserAgent, p.telemetryValue) + return req.Next() +} + +// NOTE: the ONLY function that should write to this variable is this func +var platformInfo = func() string { + operatingSystem := runtime.GOOS // Default OS string + switch operatingSystem { + case "windows": + operatingSystem = os.Getenv("OS") // Get more specific OS information + case "linux": // accept default OS info + case "freebsd": // accept default OS info + } + return fmt.Sprintf("(%s; %s)", runtime.Version(), operatingSystem) +}() diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go new file mode 100644 index 000000000..a89ae9b7b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/poller.go @@ -0,0 +1,396 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "encoding/json" + "errors" + "flag" + "fmt" + "net/http" + "reflect" + "strings" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/fake" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing" + "github.com/Azure/azure-sdk-for-go/sdk/internal/poller" +) + +// FinalStateVia is the enumerated type for the possible final-state-via values. +type FinalStateVia = pollers.FinalStateVia + +const ( + // FinalStateViaAzureAsyncOp indicates the final payload comes from the Azure-AsyncOperation URL. + FinalStateViaAzureAsyncOp = pollers.FinalStateViaAzureAsyncOp + + // FinalStateViaLocation indicates the final payload comes from the Location URL. + FinalStateViaLocation = pollers.FinalStateViaLocation + + // FinalStateViaOriginalURI indicates the final payload comes from the original URL. + FinalStateViaOriginalURI = pollers.FinalStateViaOriginalURI + + // FinalStateViaOpLocation indicates the final payload comes from the Operation-Location URL. + FinalStateViaOpLocation = pollers.FinalStateViaOpLocation +) + +// NewPollerOptions contains the optional parameters for NewPoller. +type NewPollerOptions[T any] struct { + // FinalStateVia contains the final-state-via value for the LRO. + // NOTE: used only for Azure-AsyncOperation and Operation-Location LROs. + FinalStateVia FinalStateVia + + // OperationLocationResultPath contains the JSON path to the result's + // payload when it's included with the terminal success response. + // NOTE: only used for Operation-Location LROs. + OperationLocationResultPath string + + // Response contains a preconstructed response type. + // The final payload will be unmarshaled into it and returned. + Response *T + + // Handler[T] contains a custom polling implementation. + Handler PollingHandler[T] + + // Tracer contains the Tracer from the client that's creating the Poller. + Tracer tracing.Tracer +} + +// NewPoller creates a Poller based on the provided initial response. +func NewPoller[T any](resp *http.Response, pl exported.Pipeline, options *NewPollerOptions[T]) (*Poller[T], error) { + if options == nil { + options = &NewPollerOptions[T]{} + } + result := options.Response + if result == nil { + result = new(T) + } + if options.Handler != nil { + return &Poller[T]{ + op: options.Handler, + resp: resp, + result: result, + tracer: options.Tracer, + }, nil + } + + defer resp.Body.Close() + // this is a back-stop in case the swagger is incorrect (i.e. missing one or more status codes for success). + // ideally the codegen should return an error if the initial response failed and not even create a poller. + if !poller.StatusCodeValid(resp) { + return nil, exported.NewResponseError(resp) + } + + // determine the polling method + var opr PollingHandler[T] + var err error + if fake.Applicable(resp) { + opr, err = fake.New[T](pl, resp) + } else if async.Applicable(resp) { + // async poller must be checked first as it can also have a location header + opr, err = async.New[T](pl, resp, options.FinalStateVia) + } else if op.Applicable(resp) { + // op poller must be checked before loc as it can also have a location header + opr, err = op.New[T](pl, resp, options.FinalStateVia, options.OperationLocationResultPath) + } else if loc.Applicable(resp) { + opr, err = loc.New[T](pl, resp) + } else if body.Applicable(resp) { + // must test body poller last as it's a subset of the other pollers. + // TODO: this is ambiguous for PATCH/PUT if it returns a 200 with no polling headers (sync completion) + opr, err = body.New[T](pl, resp) + } else if m := resp.Request.Method; resp.StatusCode == http.StatusAccepted && (m == http.MethodDelete || m == http.MethodPost) { + // if we get here it means we have a 202 with no polling headers. + // for DELETE and POST this is a hard error per ARM RPC spec. + return nil, errors.New("response is missing polling URL") + } else { + opr, err = pollers.NewNopPoller[T](resp) + } + + if err != nil { + return nil, err + } + return &Poller[T]{ + op: opr, + resp: resp, + result: result, + tracer: options.Tracer, + }, nil +} + +// NewPollerFromResumeTokenOptions contains the optional parameters for NewPollerFromResumeToken. +type NewPollerFromResumeTokenOptions[T any] struct { + // Response contains a preconstructed response type. + // The final payload will be unmarshaled into it and returned. + Response *T + + // Handler[T] contains a custom polling implementation. + Handler PollingHandler[T] + + // Tracer contains the Tracer from the client that's creating the Poller. + Tracer tracing.Tracer +} + +// NewPollerFromResumeToken creates a Poller from a resume token string. +func NewPollerFromResumeToken[T any](token string, pl exported.Pipeline, options *NewPollerFromResumeTokenOptions[T]) (*Poller[T], error) { + if options == nil { + options = &NewPollerFromResumeTokenOptions[T]{} + } + result := options.Response + if result == nil { + result = new(T) + } + + if err := pollers.IsTokenValid[T](token); err != nil { + return nil, err + } + raw, err := pollers.ExtractToken(token) + if err != nil { + return nil, err + } + var asJSON map[string]any + if err := json.Unmarshal(raw, &asJSON); err != nil { + return nil, err + } + + opr := options.Handler + // now rehydrate the poller based on the encoded poller type + if fake.CanResume(asJSON) { + opr, _ = fake.New[T](pl, nil) + } else if opr != nil { + log.Writef(log.EventLRO, "Resuming custom poller %T.", opr) + } else if async.CanResume(asJSON) { + opr, _ = async.New[T](pl, nil, "") + } else if body.CanResume(asJSON) { + opr, _ = body.New[T](pl, nil) + } else if loc.CanResume(asJSON) { + opr, _ = loc.New[T](pl, nil) + } else if op.CanResume(asJSON) { + opr, _ = op.New[T](pl, nil, "", "") + } else { + return nil, fmt.Errorf("unhandled poller token %s", string(raw)) + } + if err := json.Unmarshal(raw, &opr); err != nil { + return nil, err + } + return &Poller[T]{ + op: opr, + result: result, + tracer: options.Tracer, + }, nil +} + +// PollingHandler[T] abstracts the differences among poller implementations. +type PollingHandler[T any] interface { + // Done returns true if the LRO has reached a terminal state. + Done() bool + + // Poll fetches the latest state of the LRO. + Poll(context.Context) (*http.Response, error) + + // Result is called once the LRO has reached a terminal state. It populates the out parameter + // with the result of the operation. + Result(ctx context.Context, out *T) error +} + +// Poller encapsulates a long-running operation, providing polling facilities until the operation reaches a terminal state. +// Methods on this type are not safe for concurrent use. +type Poller[T any] struct { + op PollingHandler[T] + resp *http.Response + err error + result *T + tracer tracing.Tracer + done bool +} + +// PollUntilDoneOptions contains the optional values for the Poller[T].PollUntilDone() method. +type PollUntilDoneOptions struct { + // Frequency is the time to wait between polling intervals in absence of a Retry-After header. Allowed minimum is one second. + // Pass zero to accept the default value (30s). + Frequency time.Duration +} + +// PollUntilDone will poll the service endpoint until a terminal state is reached, an error is received, or the context expires. +// It internally uses Poll(), Done(), and Result() in its polling loop, sleeping for the specified duration between intervals. +// options: pass nil to accept the default values. +// NOTE: the default polling frequency is 30 seconds which works well for most operations. However, some operations might +// benefit from a shorter or longer duration. +func (p *Poller[T]) PollUntilDone(ctx context.Context, options *PollUntilDoneOptions) (res T, err error) { + if options == nil { + options = &PollUntilDoneOptions{} + } + cp := *options + if cp.Frequency == 0 { + cp.Frequency = 30 * time.Second + } + + ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.PollUntilDone", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil) + defer func() { endSpan(err) }() + + // skip the floor check when executing tests so they don't take so long + if isTest := flag.Lookup("test.v"); isTest == nil && cp.Frequency < time.Second { + err = errors.New("polling frequency minimum is one second") + return + } + + start := time.Now() + logPollUntilDoneExit := func(v any) { + log.Writef(log.EventLRO, "END PollUntilDone() for %T: %v, total time: %s", p.op, v, time.Since(start)) + } + log.Writef(log.EventLRO, "BEGIN PollUntilDone() for %T", p.op) + if p.resp != nil { + // initial check for a retry-after header existing on the initial response + if retryAfter := shared.RetryAfter(p.resp); retryAfter > 0 { + log.Writef(log.EventLRO, "initial Retry-After delay for %s", retryAfter.String()) + if err = shared.Delay(ctx, retryAfter); err != nil { + logPollUntilDoneExit(err) + return + } + } + } + // begin polling the endpoint until a terminal state is reached + for { + var resp *http.Response + resp, err = p.Poll(ctx) + if err != nil { + logPollUntilDoneExit(err) + return + } + if p.Done() { + logPollUntilDoneExit("succeeded") + res, err = p.Result(ctx) + return + } + d := cp.Frequency + if retryAfter := shared.RetryAfter(resp); retryAfter > 0 { + log.Writef(log.EventLRO, "Retry-After delay for %s", retryAfter.String()) + d = retryAfter + } else { + log.Writef(log.EventLRO, "delay for %s", d.String()) + } + if err = shared.Delay(ctx, d); err != nil { + logPollUntilDoneExit(err) + return + } + } +} + +// Poll fetches the latest state of the LRO. It returns an HTTP response or error. +// If Poll succeeds, the poller's state is updated and the HTTP response is returned. +// If Poll fails, the poller's state is unmodified and the error is returned. +// Calling Poll on an LRO that has reached a terminal state will return the last HTTP response. +func (p *Poller[T]) Poll(ctx context.Context) (resp *http.Response, err error) { + if p.Done() { + // the LRO has reached a terminal state, don't poll again + resp = p.resp + return + } + + ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.Poll", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil) + defer func() { endSpan(err) }() + + resp, err = p.op.Poll(ctx) + if err != nil { + return + } + p.resp = resp + return +} + +// Done returns true if the LRO has reached a terminal state. +// Once a terminal state is reached, call Result(). +func (p *Poller[T]) Done() bool { + return p.op.Done() +} + +// Result returns the result of the LRO and is meant to be used in conjunction with Poll and Done. +// If the LRO completed successfully, a populated instance of T is returned. +// If the LRO failed or was canceled, an *azcore.ResponseError error is returned. +// Calling this on an LRO in a non-terminal state will return an error. +func (p *Poller[T]) Result(ctx context.Context) (res T, err error) { + if !p.Done() { + err = errors.New("poller is in a non-terminal state") + return + } + if p.done { + // the result has already been retrieved, return the cached value + if p.err != nil { + err = p.err + return + } + res = *p.result + return + } + + ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.Result", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil) + defer func() { endSpan(err) }() + + err = p.op.Result(ctx, p.result) + var respErr *exported.ResponseError + if errors.As(err, &respErr) { + if pollers.IsNonTerminalHTTPStatusCode(respErr.RawResponse) { + // the request failed in a non-terminal way. + // don't cache the error or mark the Poller as done + return + } + // the LRO failed. record the error + p.err = err + } else if err != nil { + // the call to Result failed, don't cache anything in this case + return + } + p.done = true + if p.err != nil { + err = p.err + return + } + res = *p.result + return +} + +// ResumeToken returns a value representing the poller that can be used to resume +// the LRO at a later time. ResumeTokens are unique per service operation. +// The token's format should be considered opaque and is subject to change. +// Calling this on an LRO in a terminal state will return an error. +func (p *Poller[T]) ResumeToken() (string, error) { + if p.Done() { + return "", errors.New("poller is in a terminal state") + } + tk, err := pollers.NewResumeToken[T](p.op) + if err != nil { + return "", err + } + return tk, err +} + +// extracts the type name from the string returned from reflect.Value.Name() +func shortenTypeName(s string) string { + // the value is formatted as follows + // Poller[module/Package.Type].Method + // we want to shorten the generic type parameter string to Type + // anything we don't recognize will be left as-is + begin := strings.Index(s, "[") + end := strings.Index(s, "]") + if begin == -1 || end == -1 { + return s + } + + typeName := s[begin+1 : end] + if i := strings.LastIndex(typeName, "."); i > -1 { + typeName = typeName[i+1:] + } + return s[:begin+1] + typeName + s[end:] +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/request.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/request.go new file mode 100644 index 000000000..7d34b7803 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/request.go @@ -0,0 +1,281 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/textproto" + "net/url" + "path" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming" + "github.com/Azure/azure-sdk-for-go/sdk/internal/uuid" +) + +// Base64Encoding is usesd to specify which base-64 encoder/decoder to use when +// encoding/decoding a slice of bytes to/from a string. +type Base64Encoding = exported.Base64Encoding + +const ( + // Base64StdFormat uses base64.StdEncoding for encoding and decoding payloads. + Base64StdFormat Base64Encoding = exported.Base64StdFormat + + // Base64URLFormat uses base64.RawURLEncoding for encoding and decoding payloads. + Base64URLFormat Base64Encoding = exported.Base64URLFormat +) + +// NewRequest creates a new policy.Request with the specified input. +// The endpoint MUST be properly encoded before calling this function. +func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*policy.Request, error) { + return exported.NewRequest(ctx, httpMethod, endpoint) +} + +// NewRequestFromRequest creates a new policy.Request with an existing *http.Request +func NewRequestFromRequest(req *http.Request) (*policy.Request, error) { + return exported.NewRequestFromRequest(req) +} + +// EncodeQueryParams will parse and encode any query parameters in the specified URL. +// Any semicolons will automatically be escaped. +func EncodeQueryParams(u string) (string, error) { + before, after, found := strings.Cut(u, "?") + if !found { + return u, nil + } + // starting in Go 1.17, url.ParseQuery will reject semicolons in query params. + // so, we must escape them first. note that this assumes that semicolons aren't + // being used as query param separators which is per the current RFC. + // for more info: + // https://github.com/golang/go/issues/25192 + // https://github.com/golang/go/issues/50034 + qp, err := url.ParseQuery(strings.ReplaceAll(after, ";", "%3B")) + if err != nil { + return "", err + } + return before + "?" + qp.Encode(), nil +} + +// JoinPaths concatenates multiple URL path segments into one path, +// inserting path separation characters as required. JoinPaths will preserve +// query parameters in the root path +func JoinPaths(root string, paths ...string) string { + if len(paths) == 0 { + return root + } + + qps := "" + if strings.Contains(root, "?") { + splitPath := strings.Split(root, "?") + root, qps = splitPath[0], splitPath[1] + } + + p := path.Join(paths...) + // path.Join will remove any trailing slashes. + // if one was provided, preserve it. + if strings.HasSuffix(paths[len(paths)-1], "/") && !strings.HasSuffix(p, "/") { + p += "/" + } + + if qps != "" { + p = p + "?" + qps + } + + if strings.HasSuffix(root, "/") && strings.HasPrefix(p, "/") { + root = root[:len(root)-1] + } else if !strings.HasSuffix(root, "/") && !strings.HasPrefix(p, "/") { + p = "/" + p + } + return root + p +} + +// EncodeByteArray will base-64 encode the byte slice v. +func EncodeByteArray(v []byte, format Base64Encoding) string { + return exported.EncodeByteArray(v, format) +} + +// MarshalAsByteArray will base-64 encode the byte slice v, then calls SetBody. +// The encoded value is treated as a JSON string. +func MarshalAsByteArray(req *policy.Request, v []byte, format Base64Encoding) error { + // send as a JSON string + encode := fmt.Sprintf("\"%s\"", EncodeByteArray(v, format)) + // tsp generated code can set Content-Type so we must prefer that + return exported.SetBody(req, exported.NopCloser(strings.NewReader(encode)), shared.ContentTypeAppJSON, false) +} + +// MarshalAsJSON calls json.Marshal() to get the JSON encoding of v then calls SetBody. +func MarshalAsJSON(req *policy.Request, v any) error { + b, err := json.Marshal(v) + if err != nil { + return fmt.Errorf("error marshalling type %T: %s", v, err) + } + // tsp generated code can set Content-Type so we must prefer that + return exported.SetBody(req, exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppJSON, false) +} + +// MarshalAsXML calls xml.Marshal() to get the XML encoding of v then calls SetBody. +func MarshalAsXML(req *policy.Request, v any) error { + b, err := xml.Marshal(v) + if err != nil { + return fmt.Errorf("error marshalling type %T: %s", v, err) + } + // inclue the XML header as some services require it + b = []byte(xml.Header + string(b)) + return req.SetBody(exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppXML) +} + +// SetMultipartFormData writes the specified keys/values as multi-part form fields with the specified value. +// File content must be specified as an [io.ReadSeekCloser] or [streaming.MultipartContent]. +// Byte slices will be treated as JSON. All other values are treated as string values. +func SetMultipartFormData(req *policy.Request, formData map[string]any) error { + body := bytes.Buffer{} + writer := multipart.NewWriter(&body) + + writeContent := func(fieldname, filename string, src io.Reader) error { + fd, err := writer.CreateFormFile(fieldname, filename) + if err != nil { + return err + } + // copy the data to the form file + if _, err = io.Copy(fd, src); err != nil { + return err + } + return nil + } + + quoteEscaper := strings.NewReplacer("\\", "\\\\", `"`, "\\\"") + + writeMultipartContent := func(fieldname string, mpc streaming.MultipartContent) error { + if mpc.Body == nil { + return errors.New("streaming.MultipartContent.Body cannot be nil") + } + + // use fieldname for the file name when unspecified + filename := fieldname + + if mpc.ContentType == "" && mpc.Filename == "" { + return writeContent(fieldname, filename, mpc.Body) + } + if mpc.Filename != "" { + filename = mpc.Filename + } + // this is pretty much copied from multipart.Writer.CreateFormFile + // but lets us set the caller provided Content-Type and filename + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", + fmt.Sprintf(`form-data; name="%s"; filename="%s"`, + quoteEscaper.Replace(fieldname), quoteEscaper.Replace(filename))) + contentType := "application/octet-stream" + if mpc.ContentType != "" { + contentType = mpc.ContentType + } + h.Set("Content-Type", contentType) + fd, err := writer.CreatePart(h) + if err != nil { + return err + } + // copy the data to the form file + if _, err = io.Copy(fd, mpc.Body); err != nil { + return err + } + return nil + } + + // the same as multipart.Writer.WriteField but lets us specify the Content-Type + writeField := func(fieldname, contentType string, value string) error { + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", + fmt.Sprintf(`form-data; name="%s"`, quoteEscaper.Replace(fieldname))) + h.Set("Content-Type", contentType) + fd, err := writer.CreatePart(h) + if err != nil { + return err + } + if _, err = fd.Write([]byte(value)); err != nil { + return err + } + return nil + } + + for k, v := range formData { + if rsc, ok := v.(io.ReadSeekCloser); ok { + if err := writeContent(k, k, rsc); err != nil { + return err + } + continue + } else if rscs, ok := v.([]io.ReadSeekCloser); ok { + for _, rsc := range rscs { + if err := writeContent(k, k, rsc); err != nil { + return err + } + } + continue + } else if mpc, ok := v.(streaming.MultipartContent); ok { + if err := writeMultipartContent(k, mpc); err != nil { + return err + } + continue + } else if mpcs, ok := v.([]streaming.MultipartContent); ok { + for _, mpc := range mpcs { + if err := writeMultipartContent(k, mpc); err != nil { + return err + } + } + continue + } + + var content string + contentType := shared.ContentTypeTextPlain + switch tt := v.(type) { + case []byte: + // JSON, don't quote it + content = string(tt) + contentType = shared.ContentTypeAppJSON + case string: + content = tt + default: + // ensure the value is in string format + content = fmt.Sprintf("%v", v) + } + + if err := writeField(k, contentType, content); err != nil { + return err + } + } + if err := writer.Close(); err != nil { + return err + } + return req.SetBody(exported.NopCloser(bytes.NewReader(body.Bytes())), writer.FormDataContentType()) +} + +// SkipBodyDownload will disable automatic downloading of the response body. +func SkipBodyDownload(req *policy.Request) { + req.SetOperationValue(bodyDownloadPolicyOpValues{Skip: true}) +} + +// CtxAPINameKey is used as a context key for adding/retrieving the API name. +type CtxAPINameKey = shared.CtxAPINameKey + +// NewUUID returns a new UUID using the RFC4122 algorithm. +func NewUUID() (string, error) { + u, err := uuid.New() + if err != nil { + return "", err + } + return u.String(), nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/response.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/response.go new file mode 100644 index 000000000..048566e02 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/response.go @@ -0,0 +1,109 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "net/http" + + azexported "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" + "github.com/Azure/azure-sdk-for-go/sdk/internal/exported" +) + +// Payload reads and returns the response body or an error. +// On a successful read, the response body is cached. +// Subsequent reads will access the cached value. +func Payload(resp *http.Response) ([]byte, error) { + return exported.Payload(resp, nil) +} + +// HasStatusCode returns true if the Response's status code is one of the specified values. +func HasStatusCode(resp *http.Response, statusCodes ...int) bool { + return exported.HasStatusCode(resp, statusCodes...) +} + +// UnmarshalAsByteArray will base-64 decode the received payload and place the result into the value pointed to by v. +func UnmarshalAsByteArray(resp *http.Response, v *[]byte, format Base64Encoding) error { + p, err := Payload(resp) + if err != nil { + return err + } + return DecodeByteArray(string(p), v, format) +} + +// UnmarshalAsJSON calls json.Unmarshal() to unmarshal the received payload into the value pointed to by v. +func UnmarshalAsJSON(resp *http.Response, v any) error { + payload, err := Payload(resp) + if err != nil { + return err + } + // TODO: verify early exit is correct + if len(payload) == 0 { + return nil + } + err = removeBOM(resp) + if err != nil { + return err + } + err = json.Unmarshal(payload, v) + if err != nil { + err = fmt.Errorf("unmarshalling type %T: %s", v, err) + } + return err +} + +// UnmarshalAsXML calls xml.Unmarshal() to unmarshal the received payload into the value pointed to by v. +func UnmarshalAsXML(resp *http.Response, v any) error { + payload, err := Payload(resp) + if err != nil { + return err + } + // TODO: verify early exit is correct + if len(payload) == 0 { + return nil + } + err = removeBOM(resp) + if err != nil { + return err + } + err = xml.Unmarshal(payload, v) + if err != nil { + err = fmt.Errorf("unmarshalling type %T: %s", v, err) + } + return err +} + +// Drain reads the response body to completion then closes it. The bytes read are discarded. +func Drain(resp *http.Response) { + if resp != nil && resp.Body != nil { + _, _ = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + } +} + +// removeBOM removes any byte-order mark prefix from the payload if present. +func removeBOM(resp *http.Response) error { + _, err := exported.Payload(resp, &exported.PayloadOptions{ + BytesModifier: func(b []byte) []byte { + // UTF8 + return bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) + }, + }) + if err != nil { + return err + } + return nil +} + +// DecodeByteArray will base-64 decode the provided string into v. +func DecodeByteArray(s string, v *[]byte, format Base64Encoding) error { + return azexported.DecodeByteArray(s, v, format) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_dialer_other.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_dialer_other.go new file mode 100644 index 000000000..1c75d771f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_dialer_other.go @@ -0,0 +1,15 @@ +//go:build !wasm + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "net" +) + +func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) { + return dialer.DialContext +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_dialer_wasm.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_dialer_wasm.go new file mode 100644 index 000000000..3dc9eeecd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_dialer_wasm.go @@ -0,0 +1,15 @@ +//go:build (js && wasm) || wasip1 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "context" + "net" +) + +func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) { + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_http_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_http_client.go new file mode 100644 index 000000000..2124c1d48 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/transport_default_http_client.go @@ -0,0 +1,48 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package runtime + +import ( + "crypto/tls" + "net" + "net/http" + "time" + + "golang.org/x/net/http2" +) + +var defaultHTTPClient *http.Client + +func init() { + defaultTransport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: defaultTransportDialContext(&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }), + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + MaxIdleConnsPerHost: 10, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + TLSClientConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + Renegotiation: tls.RenegotiateFreelyAsClient, + }, + } + // TODO: evaluate removing this once https://github.com/golang/go/issues/59690 has been fixed + if http2Transport, err := http2.ConfigureTransports(defaultTransport); err == nil { + // if the connection has been idle for 10 seconds, send a ping frame for a health check + http2Transport.ReadIdleTimeout = 10 * time.Second + // if there's no response to the ping within the timeout, the connection will be closed + http2Transport.PingTimeout = 5 * time.Second + } + defaultHTTPClient = &http.Client{ + Transport: defaultTransport, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming/doc.go new file mode 100644 index 000000000..cadaef3d5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming/doc.go @@ -0,0 +1,9 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package streaming contains helpers for streaming IO operations and progress reporting. +package streaming diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming/progress.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming/progress.go new file mode 100644 index 000000000..2468540bd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming/progress.go @@ -0,0 +1,89 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package streaming + +import ( + "io" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported" +) + +type progress struct { + rc io.ReadCloser + rsc io.ReadSeekCloser + pr func(bytesTransferred int64) + offset int64 +} + +// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker. +// In addition to adding a Close method to an io.ReadSeeker, this can also be used to wrap an +// io.ReadSeekCloser with a no-op Close method to allow explicit control of when the io.ReedSeekCloser +// has its underlying stream closed. +func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser { + return exported.NopCloser(rs) +} + +// NewRequestProgress adds progress reporting to an HTTP request's body stream. +func NewRequestProgress(body io.ReadSeekCloser, pr func(bytesTransferred int64)) io.ReadSeekCloser { + return &progress{ + rc: body, + rsc: body, + pr: pr, + offset: 0, + } +} + +// NewResponseProgress adds progress reporting to an HTTP response's body stream. +func NewResponseProgress(body io.ReadCloser, pr func(bytesTransferred int64)) io.ReadCloser { + return &progress{ + rc: body, + rsc: nil, + pr: pr, + offset: 0, + } +} + +// Read reads a block of data from an inner stream and reports progress +func (p *progress) Read(b []byte) (n int, err error) { + n, err = p.rc.Read(b) + if err != nil && err != io.EOF { + return + } + p.offset += int64(n) + // Invokes the user's callback method to report progress + p.pr(p.offset) + return +} + +// Seek only expects a zero or from beginning. +func (p *progress) Seek(offset int64, whence int) (int64, error) { + // This should only ever be called with offset = 0 and whence = io.SeekStart + n, err := p.rsc.Seek(offset, whence) + if err == nil { + p.offset = int64(n) + } + return n, err +} + +// requestBodyProgress supports Close but the underlying stream may not; if it does, Close will close it. +func (p *progress) Close() error { + return p.rc.Close() +} + +// MultipartContent contains streaming content used in multipart/form payloads. +type MultipartContent struct { + // Body contains the required content body. + Body io.ReadSeekCloser + + // ContentType optionally specifies the HTTP Content-Type for this Body. + // The default value is application/octet-stream. + ContentType string + + // Filename optionally specifies the filename for this Body. + // The default value is the field name for the multipart/form section. + Filename string +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/to/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/to/doc.go new file mode 100644 index 000000000..faa98c9dc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/to/doc.go @@ -0,0 +1,9 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +// Package to contains various type-conversion helper functions. +package to diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/to/to.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/to/to.go new file mode 100644 index 000000000..e0e4817b9 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/to/to.go @@ -0,0 +1,21 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package to + +// Ptr returns a pointer to the provided value. +func Ptr[T any](v T) *T { + return &v +} + +// SliceOfPtrs returns a slice of *T from the specified values. +func SliceOfPtrs[T any](vv ...T) []*T { + slc := make([]*T, len(vv)) + for i := range vv { + slc[i] = Ptr(vv[i]) + } + return slc +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing/constants.go new file mode 100644 index 000000000..80282d4ab --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing/constants.go @@ -0,0 +1,41 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package tracing + +// SpanKind represents the role of a Span inside a Trace. Often, this defines how a Span will be processed and visualized by various backends. +type SpanKind int + +const ( + // SpanKindInternal indicates the span represents an internal operation within an application. + SpanKindInternal SpanKind = 1 + + // SpanKindServer indicates the span covers server-side handling of a request. + SpanKindServer SpanKind = 2 + + // SpanKindClient indicates the span describes a request to a remote service. + SpanKindClient SpanKind = 3 + + // SpanKindProducer indicates the span was created by a messaging producer. + SpanKindProducer SpanKind = 4 + + // SpanKindConsumer indicates the span was created by a messaging consumer. + SpanKindConsumer SpanKind = 5 +) + +// SpanStatus represents the status of a span. +type SpanStatus int + +const ( + // SpanStatusUnset is the default status code. + SpanStatusUnset SpanStatus = 0 + + // SpanStatusError indicates the operation contains an error. + SpanStatusError SpanStatus = 1 + + // SpanStatusOK indicates the operation completed successfully. + SpanStatusOK SpanStatus = 2 +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing/tracing.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing/tracing.go new file mode 100644 index 000000000..1ade7c560 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing/tracing.go @@ -0,0 +1,191 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// Package tracing contains the definitions needed to support distributed tracing. +package tracing + +import ( + "context" +) + +// ProviderOptions contains the optional values when creating a Provider. +type ProviderOptions struct { + // for future expansion +} + +// NewProvider creates a new Provider with the specified values. +// - newTracerFn is the underlying implementation for creating Tracer instances +// - options contains optional values; pass nil to accept the default value +func NewProvider(newTracerFn func(name, version string) Tracer, options *ProviderOptions) Provider { + return Provider{ + newTracerFn: newTracerFn, + } +} + +// Provider is the factory that creates Tracer instances. +// It defaults to a no-op provider. +type Provider struct { + newTracerFn func(name, version string) Tracer +} + +// NewTracer creates a new Tracer for the specified module name and version. +// - module - the fully qualified name of the module +// - version - the version of the module +func (p Provider) NewTracer(module, version string) (tracer Tracer) { + if p.newTracerFn != nil { + tracer = p.newTracerFn(module, version) + } + return +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// TracerOptions contains the optional values when creating a Tracer. +type TracerOptions struct { + // SpanFromContext contains the implementation for the Tracer.SpanFromContext method. + SpanFromContext func(context.Context) Span +} + +// NewTracer creates a Tracer with the specified values. +// - newSpanFn is the underlying implementation for creating Span instances +// - options contains optional values; pass nil to accept the default value +func NewTracer(newSpanFn func(ctx context.Context, spanName string, options *SpanOptions) (context.Context, Span), options *TracerOptions) Tracer { + if options == nil { + options = &TracerOptions{} + } + return Tracer{ + newSpanFn: newSpanFn, + spanFromContextFn: options.SpanFromContext, + } +} + +// Tracer is the factory that creates Span instances. +type Tracer struct { + attrs []Attribute + newSpanFn func(ctx context.Context, spanName string, options *SpanOptions) (context.Context, Span) + spanFromContextFn func(ctx context.Context) Span +} + +// Start creates a new span and a context.Context that contains it. +// - ctx is the parent context for this span. If it contains a Span, the newly created span will be a child of that span, else it will be a root span +// - spanName identifies the span within a trace, it's typically the fully qualified API name +// - options contains optional values for the span, pass nil to accept any defaults +func (t Tracer) Start(ctx context.Context, spanName string, options *SpanOptions) (context.Context, Span) { + if t.newSpanFn != nil { + opts := SpanOptions{} + if options != nil { + opts = *options + } + opts.Attributes = append(opts.Attributes, t.attrs...) + return t.newSpanFn(ctx, spanName, &opts) + } + return ctx, Span{} +} + +// SetAttributes sets attrs to be applied to each Span. If a key from attrs +// already exists for an attribute of the Span it will be overwritten with +// the value contained in attrs. +func (t *Tracer) SetAttributes(attrs ...Attribute) { + t.attrs = append(t.attrs, attrs...) +} + +// Enabled returns true if this Tracer is capable of creating Spans. +func (t Tracer) Enabled() bool { + return t.newSpanFn != nil +} + +// SpanFromContext returns the Span associated with the current context. +// If the provided context has no Span, false is returned. +func (t Tracer) SpanFromContext(ctx context.Context) Span { + if t.spanFromContextFn != nil { + return t.spanFromContextFn(ctx) + } + return Span{} +} + +// SpanOptions contains optional settings for creating a span. +type SpanOptions struct { + // Kind indicates the kind of Span. + Kind SpanKind + + // Attributes contains key-value pairs of attributes for the span. + Attributes []Attribute +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// SpanImpl abstracts the underlying implementation for Span, +// allowing it to work with various tracing implementations. +// Any zero-values will have their default, no-op behavior. +type SpanImpl struct { + // End contains the implementation for the Span.End method. + End func() + + // SetAttributes contains the implementation for the Span.SetAttributes method. + SetAttributes func(...Attribute) + + // AddEvent contains the implementation for the Span.AddEvent method. + AddEvent func(string, ...Attribute) + + // SetStatus contains the implementation for the Span.SetStatus method. + SetStatus func(SpanStatus, string) +} + +// NewSpan creates a Span with the specified implementation. +func NewSpan(impl SpanImpl) Span { + return Span{ + impl: impl, + } +} + +// Span is a single unit of a trace. A trace can contain multiple spans. +// A zero-value Span provides a no-op implementation. +type Span struct { + impl SpanImpl +} + +// End terminates the span and MUST be called before the span leaves scope. +// Any further updates to the span will be ignored after End is called. +func (s Span) End() { + if s.impl.End != nil { + s.impl.End() + } +} + +// SetAttributes sets the specified attributes on the Span. +// Any existing attributes with the same keys will have their values overwritten. +func (s Span) SetAttributes(attrs ...Attribute) { + if s.impl.SetAttributes != nil { + s.impl.SetAttributes(attrs...) + } +} + +// AddEvent adds a named event with an optional set of attributes to the span. +func (s Span) AddEvent(name string, attrs ...Attribute) { + if s.impl.AddEvent != nil { + s.impl.AddEvent(name, attrs...) + } +} + +// SetStatus sets the status on the span along with a description. +func (s Span) SetStatus(code SpanStatus, desc string) { + if s.impl.SetStatus != nil { + s.impl.SetStatus(code, desc) + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Attribute is a key-value pair. +type Attribute struct { + // Key is the name of the attribute. + Key string + + // Value is the attribute's value. + // Types that are natively supported include int64, float64, int, bool, string. + // Any other type will be formatted per rules of fmt.Sprintf("%v"). + Value any +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/.gitignore b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/.gitignore new file mode 100644 index 000000000..8cdb91036 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/.gitignore @@ -0,0 +1,4 @@ +# live test artifacts +Dockerfile +k8s.yaml +sshkey* diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/BREAKING_CHANGES.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/BREAKING_CHANGES.md new file mode 100644 index 000000000..567e6975b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/BREAKING_CHANGES.md @@ -0,0 +1,20 @@ +# Breaking Changes + +## v1.8.0 + +### New errors from `NewManagedIdentityCredential` in some environments + +`NewManagedIdentityCredential` now returns an error when `ManagedIdentityCredentialOptions.ID` is set in a hosting environment whose managed identity API doesn't support user-assigned identities. `ManagedIdentityCredential.GetToken()` formerly logged a warning in these cases. Returning an error instead prevents the credential authenticating an unexpected identity. The affected hosting environments are: + * Azure Arc + * Azure ML (when a resource or object ID is specified; client IDs are supported) + * Cloud Shell + * Service Fabric + +## v1.6.0 + +### Behavioral change to `DefaultAzureCredential` in IMDS managed identity scenarios + +As of `azidentity` v1.6.0, `DefaultAzureCredential` makes a minor behavioral change when it uses IMDS managed +identity. It sends its first request to IMDS without the "Metadata" header, to expedite validating whether the endpoint +is available. This precedes the credential's first token request and is guaranteed to fail with a 400 error. This error +response can appear in logs but doesn't indicate authentication failed. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md new file mode 100644 index 000000000..ab63f9c03 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md @@ -0,0 +1,695 @@ +# Release History + +## 1.12.0 (2025-09-16) + +### Features Added +- Added `DefaultAzureCredentialOptions.RequireAzureTokenCredentials`. `NewDefaultAzureCredential` returns an + error when this option is true and the environment variable `AZURE_TOKEN_CREDENTIALS` has no value. + +### Other Changes +- `AzureDeveloperCLICredential` no longer hangs when AZD_DEBUG is set +- `GetToken` methods of `AzureCLICredential` and `AzureDeveloperCLICredential` return an error when + `TokenRequestOptions.Claims` has a value because these credentials can't acquire a token in that + case. The error messages describe the action required to get a token. + +## 1.11.0 (2025-08-05) + +### Other Changes +- `DefaultAzureCredential` tries its next credential when a dev tool credential such as + `AzureCLICredential` returns an error + +## 1.11.0-beta.1 (2025-07-15) + +### Features Added +- `DefaultAzureCredential` allows selecting one of its credential types by name via environment variable + `AZURE_TOKEN_CREDENTIALS`. It will use only the selected type at runtime. For example, set + `AZURE_TOKEN_CREDENTIALS=WorkloadIdentityCredential` to have `DefaultAzureCredential` use only + `WorkloadIdentityCredential`. + +### Other Changes +- By default, `ManagedIdentityCredential` retries IMDS requests for a maximum of ~70 seconds as recommended + in IMDS documentation. In previous versions, it would stop retrying after ~54 seconds by default. + +## 1.10.1 (2025-06-10) + +### Bugs Fixed +- `AzureCLICredential` and `AzureDeveloperCLICredential` could wait indefinitely for subprocess output + +## 1.10.0 (2025-05-14) + +### Features Added +- `DefaultAzureCredential` reads environment variable `AZURE_TOKEN_CREDENTIALS` to enable a subset of its credentials: + - `dev` selects `AzureCLICredential` and `AzureDeveloperCLICredential` + - `prod` selects `EnvironmentCredential`, `WorkloadIdentityCredential` and `ManagedIdentityCredential` + +## 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 +* Upgraded dependencies + +## 1.8.1 (2025-01-15) + +### Bugs Fixed +* User credential types inconsistently log access token scopes +* `DefaultAzureCredential` skips managed identity in Azure Container Instances +* Credentials having optional tenant IDs such as `AzureCLICredential` and + `InteractiveBrowserCredential` require setting `AdditionallyAllowedTenants` + when used with some clients + +### Other Changes +* `ChainedTokenCredential` and `DefaultAzureCredential` continue to their next + credential after `ManagedIdentityCredential` receives an unexpected response + from IMDS, indicating the response is from something else such as a proxy + +## 1.8.0 (2024-10-08) + +### Other Changes +* `AzurePipelinesCredential` sets an additional OIDC request header so that it + receives a 401 instead of a 302 after presenting an invalid system access token +* Allow logging of debugging headers for `AzurePipelinesCredential` and include + them in error messages + +## 1.8.0-beta.3 (2024-09-17) + +### Features Added +* Added `ObjectID` type for `ManagedIdentityCredentialOptions.ID` + +### Other Changes +* Removed redundant content from error messages + +## 1.8.0-beta.2 (2024-08-06) + +### Breaking Changes +* `NewManagedIdentityCredential` now returns an error when a user-assigned identity + is specified on a platform whose managed identity API doesn't support that. + `ManagedIdentityCredential.GetToken()` formerly logged a warning in these cases. + Returning an error instead prevents the credential authenticating an unexpected + identity, causing a client to act with unexpected privileges. The affected + platforms are: + * Azure Arc + * Azure ML (when a resource ID is specified; client IDs are supported) + * Cloud Shell + * Service Fabric + +### Other Changes +* If `DefaultAzureCredential` receives a non-JSON response when probing IMDS before + attempting to authenticate a managed identity, it continues to the next credential + in the chain instead of immediately returning an error. + +## 1.8.0-beta.1 (2024-07-17) + +### Features Added +* Restored persistent token caching feature + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.7.0-beta.1 +* Redesigned the persistent caching API. Encryption is now required in all cases + and persistent cache construction is separate from credential construction. + The `PersistentUserAuthentication` example in the package docs has been updated + to demonstrate the new API. + +## 1.7.0 (2024-06-20) + +### Features Added +* `AzurePipelinesCredential` authenticates an Azure Pipelines service connection with + workload identity federation + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.7.0-beta.1 +* Removed the persistent token caching API. It will return in v1.8.0-beta.1 + +## 1.7.0-beta.1 (2024-06-10) + +### Features Added +* Restored `AzurePipelinesCredential` and persistent token caching API + +## Breaking Changes +> These changes affect only code written against a beta version such as v1.6.0-beta.4 +* Values which `NewAzurePipelinesCredential` read from environment variables in + prior versions are now parameters +* Renamed `AzurePipelinesServiceConnectionCredentialOptions` to `AzurePipelinesCredentialOptions` + +### Bugs Fixed +* Managed identity bug fixes + +## 1.6.0 (2024-06-10) + +### Features Added +* `NewOnBehalfOfCredentialWithClientAssertions` creates an on-behalf-of credential + that authenticates with client assertions such as federated credentials + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.6.0-beta.4 +* Removed `AzurePipelinesCredential` and the persistent token caching API. + They will return in v1.7.0-beta.1 + +### Bugs Fixed +* Managed identity bug fixes + +## 1.6.0-beta.4 (2024-05-14) + +### Features Added +* `AzurePipelinesCredential` authenticates an Azure Pipeline service connection with + workload identity federation + +## 1.6.0-beta.3 (2024-04-09) + +### Breaking Changes +* `DefaultAzureCredential` now sends a probe request with no retries for IMDS managed identity + environments to avoid excessive retry delays when the IMDS endpoint is not available. This + should improve credential chain resolution for local development scenarios. + +### Bugs Fixed +* `ManagedIdentityCredential` now specifies resource IDs correctly for Azure Container Instances + +## 1.5.2 (2024-04-09) + +### Bugs Fixed +* `ManagedIdentityCredential` now specifies resource IDs correctly for Azure Container Instances + +### Other Changes +* Restored v1.4.0 error behavior for empty tenant IDs +* Upgraded dependencies + +## 1.6.0-beta.2 (2024-02-06) + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.6.0-beta.1 +* Replaced `ErrAuthenticationRequired` with `AuthenticationRequiredError`, a struct + type that carries the `TokenRequestOptions` passed to the `GetToken` call which + returned the error. + +### Bugs Fixed +* Fixed more cases in which credential chains like `DefaultAzureCredential` + should try their next credential after attempting managed identity + authentication in a Docker Desktop container + +### Other Changes +* `AzureCLICredential` uses the CLI's `expires_on` value for token expiration + +## 1.6.0-beta.1 (2024-01-17) + +### Features Added +* Restored persistent token caching API first added in v1.5.0-beta.1 +* Added `AzureCLICredentialOptions.Subscription` + +## 1.5.1 (2024-01-17) + +### Bugs Fixed +* `InteractiveBrowserCredential` handles `AdditionallyAllowedTenants` correctly + +## 1.5.0 (2024-01-16) + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.5.0-beta.1 +* Removed persistent token caching. It will return in v1.6.0-beta.1 + +### Bugs Fixed +* Credentials now preserve MSAL headers e.g. X-Client-Sku + +### Other Changes +* Upgraded dependencies + +## 1.5.0-beta.2 (2023-11-07) + +### Features Added +* `DefaultAzureCredential` and `ManagedIdentityCredential` support Azure ML managed identity +* Added spans for distributed tracing. + +## 1.5.0-beta.1 (2023-10-10) + +### Features Added +* Optional persistent token caching for most credentials. Set `TokenCachePersistenceOptions` + on a credential's options to enable and configure this. See the package documentation for + this version and [TOKEN_CACHING.md](https://aka.ms/azsdk/go/identity/caching) for more + details. +* `AzureDeveloperCLICredential` authenticates with the Azure Developer CLI (`azd`). This + credential is also part of the `DefaultAzureCredential` authentication flow. + +## 1.4.0 (2023-10-10) + +### Bugs Fixed +* `ManagedIdentityCredential` will now retry when IMDS responds 410 or 503 + +## 1.4.0-beta.5 (2023-09-12) + +### Features Added +* Service principal credentials can request CAE tokens + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.4.0-beta.4 +* Whether `GetToken` requests a CAE token is now determined by `TokenRequestOptions.EnableCAE`. Azure + SDK clients which support CAE will set this option automatically. Credentials no longer request CAE + tokens by default or observe the environment variable "AZURE_IDENTITY_DISABLE_CP1". + +### Bugs Fixed +* Credential chains such as `DefaultAzureCredential` now try their next credential, if any, when + managed identity authentication fails in a Docker Desktop container + ([#21417](https://github.com/Azure/azure-sdk-for-go/issues/21417)) + +## 1.4.0-beta.4 (2023-08-16) + +### Other Changes +* Upgraded dependencies + +## 1.3.1 (2023-08-16) + +### Other Changes +* Upgraded dependencies + +## 1.4.0-beta.3 (2023-08-08) + +### Bugs Fixed +* One invocation of `AzureCLICredential.GetToken()` and `OnBehalfOfCredential.GetToken()` + can no longer make two authentication attempts + +## 1.4.0-beta.2 (2023-07-14) + +### Other Changes +* `DefaultAzureCredentialOptions.TenantID` applies to workload identity authentication +* Upgraded dependencies + +## 1.4.0-beta.1 (2023-06-06) + +### Other Changes +* Re-enabled CAE support as in v1.3.0-beta.3 + +## 1.3.0 (2023-05-09) + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.3.0-beta.5 +* Renamed `NewOnBehalfOfCredentialFromCertificate` to `NewOnBehalfOfCredentialWithCertificate` +* Renamed `NewOnBehalfOfCredentialFromSecret` to `NewOnBehalfOfCredentialWithSecret` + +### Other Changes +* Upgraded to MSAL v1.0.0 + +## 1.3.0-beta.5 (2023-04-11) + +### Breaking Changes +> These changes affect only code written against a beta version such as v1.3.0-beta.4 +* Moved `NewWorkloadIdentityCredential()` parameters into `WorkloadIdentityCredentialOptions`. + The constructor now reads default configuration from environment variables set by the Azure + workload identity webhook by default. + ([#20478](https://github.com/Azure/azure-sdk-for-go/pull/20478)) +* Removed CAE support. It will return in v1.4.0-beta.1 + ([#20479](https://github.com/Azure/azure-sdk-for-go/pull/20479)) + +### Bugs Fixed +* Fixed an issue in `DefaultAzureCredential` that could cause the managed identity endpoint check to fail in rare circumstances. + +## 1.3.0-beta.4 (2023-03-08) + +### Features Added +* Added `WorkloadIdentityCredentialOptions.AdditionallyAllowedTenants` and `.DisableInstanceDiscovery` + +### Bugs Fixed +* Credentials now synchronize within `GetToken()` so a single instance can be shared among goroutines + ([#20044](https://github.com/Azure/azure-sdk-for-go/issues/20044)) + +### Other Changes +* Upgraded dependencies + +## 1.2.2 (2023-03-07) + +### Other Changes +* Upgraded dependencies + +## 1.3.0-beta.3 (2023-02-07) + +### Features Added +* By default, credentials set client capability "CP1" to enable support for + [Continuous Access Evaluation (CAE)](https://learn.microsoft.com/entra/identity-platform/app-resilience-continuous-access-evaluation). + This indicates to Microsoft Entra ID that your application can handle CAE claims challenges. + You can disable this behavior by setting the environment variable "AZURE_IDENTITY_DISABLE_CP1" to "true". +* `InteractiveBrowserCredentialOptions.LoginHint` enables pre-populating the login + prompt with a username ([#15599](https://github.com/Azure/azure-sdk-for-go/pull/15599)) +* Service principal and user credentials support ADFS authentication on Azure Stack. + Specify "adfs" as the credential's tenant. +* Applications running in private or disconnected clouds can prevent credentials from + requesting Microsoft Entra instance metadata by setting the `DisableInstanceDiscovery` + field on credential options. +* Many credentials can now be configured to authenticate in multiple tenants. The + options types for these credentials have an `AdditionallyAllowedTenants` field + that specifies additional tenants in which the credential may authenticate. + +## 1.3.0-beta.2 (2023-01-10) + +### Features Added +* Added `OnBehalfOfCredential` to support the on-behalf-of flow + ([#16642](https://github.com/Azure/azure-sdk-for-go/issues/16642)) + +### Bugs Fixed +* `AzureCLICredential` reports token expiration in local time (should be UTC) + +### Other Changes +* `AzureCLICredential` imposes its default timeout only when the `Context` + passed to `GetToken()` has no deadline +* Added `NewCredentialUnavailableError()`. This function constructs an error indicating + a credential can't authenticate and an encompassing `ChainedTokenCredential` should + try its next credential, if any. + +## 1.3.0-beta.1 (2022-12-13) + +### Features Added +* `WorkloadIdentityCredential` and `DefaultAzureCredential` support + Workload Identity Federation on Kubernetes. `DefaultAzureCredential` + support requires environment variable configuration as set by the + Workload Identity webhook. + ([#15615](https://github.com/Azure/azure-sdk-for-go/issues/15615)) + +## 1.2.0 (2022-11-08) + +### Other Changes +* This version includes all fixes and features from 1.2.0-beta.* + +## 1.2.0-beta.3 (2022-10-11) + +### Features Added +* `ManagedIdentityCredential` caches tokens in memory + +### Bugs Fixed +* `ClientCertificateCredential` sends only the leaf cert for SNI authentication + +## 1.2.0-beta.2 (2022-08-10) + +### Features Added +* Added `ClientAssertionCredential` to enable applications to authenticate + with custom client assertions + +### Other Changes +* Updated AuthenticationFailedError with links to TROUBLESHOOTING.md for relevant errors +* Upgraded `microsoft-authentication-library-for-go` requirement to v0.6.0 + +## 1.2.0-beta.1 (2022-06-07) + +### Features Added +* `EnvironmentCredential` reads certificate passwords from `AZURE_CLIENT_CERTIFICATE_PASSWORD` + ([#17099](https://github.com/Azure/azure-sdk-for-go/pull/17099)) + +## 1.1.0 (2022-06-07) + +### Features Added +* `ClientCertificateCredential` and `ClientSecretCredential` support ESTS-R. First-party + applications can set environment variable `AZURE_REGIONAL_AUTHORITY_NAME` with a + region name. + ([#15605](https://github.com/Azure/azure-sdk-for-go/issues/15605)) + +## 1.0.1 (2022-06-07) + +### Other Changes +* Upgrade `microsoft-authentication-library-for-go` requirement to v0.5.1 + ([#18176](https://github.com/Azure/azure-sdk-for-go/issues/18176)) + +## 1.0.0 (2022-05-12) + +### Features Added +* `DefaultAzureCredential` reads environment variable `AZURE_CLIENT_ID` for the + client ID of a user-assigned managed identity + ([#17293](https://github.com/Azure/azure-sdk-for-go/pull/17293)) + +### Breaking Changes +* Removed `AuthorizationCodeCredential`. Use `InteractiveBrowserCredential` instead + to authenticate a user with the authorization code flow. +* Instances of `AuthenticationFailedError` are now returned by pointer. +* `GetToken()` returns `azcore.AccessToken` by value + +### Bugs Fixed +* `AzureCLICredential` panics after receiving an unexpected error type + ([#17490](https://github.com/Azure/azure-sdk-for-go/issues/17490)) + +### Other Changes +* `GetToken()` returns an error when the caller specifies no scope +* Updated to the latest versions of `golang.org/x/crypto`, `azcore` and `internal` + +## 0.14.0 (2022-04-05) + +### Breaking Changes +* This module now requires Go 1.18 +* Removed `AuthorityHost`. Credentials are now configured for sovereign or private + clouds with the API in `azcore/cloud`, for example: + ```go + // before + opts := azidentity.ClientSecretCredentialOptions{AuthorityHost: azidentity.AzureGovernment} + cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, &opts) + + // after + import "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + + opts := azidentity.ClientSecretCredentialOptions{} + opts.Cloud = cloud.AzureGovernment + cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, &opts) + ``` + +## 0.13.2 (2022-03-08) + +### Bugs Fixed +* Prevented a data race in `DefaultAzureCredential` and `ChainedTokenCredential` + ([#17144](https://github.com/Azure/azure-sdk-for-go/issues/17144)) + +### Other Changes +* Upgraded App Service managed identity version from 2017-09-01 to 2019-08-01 + ([#17086](https://github.com/Azure/azure-sdk-for-go/pull/17086)) + +## 0.13.1 (2022-02-08) + +### Features Added +* `EnvironmentCredential` supports certificate SNI authentication when + `AZURE_CLIENT_SEND_CERTIFICATE_CHAIN` is "true". + ([#16851](https://github.com/Azure/azure-sdk-for-go/pull/16851)) + +### Bugs Fixed +* `ManagedIdentityCredential.GetToken()` now returns an error when configured for + a user assigned identity in Azure Cloud Shell (which doesn't support such identities) + ([#16946](https://github.com/Azure/azure-sdk-for-go/pull/16946)) + +### Other Changes +* `NewDefaultAzureCredential()` logs non-fatal errors. These errors are also included in the + error returned by `DefaultAzureCredential.GetToken()` when it's unable to acquire a token + from any source. ([#15923](https://github.com/Azure/azure-sdk-for-go/issues/15923)) + +## 0.13.0 (2022-01-11) + +### Breaking Changes +* Replaced `AuthenticationFailedError.RawResponse()` with a field having the same name +* Unexported `CredentialUnavailableError` +* Instances of `ChainedTokenCredential` will now skip looping through the list of source credentials and re-use the first successful credential on subsequent calls to `GetToken`. + * If `ChainedTokenCredentialOptions.RetrySources` is true, `ChainedTokenCredential` will continue to try all of the originally provided credentials each time the `GetToken` method is called. + * `ChainedTokenCredential.successfulCredential` will contain a reference to the last successful credential. + * `DefaultAzureCredenial` will also re-use the first successful credential on subsequent calls to `GetToken`. + * `DefaultAzureCredential.chain.successfulCredential` will also contain a reference to the last successful credential. + +### Other Changes +* `ManagedIdentityCredential` no longer probes IMDS before requesting a token + from it. Also, an error response from IMDS no longer disables a credential + instance. Following an error, a credential instance will continue to send + requests to IMDS as necessary. +* Adopted MSAL for user and service principal authentication +* Updated `azcore` requirement to 0.21.0 + +## 0.12.0 (2021-11-02) +### Breaking Changes +* Raised minimum go version to 1.16 +* Removed `NewAuthenticationPolicy()` from credentials. Clients should instead use azcore's + `runtime.NewBearerTokenPolicy()` to construct a bearer token authorization policy. +* The `AuthorityHost` field in credential options structs is now a custom type, + `AuthorityHost`, with underlying type `string` +* `NewChainedTokenCredential` has a new signature to accommodate a placeholder + options struct: + ```go + // before + cred, err := NewChainedTokenCredential(credA, credB) + + // after + cred, err := NewChainedTokenCredential([]azcore.TokenCredential{credA, credB}, nil) + ``` +* Removed `ExcludeAzureCLICredential`, `ExcludeEnvironmentCredential`, and `ExcludeMSICredential` + from `DefaultAzureCredentialOptions` +* `NewClientCertificateCredential` requires a `[]*x509.Certificate` and `crypto.PrivateKey` instead of + a path to a certificate file. Added `ParseCertificates` to simplify getting these in common cases: + ```go + // before + cred, err := NewClientCertificateCredential("tenant", "client-id", "/cert.pem", nil) + + // after + certData, err := os.ReadFile("/cert.pem") + certs, key, err := ParseCertificates(certData, password) + cred, err := NewClientCertificateCredential(tenantID, clientID, certs, key, nil) + ``` +* Removed `InteractiveBrowserCredentialOptions.ClientSecret` and `.Port` +* Removed `AADAuthenticationFailedError` +* Removed `id` parameter of `NewManagedIdentityCredential()`. User assigned identities are now + specified by `ManagedIdentityCredentialOptions.ID`: + ```go + // before + cred, err := NewManagedIdentityCredential("client-id", nil) + // or, for a resource ID + opts := &ManagedIdentityCredentialOptions{ID: ResourceID} + cred, err := NewManagedIdentityCredential("/subscriptions/...", opts) + + // after + clientID := ClientID("7cf7db0d-...") + opts := &ManagedIdentityCredentialOptions{ID: clientID} + // or, for a resource ID + resID: ResourceID("/subscriptions/...") + opts := &ManagedIdentityCredentialOptions{ID: resID} + cred, err := NewManagedIdentityCredential(opts) + ``` +* `DeviceCodeCredentialOptions.UserPrompt` has a new type: `func(context.Context, DeviceCodeMessage) error` +* Credential options structs now embed `azcore.ClientOptions`. In addition to changing literal initialization + syntax, this change renames `HTTPClient` fields to `Transport`. +* Renamed `LogCredential` to `EventCredential` +* `AzureCLICredential` no longer reads the environment variable `AZURE_CLI_PATH` +* `NewManagedIdentityCredential` no longer reads environment variables `AZURE_CLIENT_ID` and + `AZURE_RESOURCE_ID`. Use `ManagedIdentityCredentialOptions.ID` instead. +* Unexported `AuthenticationFailedError` and `CredentialUnavailableError` structs. In their place are two + interfaces having the same names. + +### Bugs Fixed +* `AzureCLICredential.GetToken` no longer mutates its `opts.Scopes` + +### Features Added +* Added connection configuration options to `DefaultAzureCredentialOptions` +* `AuthenticationFailedError.RawResponse()` returns the HTTP response motivating the error, + if available + +### Other Changes +* `NewDefaultAzureCredential()` returns `*DefaultAzureCredential` instead of `*ChainedTokenCredential` +* Added `TenantID` field to `DefaultAzureCredentialOptions` and `AzureCLICredentialOptions` + +## 0.11.0 (2021-09-08) +### Breaking Changes +* Unexported `AzureCLICredentialOptions.TokenProvider` and its type, + `AzureCLITokenProvider` + +### Bug Fixes +* `ManagedIdentityCredential.GetToken` returns `CredentialUnavailableError` + when IMDS has no assigned identity, signaling `DefaultAzureCredential` to + try other credentials + + +## 0.10.0 (2021-08-30) +### Breaking Changes +* Update based on `azcore` refactor [#15383](https://github.com/Azure/azure-sdk-for-go/pull/15383) + +## 0.9.3 (2021-08-20) + +### Bugs Fixed +* `ManagedIdentityCredential.GetToken` no longer mutates its `opts.Scopes` + +### Other Changes +* Bumps version of `azcore` to `v0.18.1` + + +## 0.9.2 (2021-07-23) +### Features Added +* Adding support for Service Fabric environment in `ManagedIdentityCredential` +* Adding an option for using a resource ID instead of client ID in `ManagedIdentityCredential` + + +## 0.9.1 (2021-05-24) +### Features Added +* Add LICENSE.txt and bump version information + + +## 0.9.0 (2021-05-21) +### Features Added +* Add support for authenticating in Azure Stack environments +* Enable user assigned identities for the IMDS scenario in `ManagedIdentityCredential` +* Add scope to resource conversion in `GetToken()` on `ManagedIdentityCredential` + + +## 0.8.0 (2021-01-20) +### Features Added +* Updating documentation + + +## 0.7.1 (2021-01-04) +### Features Added +* Adding port option to `InteractiveBrowserCredential` + + +## 0.7.0 (2020-12-11) +### Features Added +* Add `redirectURI` parameter back to authentication code flow + + +## 0.6.1 (2020-12-09) +### Features Added +* Updating query parameter in `ManagedIdentityCredential` and updating datetime string for parsing managed identity access tokens. + + +## 0.6.0 (2020-11-16) +### Features Added +* Remove `RedirectURL` parameter from auth code flow to align with the MSAL implementation which relies on the native client redirect URL. + + +## 0.5.0 (2020-10-30) +### Features Added +* Flattening credential options + + +## 0.4.3 (2020-10-21) +### Features Added +* Adding Azure Arc support in `ManagedIdentityCredential` + + +## 0.4.2 (2020-10-16) +### Features Added +* Typo fixes + + +## 0.4.1 (2020-10-16) +### Features Added +* Ensure authority hosts are only HTTPs + + +## 0.4.0 (2020-10-16) +### Features Added +* Adding options structs for credentials + + +## 0.3.0 (2020-10-09) +### Features Added +* Update `DeviceCodeCredential` callback + + +## 0.2.2 (2020-10-09) +### Features Added +* Add `AuthorizationCodeCredential` + + +## 0.2.1 (2020-10-06) +### Features Added +* Add `InteractiveBrowserCredential` + + +## 0.2.0 (2020-09-11) +### Features Added +* Refactor `azidentity` on top of `azcore` refactor +* Updated policies to conform to `policy.Policy` interface changes. +* Updated non-retriable errors to conform to `azcore.NonRetriableError`. +* Fixed calls to `Request.SetBody()` to include content type. +* Switched endpoints to string types and removed extra parsing code. + + +## 0.1.1 (2020-09-02) +### Features Added +* Add `AzureCLICredential` to `DefaultAzureCredential` chain + + +## 0.1.0 (2020-07-23) +### Features Added +* Initial Release. Azure Identity library that provides Microsoft Entra token authentication support for the SDK. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/LICENSE.txt new file mode 100644 index 000000000..48ea6616b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/MIGRATION.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/MIGRATION.md new file mode 100644 index 000000000..29b60baec --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/MIGRATION.md @@ -0,0 +1,307 @@ +# Migrating from autorest/adal to azidentity + +`azidentity` provides Microsoft Entra ID ([formerly Azure Active Directory](https://learn.microsoft.com/entra/fundamentals/new-name)) authentication for the newest Azure SDK modules (`github.com/azure-sdk-for-go/sdk/...`). Older Azure SDK packages (`github.com/azure-sdk-for-go/services/...`) use types from `github.com/go-autorest/autorest/adal` instead. + +This guide shows common authentication code using `autorest/adal` and its equivalent using `azidentity`. + +## Table of contents + +- [Acquire a token](#acquire-a-token) +- [Client certificate authentication](#client-certificate-authentication) +- [Client secret authentication](#client-secret-authentication) +- [Configuration](#configuration) +- [Device code authentication](#device-code-authentication) +- [Managed identity](#managed-identity) +- [Use azidentity credentials with older packages](#use-azidentity-credentials-with-older-packages) + +## Configuration + +### `autorest/adal` + +Token providers require a token audience (resource identifier) and an instance of `adal.OAuthConfig`, which requires a Microsoft Entra endpoint and tenant: + +```go +import "github.com/Azure/go-autorest/autorest/adal" + +oauthCfg, err := adal.NewOAuthConfig("https://login.chinacloudapi.cn", tenantID) +handle(err) + +spt, err := adal.NewServicePrincipalTokenWithSecret( + *oauthCfg, clientID, "https://management.chinacloudapi.cn/", &adal.ServicePrincipalTokenSecret{ClientSecret: secret}, +) +``` + +### `azidentity` + +A credential instance can acquire tokens for any audience. The audience for each token is determined by the client requesting it. Credentials require endpoint configuration only for sovereign or private clouds. The `azcore/cloud` package has predefined configuration for sovereign clouds such as Azure China: + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" +) + +clientOpts := azcore.ClientOptions{Cloud: cloud.AzureChina} + +cred, err := azidentity.NewClientSecretCredential( + tenantID, clientID, secret, &azidentity.ClientSecretCredentialOptions{ClientOptions: clientOpts}, +) +handle(err) +``` + +## Client secret authentication + +### `autorest/adal` + +```go +import ( + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" +) + +oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID) +handle(err) +spt, err := adal.NewServicePrincipalTokenWithSecret( + *oauthCfg, clientID, "https://management.azure.com/", &adal.ServicePrincipalTokenSecret{ClientSecret: secret}, +) +handle(err) + +client := subscriptions.NewClient() +client.Authorizer = autorest.NewBearerAuthorizer(spt) +``` + +### `azidentity` + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" +) + +cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, nil) +handle(err) + +client, err := armsubscriptions.NewClient(cred, nil) +handle(err) +``` + +## Client certificate authentication + +### `autorest/adal` + +```go +import ( + "os" + + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" +) +certData, err := os.ReadFile("./example.pfx") +handle(err) + +certificate, rsaPrivateKey, err := decodePkcs12(certData, "") +handle(err) + +oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID) +handle(err) + +spt, err := adal.NewServicePrincipalTokenFromCertificate( + *oauthConfig, clientID, certificate, rsaPrivateKey, "https://management.azure.com/", +) + +client := subscriptions.NewClient() +client.Authorizer = autorest.NewBearerAuthorizer(spt) +``` + +### `azidentity` + +```go +import ( + "os" + + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" +) + +certData, err := os.ReadFile("./example.pfx") +handle(err) + +certs, key, err := azidentity.ParseCertificates(certData, nil) +handle(err) + +cred, err = azidentity.NewClientCertificateCredential(tenantID, clientID, certs, key, nil) +handle(err) + +client, err := armsubscriptions.NewClient(cred, nil) +handle(err) +``` + +## Managed identity + +### `autorest/adal` + +```go +import ( + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" +) + +spt, err := adal.NewServicePrincipalTokenFromManagedIdentity("https://management.azure.com/", nil) +handle(err) + +client := subscriptions.NewClient() +client.Authorizer = autorest.NewBearerAuthorizer(spt) +``` + +### `azidentity` + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" +) + +cred, err := azidentity.NewManagedIdentityCredential(nil) +handle(err) + +client, err := armsubscriptions.NewClient(cred, nil) +handle(err) +``` + +### User-assigned identities + +`autorest/adal`: + +```go +import "github.com/Azure/go-autorest/autorest/adal" + +opts := &adal.ManagedIdentityOptions{ClientID: "..."} +spt, err := adal.NewServicePrincipalTokenFromManagedIdentity("https://management.azure.com/") +handle(err) +``` + +`azidentity`: + +```go +import "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + +opts := azidentity.ManagedIdentityCredentialOptions{ID: azidentity.ClientID("...")} +cred, err := azidentity.NewManagedIdentityCredential(&opts) +handle(err) +``` + +## Device code authentication + +### `autorest/adal` + +```go +import ( + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/adal" +) + +oauthClient := &http.Client{} +oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID) +handle(err) +resource := "https://management.azure.com/" +deviceCode, err := adal.InitiateDeviceAuth(oauthClient, *oauthCfg, clientID, resource) +handle(err) + +// display instructions, wait for the user to authenticate +fmt.Println(*deviceCode.Message) +token, err := adal.WaitForUserCompletion(oauthClient, deviceCode) +handle(err) + +spt, err := adal.NewServicePrincipalTokenFromManualToken(*oauthCfg, clientID, resource, *token) +handle(err) + +client := subscriptions.NewClient() +client.Authorizer = autorest.NewBearerAuthorizer(spt) +``` + +### `azidentity` + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" +) + +cred, err := azidentity.NewDeviceCodeCredential(nil) +handle(err) + +client, err := armsubscriptions.NewSubscriptionsClient(cred, nil) +handle(err) +``` + +`azidentity.DeviceCodeCredential` will guide a user through authentication, printing instructions to the console by default. The user prompt is customizable. For more information, see the [package documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DeviceCodeCredential). + +## Acquire a token + +### `autorest/adal` + +```go +import "github.com/Azure/go-autorest/autorest/adal" + +oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID) +handle(err) + +spt, err := adal.NewServicePrincipalTokenWithSecret( + *oauthCfg, clientID, "https://vault.azure.net", &adal.ServicePrincipalTokenSecret{ClientSecret: secret}, +) + +err = spt.Refresh() +if err == nil { + token := spt.Token +} +``` + +### `azidentity` + +In ordinary usage, application code doesn't need to request tokens from credentials directly. Azure SDK clients handle token acquisition and refreshing internally. However, applications may call `GetToken()` to do so. All credential types have this method. + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" +) + +cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, nil) +handle(err) + +tk, err := cred.GetToken( + context.TODO(), policy.TokenRequestOptions{Scopes: []string{"https://vault.azure.net/.default"}}, +) +if err == nil { + token := tk.Token +} +``` + +Note that `azidentity` credentials use the Microsoft Entra endpoint, which requires OAuth 2 scopes instead of the resource identifiers `autorest/adal` expects. For more information, see [Microsoft Entra ID documentation](https://learn.microsoft.com/entra/identity-platform/permissions-consent-overview). + +## Use azidentity credentials with older packages + +The [azidext module](https://pkg.go.dev/github.com/jongio/azidext/go/azidext) provides an adapter for `azidentity` credential types. The adapter enables using the credential types with older Azure SDK clients. For example: + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions" + "github.com/jongio/azidext/go/azidext" +) + +cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, nil) +handle(err) + +client := subscriptions.NewClient() +client.Authorizer = azidext.NewTokenCredentialAdapter(cred, []string{"https://management.azure.com//.default"}) +``` + + diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/README.md new file mode 100644 index 000000000..069bc688d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/README.md @@ -0,0 +1,247 @@ +# Azure Identity Client Module for Go + +The Azure Identity module provides Microsoft Entra ID ([formerly Azure Active Directory](https://learn.microsoft.com/entra/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) +| [Microsoft Entra ID documentation](https://learn.microsoft.com/entra/identity/) +| [Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/azidentity) + +# Getting started + +## Install the module + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Install the Azure Identity module: + +```sh +go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity +``` + +## Prerequisites + +- an [Azure subscription](https://azure.microsoft.com/free/) +- [Supported](https://aka.ms/azsdk/go/supported-versions) version of Go + +### Authenticating during local development + +When debugging and executing code locally, developers typically use their own accounts to authenticate calls to Azure services. The `azidentity` module supports authenticating through developer tools to simplify local development. + +#### Authenticating via the Azure CLI + +`DefaultAzureCredential` and `AzureCLICredential` can authenticate as the user +signed in to the [Azure CLI](https://learn.microsoft.com/cli/azure). To sign in to the Azure CLI, run `az login`. On a system with a default web browser, the Azure CLI will launch the browser to authenticate a user. + +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 + +A credential is a type which contains or can obtain the data needed for a +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 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 + +`DefaultAzureCredential` simplifies authentication while developing apps that deploy to Azure by combining credentials used in Azure hosting environments with credentials used in local development. For more information, see [DefaultAzureCredential overview][dac_overview]. + +## Managed Identity + +`DefaultAzureCredential` and `ManagedIdentityCredential` support +[managed identity authentication](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview) +in any hosting environment which supports managed identities, such as (this list is not exhaustive): +* [Azure App Service](https://learn.microsoft.com/azure/app-service/overview-managed-identity) +* [Azure Arc](https://learn.microsoft.com/azure/azure-arc/servers/managed-identity-authentication) +* [Azure Cloud Shell](https://learn.microsoft.com/azure/cloud-shell/msi-authorization) +* [Azure Kubernetes Service](https://learn.microsoft.com/azure/aks/use-managed-identity) +* [Azure Service Fabric](https://learn.microsoft.com/azure/service-fabric/concepts-managed-identity) +* [Azure Virtual Machines](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-use-vm-token) + +## Examples + +- [Authenticate with DefaultAzureCredential](#authenticate-with-defaultazurecredential "Authenticate with DefaultAzureCredential") +- [Define a custom authentication flow with ChainedTokenCredential](#define-a-custom-authentication-flow-with-chainedtokencredential "Define a custom authentication flow with ChainedTokenCredential") +- [Specify a user-assigned managed identity for DefaultAzureCredential](#specify-a-user-assigned-managed-identity-for-defaultazurecredential) + +### Authenticate with DefaultAzureCredential + +This example demonstrates authenticating a client from the `armresources` module with `DefaultAzureCredential`. + +```go +cred, err := azidentity.NewDefaultAzureCredential(nil) +if err != nil { + // handle error +} + +client := armresources.NewResourceGroupsClient("subscription ID", cred, nil) +``` + +### Specify a user-assigned managed identity for DefaultAzureCredential + +To configure `DefaultAzureCredential` to authenticate a user-assigned managed identity, set the environment variable `AZURE_CLIENT_ID` to the identity's client ID. + +### Define a custom authentication flow with `ChainedTokenCredential` + +`DefaultAzureCredential` is generally the quickest way to get started developing apps for Azure. For more advanced scenarios, `ChainedTokenCredential` links multiple credential instances to be tried sequentially when authenticating. It will try each chained credential in turn until one provides a token or fails to authenticate due to an error. + +The following example demonstrates creating a credential, which will attempt to authenticate using managed identity. It will fall back to authenticating via the Azure CLI when a managed identity is unavailable. + +```go +managed, err := azidentity.NewManagedIdentityCredential(nil) +if err != nil { + // handle error +} +azCLI, err := azidentity.NewAzureCLICredential(nil) +if err != nil { + // handle error +} +chain, err := azidentity.NewChainedTokenCredential([]azcore.TokenCredential{managed, azCLI}, nil) +if err != nil { + // handle error +} + +client := armresources.NewResourceGroupsClient("subscription ID", chain, nil) +``` + +## Credential Types + +### Credential chains + +|Credential|Usage|Reference +|-|-|- +|[DefaultAzureCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential)|Simplified authentication experience for getting started developing Azure apps|[DefaultAzureCredential overview][dac_overview]| +|[ChainedTokenCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ChainedTokenCredential)|Define custom authentication flows, composing multiple credentials|[ChainedTokenCredential overview][ctc_overview]| + +### Authenticating Azure-Hosted Applications + +|Credential|Usage +|-|- +|[EnvironmentCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#EnvironmentCredential)|Authenticate a service principal or user configured by environment variables +|[ManagedIdentityCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ManagedIdentityCredential)|Authenticate the managed identity of an Azure resource +|[WorkloadIdentityCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#WorkloadIdentityCredential)|Authenticate a workload identity on Kubernetes + +### Authenticating Service Principals + +|Credential|Usage +|-|- +|[AzurePipelinesCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#AzurePipelinesCredential)|Authenticate an Azure Pipelines [service connection](https://learn.microsoft.com/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml) +|[ClientAssertionCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ClientAssertionCredential)|Authenticate a service principal with a signed client assertion +|[ClientCertificateCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ClientCertificateCredential)|Authenticate a service principal with a certificate +|[ClientSecretCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ClientSecretCredential)|Authenticate a service principal with a secret + +### Authenticating Users + +|Credential|Usage +|-|- +|[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 + +### Authenticating via Development Tools + +|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 + +`DefaultAzureCredential` and `EnvironmentCredential` can be configured with environment variables. Each type of authentication requires values for specific variables: + +### Service principal with secret + +|variable name|value +|-|- +|`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 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 + +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 Microsoft Entra errors, see the Microsoft Entra [error code documentation](https://learn.microsoft.com/entra/identity-platform/reference-error-codes). + +### Logging + +This module uses the classification-based logging implementation in `azcore`. To enable console logging for all SDK modules, set `AZURE_SDK_GO_LOGGING` to `all`. Use the `azcore/log` package to control log event output or to enable logs for `azidentity` only. For example: +```go +import azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log" + +// print log output to stdout +azlog.SetListener(func(event azlog.Event, s string) { + fmt.Println(s) +}) + +// include only azidentity credential logs +azlog.SetEvents(azidentity.EventAuthentication) +``` + +Credentials log basic information only, such as `GetToken` success or failure and errors. These log entries don't contain authentication secrets but may contain sensitive information. + +## Next steps + +Client and management modules listed on the [Azure SDK releases page](https://azure.github.io/azure-sdk/releases/latest/go.html) support authenticating with `azidentity` credential types. You can learn more about using these libraries in their documentation, which is linked from the release page. + +## Provide Feedback + +If you encounter bugs or have suggestions, please +[open an issue](https://github.com/Azure/azure-sdk-for-go/issues). + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. +For details, visit [https://cla.microsoft.com](https://cla.microsoft.com). + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only +need to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information, see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. + + +[ctc_overview]: https://aka.ms/azsdk/go/identity/credential-chains#chainedtokencredential-overview +[dac_overview]: https://aka.ms/azsdk/go/identity/credential-chains#defaultazurecredential-overview + + diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD new file mode 100644 index 000000000..da2094e36 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD @@ -0,0 +1,56 @@ +## Token caching in the Azure Identity client module + +Token caching helps apps: + +- Improve their resilience and performance. +- Reduce the number of requests sent to Microsoft Entra ID to obtain access tokens. +- Reduce the number of times users are prompted to authenticate. + +When an app needs to access a protected Azure resource, it typically needs to obtain an access token from Entra ID by sending an HTTP request and sometimes prompting a user to authenticate interactively. Credentials with caches (see [the below table](#credentials-supporting-token-caching) for a list) store access tokens either [in memory](#in-memory-token-caching) or, optionally, [on disk](#persistent-token-caching). These credentials return cached tokens whenever possible, to avoid unnecessary token requests or user interaction. Both cache implementations are safe for concurrent use. + +#### Caching can't be disabled + +Whether a credential caches tokens isn't configurable. If a credential has a cache of either kind, it requests a new token only when it can't provide one from its cache. Azure SDK service clients have an additional, independent layer of in-memory token caching, to prevent redundant token requests. This cache works with any credential type, even a custom implementation defined outside the Azure SDK, and can't be disabled. Disabling token caching is therefore impossible when using Azure SDK clients or most `azidentity` credential types. However, in-memory caches can be cleared by constructing new credential and client instances. + +### In-memory token caching + +Credential types that support caching store tokens in memory by default and require no configuration to do so. Each instance of these types has its own cache, and two credential instances never share an in-memory cache. + +### Persistent token caching + +Some credential types support opt-in persistent token caching (see [the below table](#credentials-supporting-token-caching) for a list). This feature enables credentials to store and retrieve tokens across process executions, so an application doesn't need to authenticate every time it runs. + +Persistent caches are encrypted at rest using a mechanism that depends on the operating system: + +| 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 + +The following table indicates the state of in-memory and persistent caching in each credential type. + +**Note:** in-memory caching is enabled by default for every type supporting it. Persistent token caching must be enabled explicitly. See the [package documentation][user_example] for an example showing how to do this for credential types authenticating users. For types that authenticate service principals, set the `Cache` field on the constructor's options as shown in [this example][sp_example]. + +| Credential | In-memory token caching | Persistent token caching | +| ------------------------------ | ------------------------------------------------------------------- | ------------------------ | +| `AzureCLICredential` | Not Supported | Not Supported | +| `AzureDeveloperCLICredential` | Not Supported | Not Supported | +| `AzurePipelinesCredential` | Supported | 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 | Not Supported | +| `WorkloadIdentityCredential` | Supported | Supported | + +[sp_example]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#example-package-PersistentServicePrincipalAuthentication +[user_example]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#example-package-PersistentUserAuthentication diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md new file mode 100644 index 000000000..838601d69 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TROUBLESHOOTING.md @@ -0,0 +1,249 @@ +# Troubleshoot Azure Identity authentication issues + +This troubleshooting guide covers failure investigation techniques, common errors for the credential types in the `azidentity` module, and mitigation steps to resolve these errors. + +## Table of contents + +- [Handle azidentity errors](#handle-azidentity-errors) + - [Permission issues](#permission-issues) +- [Find relevant information in errors](#find-relevant-information-in-errors) +- [Enable and configure logging](#enable-and-configure-logging) +- [Troubleshoot persistent token caching issues](#troubleshoot-persistent-token-caching-issues) +- [Troubleshoot AzureCLICredential authentication issues](#troubleshoot-azureclicredential-authentication-issues) +- [Troubleshoot AzureDeveloperCLICredential authentication issues](#troubleshoot-azuredeveloperclicredential-authentication-issues) +- [Troubleshoot AzurePipelinesCredential authentication issues](#troubleshoot-azurepipelinescredential-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) +- [Troubleshoot EnvironmentCredential authentication issues](#troubleshoot-environmentcredential-authentication-issues) +- [Troubleshoot ManagedIdentityCredential authentication issues](#troubleshoot-managedidentitycredential-authentication-issues) + - [Azure App Service and Azure Functions managed identity](#azure-app-service-and-azure-functions-managed-identity) + - [Azure Virtual Machine managed identity](#azure-virtual-machine-managed-identity) +- [Troubleshoot WorkloadIdentityCredential authentication issues](#troubleshoot-workloadidentitycredential-authentication-issues) +- [Get additional help](#get-additional-help) + +## 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 Microsoft Entra ID. Depending on the application, these errors may or may not be recoverable. + +### Permission issues + +Service client errors with a status code of 401 or 403 often indicate that authentication succeeded but the caller doesn't have permission to access the specified API. Check the service documentation to determine which RBAC roles are needed for the request, and ensure the authenticated user or service principal has the appropriate role assignments. + +## Find relevant information in errors + +Authentication errors can include responses from Microsoft Entra ID and often contain information helpful in diagnosis. Consider the following error message: + +``` +ClientSecretCredential authentication failed +POST https://login.microsoftonline.com/3c631bb7-a9f7-4343-a5ba-a615913/oauth2/v2.0/token +-------------------------------------------------------------------------------- +RESPONSE 401 Unauthorized +-------------------------------------------------------------------------------- +{ + "error": "invalid_client", + "error_description": "AADSTS7000215: Invalid client secret provided. Ensure the secret being sent in the request is the client secret value, not the client secret ID, for a secret added to app '86be4c01-505b-45e9-bfc0-9b825fd84'.\r\nTrace ID: 03da4b8e-5ffe-48ca-9754-aff4276f0100\r\nCorrelation ID: 7b12f9bb-2eef-42e3-ad75-eee69ec9088d\r\nTimestamp: 2022-03-02 18:25:26Z", + "error_codes": [ + 7000215 + ], + "timestamp": "2022-03-02 18:25:26Z", + "trace_id": "03da4b8e-5ffe-48ca-9754-aff4276f0100", + "correlation_id": "7b12f9bb-2eef-42e3-ad75-eee69ec9088d", + "error_uri": "https://login.microsoftonline.com/error?code=7000215" +} +-------------------------------------------------------------------------------- +``` + +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`. + +- __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/entra/identity-platform/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 Microsoft Entra failures. + +### Enable and configure logging + +`azidentity` provides the same logging capabilities as the rest of the Azure SDK. The simplest way to see the logs to help debug authentication issues is to print credential logs to the console. +```go +import azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log" + +// print log output to stdout +azlog.SetListener(func(event azlog.Event, s string) { + fmt.Println(s) +}) + +// include only azidentity credential logs +azlog.SetEvents(azidentity.EventAuthentication) +``` + + +## Troubleshoot DefaultAzureCredential authentication issues + +| Error |Description| Mitigation | +|---|---|---| +|"DefaultAzureCredential failed to acquire a token"|No credential in the `DefaultAzureCredential` chain provided a token|
  • [Enable logging](#enable-and-configure-logging) to get further diagnostic information.
  • Consult the troubleshooting guide for underlying credential types for more information.
    • [EnvironmentCredential](#troubleshoot-environmentcredential-authentication-issues)
    • [ManagedIdentityCredential](#troubleshoot-managedidentitycredential-authentication-issues)
    • [AzureCLICredential](#troubleshoot-azureclicredential-authentication-issues)
    | +|Error from the client with a status code of 401 or 403|Authentication succeeded but the authorizing Azure service responded with a 401 (Unauthorized), or 403 (Forbidden) status code|
    • [Enable logging](#enable-and-configure-logging) to determine which credential in the chain returned the authenticating token.
    • If an unexpected credential is returning a token, check application configuration such as environment variables.
    • Ensure the correct role is assigned to the authenticated identity. For example, a service specific role rather than the subscription Owner role.
    | +|"managed identity timed out"|`DefaultAzureCredential` sets a short timeout on its first managed identity authentication attempt to prevent very long timeouts during local development when no managed identity is available. That timeout causes this error in production when an application requests a token before the hosting environment is ready to provide one.|Use [ManagedIdentityCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#ManagedIdentityCredential) directly, at least in production. It doesn't set a timeout on its authentication attempts.| +|invalid AZURE_TOKEN_CREDENTIALS value "..."|AZURE_TOKEN_CREDENTIALS has an unexpected value|Specify a valid value as described in [DefaultAzureCredential documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential) + +## Troubleshoot EnvironmentCredential authentication issues + +| Error Message |Description| Mitigation | +|---|---|---| +|Missing or incomplete environment variable configuration|A valid combination of environment variables wasn't set|Ensure the appropriate environment variables are set for the intended authentication method as described in the [module documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#EnvironmentCredential)| + + +## Troubleshoot ClientSecretCredential authentication issues + +| 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 [Microsoft Entra ID documentation](https://learn.microsoft.com/entra/identity-platform/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/entra/identity-platform/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/entra/identity-platform/howto-create-service-principal-portal).| + + +## 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 [Microsoft Entra ID documentation](https://learn.microsoft.com/entra/identity-platform/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/entra/identity-platform/howto-create-service-principal-portal).| + + +## Troubleshoot ManagedIdentityCredential authentication issues + +`ManagedIdentityCredential` is designed to work on a variety of Azure hosts support managed identity. Configuration and troubleshooting vary from host to host. The below table lists the Azure hosts that can be assigned a managed identity and are supported by `ManagedIdentityCredential`. + +|Host Environment| | | +|---|---|---| +|Azure Virtual Machines and Scale Sets|[Configuration](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm)|[Troubleshooting](#azure-virtual-machine-managed-identity)| +|Azure App Service and Azure Functions|[Configuration](https://learn.microsoft.com/azure/app-service/overview-managed-identity)|[Troubleshooting](#azure-app-service-and-azure-functions-managed-identity)| +|Azure Arc|[Configuration](https://learn.microsoft.com/azure/azure-arc/servers/managed-identity-authentication)|| +|Azure Service Fabric|[Configuration](https://learn.microsoft.com/azure/service-fabric/concepts-managed-identity)|| + +### Azure Virtual Machine managed identity + +| Error Message |Description| Mitigation | +|---|---|---| +|The requested identity hasn’t been assigned to this resource.|The IMDS endpoint responded with a status code of 400, indicating the requested identity isn’t assigned to the VM.|If using a user assigned identity, ensure the specified ID is correct.

    If using a system assigned identity, make sure it has been enabled as described in [managed identity documentation](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm#enable-system-assigned-managed-identity-on-an-existing-vm).| +|The request failed due to a gateway error.|The request to the IMDS endpoint failed due to a gateway error, 502 or 504 status code.|IMDS doesn't support requests via proxy or gateway. Disable proxies or gateways running on the VM for requests to the IMDS endpoint `http://169.254.169.254`| +|No response received from the managed identity endpoint.|No response was received for the request to IMDS or the request timed out.|

    • Ensure the VM is configured for managed identity as described in [managed identity documentation](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm).
    • Verify the IMDS endpoint is reachable on the VM. See [below](#verify-imds-is-available-on-the-vm) for instructions.
    | +|Multiple attempts failed to obtain a token from the managed identity endpoint.|The credential has exhausted its retries for a token request.|
    • Refer to the error message for more details on specific failures.
    • Ensure the VM is configured for managed identity as described in [managed identity documentation](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/qs-configure-portal-windows-vm).
    • Verify the IMDS endpoint is reachable on the VM. See [below](#verify-imds-is-available-on-the-vm) for instructions.
    | + +#### Verify IMDS is available on the VM + +If you have access to the VM, you can use `curl` to verify the managed identity endpoint is available. + +```sh +curl 'http://169.254.169.254/metadata/identity/oauth2/token?resource=https://management.core.windows.net&api-version=2018-02-01' -H "Metadata: true" +``` + +> This command's output will contain an access token and SHOULD NOT BE SHARED, to avoid compromising account security. + +### Azure App Service and Azure Functions managed identity + +| Error Message |Description| Mitigation | +|---|---|---| +|Get "`http://169.254.169.254/...`" i/o timeout|The App Service host hasn't set environment variables for managed identity configuration.|
    • Ensure the App Service is configured for managed identity as described in [App Service documentation](https://learn.microsoft.com/azure/app-service/overview-managed-identity).
    • Verify the App Service environment is properly configured and the managed identity endpoint is available. See [below](#verify-the-app-service-managed-identity-endpoint-is-available) for instructions.
    | + +#### Verify the App Service managed identity endpoint is available + +If you can SSH into the App Service, you can verify managed identity is available in the environment. First ensure the environment variables `IDENTITY_ENDPOINT` and `IDENTITY_SECRET` are set. Then you can verify the managed identity endpoint is available using `curl`. + +```sh +curl "$IDENTITY_ENDPOINT?resource=https://management.core.windows.net&api-version=2019-08-01" -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" +``` + +> This command's output will contain an access token and SHOULD NOT BE SHARED, to avoid compromising account security. + + +## Troubleshoot AzureCLICredential authentication issues + +| Error Message |Description| Mitigation | +|---|---|---| +|Azure CLI not found on path|The Azure CLI isn’t installed or isn't on the application's path.|
    • Ensure the Azure CLI is installed as described in [Azure CLI documentation](https://learn.microsoft.com/cli/azure/install-azure-cli).
    • Validate the installation location is in the application's `PATH` environment variable.
    | +|Please run 'az login' to set up account|No account is currently logged into the Azure CLI, or the login has expired.|
    • Run `az login` to log into the Azure CLI. More information about Azure CLI authentication is available in the [Azure CLI documentation](https://learn.microsoft.com/cli/azure/authenticate-azure-cli).
    • Verify that the Azure CLI can obtain tokens. See [below](#verify-the-azure-cli-can-obtain-tokens) for instructions.
    | +|Subscription "[your subscription]" contains invalid characters. If this is the name of a subscription, use its ID instead|The subscription name contains a character that may not be safe in a command line.|Use the subscription's ID instead of its name. You can get this from the Azure CLI: `az account show --name "[your subscription]" --query "id"` + +#### Verify the Azure CLI can obtain tokens + +You can manually verify that the Azure CLI can authenticate and obtain tokens. First, use the `account` command to verify the logged in account. + +```azurecli +az account show +``` + +Once you've verified the Azure CLI is using the correct account, you can validate that it's able to obtain tokens for that account. + +```azurecli +az account get-access-token --output json --resource https://management.core.windows.net +``` + +> This command's output will contain an access token and SHOULD NOT BE SHARED, to avoid compromising account security. + + +## 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.|
    • 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).
    • Validate the installation location has been added to the `PATH` environment variable.
    | +|Please run "azd auth login"|No account is logged into the Azure Developer CLI, or the login has expired.|
    • Log in to the Azure Developer CLI using the `azd login` command.
    • 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).
    | + +#### 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. + + +## Troubleshoot `WorkloadIdentityCredential` authentication issues + +| Error Message |Description| Mitigation | +|---|---|---| +|no client ID/tenant ID/token file specified|Incomplete configuration|In most cases these values are provided via environment variables set by Azure Workload Identity.
    • If your application runs on Azure Kubernetes Service (AKS) or a cluster that has deployed the Azure Workload Identity admission webhook, check pod labels and service account configuration. See the [AKS documentation](https://learn.microsoft.com/azure/aks/workload-identity-deploy-cluster#disable-workload-identity) and [Azure Workload Identity troubleshooting guide](https://azure.github.io/azure-workload-identity/docs/troubleshooting.html) for more details.
    • If your application isn't running on AKS or your cluster hasn't deployed the Workload Identity admission webhook, set these values in `WorkloadIdentityCredentialOptions` + + +## Troubleshoot AzurePipelinesCredential authentication issues + +| Error Message |Description| Mitigation | +|---|---|---| +| AADSTS900023: Specified tenant identifier 'some tenant ID' is neither a valid DNS name, nor a valid external domain.|The `tenantID` argument to `NewAzurePipelinesCredential` is incorrect| Verify the tenant ID. It must identify the tenant of the user-assigned managed identity or service principal configured for the service connection.| +| No service connection found with identifier |The `serviceConnectionID` argument to `NewAzurePipelinesCredential` is incorrect| Verify the service connection ID. This parameter refers to the `resourceId` of the Azure Service Connection. It can also be found in the query string of the service connection's configuration in Azure DevOps. [Azure Pipelines documentation](https://learn.microsoft.com/azure/devops/pipelines/library/service-endpoints?view=azure-devops&tabs=yaml) has more information about service connections.| +|401 (Unauthorized) response from OIDC endpoint|The `systemAccessToken` argument to `NewAzurePipelinesCredential` is incorrect|Check pipeline configuration. This value comes from the predefined variable `System.AccessToken` [as described in Azure Pipelines documentation](https://learn.microsoft.com/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken).| + +## Troubleshoot persistent token caching issues + +### macOS + +[azidentity/cache](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache) encrypts persistent caches with the system Keychain on macOS. You may see build and runtime errors there because calling the Keychain API requires cgo and macOS prohibits Keychain access in some scenarios. + +#### Build errors + +Build errors about undefined `accessor` symbols indicate that cgo wasn't enabled. For example: +``` +$ GOOS=darwin go build +# github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache +../../go/pkg/mod/github.com/!azure/azure-sdk-for-go/sdk/azidentity/cache@v0.3.0/darwin.go:18:19: undefined: accessor.New +../../go/pkg/mod/github.com/!azure/azure-sdk-for-go/sdk/azidentity/cache@v0.3.0/darwin.go:18:38: undefined: accessor.WithAccount +``` + +Try `go build` again with `CGO_ENABLED=1`. You may need to install native build tools. + +#### Runtime errors + +macOS prohibits Keychain access from environments without a GUI such as SSH sessions. If your application calls the persistent cache constructor ([cache.New](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache#New)) from an SSH session on a macOS host, you'll see an error like +`persistent storage isn't available due to error "User interaction is not allowed. (-25308)"`. This doesn't mean authentication is impossible, only that credentials can't persist data and the application must reauthenticate the next time it runs. + +## Get additional help + +Additional information on ways to reach out for support can be found in [SUPPORT.md](https://github.com/Azure/azure-sdk-for-go/blob/main/SUPPORT.md). diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json new file mode 100644 index 000000000..1646ff911 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json @@ -0,0 +1,6 @@ +{ + "AssetsRepo": "Azure/azure-sdk-assets", + "AssetsRepoPrefixPath": "go", + "TagPrefix": "go/azidentity", + "Tag": "go/azidentity_530ea4279b" +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/authentication_record.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/authentication_record.go new file mode 100644 index 000000000..840a71469 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/authentication_record.go @@ -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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azidentity.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azidentity.go new file mode 100644 index 000000000..bd196ddd3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azidentity.go @@ -0,0 +1,223 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + + "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/managedidentity" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/public" +) + +const ( + azureAdditionallyAllowedTenants = "AZURE_ADDITIONALLY_ALLOWED_TENANTS" + azureAuthorityHost = "AZURE_AUTHORITY_HOST" + azureClientCertificatePassword = "AZURE_CLIENT_CERTIFICATE_PASSWORD" + azureClientCertificatePath = "AZURE_CLIENT_CERTIFICATE_PATH" + azureClientID = "AZURE_CLIENT_ID" + azureClientSecret = "AZURE_CLIENT_SECRET" + azureFederatedTokenFile = "AZURE_FEDERATED_TOKEN_FILE" + azurePassword = "AZURE_PASSWORD" + azureRegionalAuthorityName = "AZURE_REGIONAL_AUTHORITY_NAME" + azureTenantID = "AZURE_TENANT_ID" + azureUsername = "AZURE_USERNAME" + + organizationsTenantID = "organizations" + developerSignOnClientID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46" + defaultSuffix = "/.default" + + scopeLogFmt = "%s.GetToken() acquired a token for scope %q" + + traceNamespace = "Microsoft.Entra" + traceOpGetToken = "GetToken" + traceOpAuthenticate = "Authenticate" +) + +var ( + // capability CP1 indicates the client application is capable of handling CAE claims challenges + cp1 = []string{"CP1"} + 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") +) + +// Cache represents a persistent cache that makes authentication data available across processes. +// Construct one with [github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache.New]. This package's +// [persistent user authentication example] shows how to use a persistent cache to reuse user +// logins across application runs. For service principal credential types such as +// [ClientCertificateCredential], simply set the Cache field on the credential options. +// +// [persistent user authentication example]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#example-package-PersistentUserAuthentication +type Cache = internal.Cache + +// setAuthorityHost initializes the authority host for credentials. Precedence is: +// 1. cloud.Configuration.ActiveDirectoryAuthorityHost value set by user +// 2. value of AZURE_AUTHORITY_HOST +// 3. default: Azure Public Cloud +func setAuthorityHost(cc cloud.Configuration) (string, error) { + host := cc.ActiveDirectoryAuthorityHost + if host == "" { + if len(cc.Services) > 0 { + return "", errors.New("missing ActiveDirectoryAuthorityHost for specified cloud") + } + host = cloud.AzurePublic.ActiveDirectoryAuthorityHost + if envAuthorityHost := os.Getenv(azureAuthorityHost); envAuthorityHost != "" { + host = envAuthorityHost + } + } + u, err := url.Parse(host) + if err != nil { + return "", err + } + if u.Scheme != "https" { + return "", errors.New("cannot use an authority host without https") + } + return host, nil +} + +// resolveAdditionalTenants returns a copy of tenants, simplified when tenants contains a wildcard +func resolveAdditionalTenants(tenants []string) []string { + if len(tenants) == 0 { + return nil + } + for _, t := range tenants { + // a wildcard makes all other values redundant + if t == "*" { + return []string{"*"} + } + } + cp := make([]string, len(tenants)) + copy(cp, tenants) + return cp +} + +// resolveTenant returns the correct tenant for a token request, or "" when the calling credential doesn't +// have an explicitly configured tenant and the caller didn't specify a tenant for the token request. +// +// - defaultTenant: tenant set when constructing the credential, if any. "" is valid for credentials +// having an optional or implicit tenant such as dev tool and interactive user credentials. Those +// default to the tool's configured tenant or the user's home tenant, respectively. +// - specified: tenant specified for this token request i.e., TokenRequestOptions.TenantID. May be "". +// - credName: name of the calling credential type; for error messages +// - additionalTenants: optional allow list of tenants the credential may acquire tokens from in +// addition to defaultTenant i.e., the credential's AdditionallyAllowedTenants option +func resolveTenant(defaultTenant, specified, credName string, additionalTenants []string) (string, error) { + if specified == "" || specified == defaultTenant { + return defaultTenant, nil + } + if defaultTenant == "adfs" { + return "", errors.New("ADFS doesn't support tenants") + } + if !validTenantID(specified) { + return "", errInvalidTenantID + } + for _, t := range additionalTenants { + if t == "*" || t == specified { + return specified, nil + } + } + if len(additionalTenants) == 0 { + switch defaultTenant { + case "", organizationsTenantID: + // The application didn't specify a tenant or allow list when constructing the credential. Allow the + // tenant specified for this token request because we have nothing to compare it to (i.e., it vacuously + // satisfies the credential's configuration); don't know whether the application is multitenant; and + // don't want to return an error in the common case that the specified tenant matches the credential's + // default tenant determined elsewhere e.g., in some dev tool's configuration. + return specified, nil + } + } + 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) +} + +func alphanumeric(r rune) bool { + return ('0' <= r && r <= '9') || ('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z') +} + +func validTenantID(tenantID string) bool { + if len(tenantID) < 1 { + return false + } + for _, r := range tenantID { + if !(alphanumeric(r) || r == '.' || r == '-') { + return false + } + } + return true +} + +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 + } + if r.Body != nil && r.Body != http.NoBody { + // create a rewindable body from the existing body as required + var body io.ReadSeekCloser + if rsc, ok := r.Body.(io.ReadSeekCloser); ok { + body = rsc + } else { + b, err := io.ReadAll(r.Body) + if err != nil { + return nil, err + } + body = streaming.NopCloser(bytes.NewReader(b)) + } + err = req.SetBody(body, r.Header.Get("Content-Type")) + if err != nil { + return nil, err + } + } + + // 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 + } + return resp, err +} + +// enables fakes for test scenarios +type msalConfidentialClient interface { + AcquireTokenSilent(ctx context.Context, scopes []string, options ...confidential.AcquireSilentOption) (confidential.AuthResult, error) + AcquireTokenByAuthCode(ctx context.Context, code string, redirectURI string, scopes []string, options ...confidential.AcquireByAuthCodeOption) (confidential.AuthResult, error) + AcquireTokenByCredential(ctx context.Context, scopes []string, options ...confidential.AcquireByCredentialOption) (confidential.AuthResult, error) + 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) + AcquireTokenByUsernamePassword(ctx context.Context, scopes []string, username string, password string, options ...public.AcquireByUsernamePasswordOption) (public.AuthResult, error) + AcquireTokenByDeviceCode(ctx context.Context, scopes []string, options ...public.AcquireByDeviceCodeOption) (public.DeviceCode, error) + AcquireTokenByAuthCode(ctx context.Context, code string, redirectURI string, scopes []string, options ...public.AcquireByAuthCodeOption) (public.AuthResult, error) + AcquireTokenInteractive(ctx context.Context, scopes []string, options ...public.AcquireInteractiveOption) (public.AuthResult, error) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go new file mode 100644 index 000000000..6944152c9 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_cli_credential.go @@ -0,0 +1,156 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "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 credNameAzureCLI = "AzureCLICredential" + +// AzureCLICredentialOptions contains optional parameters for AzureCLICredential. +type AzureCLICredentialOptions struct { + // AdditionallyAllowedTenants specifies tenants to which the credential may authenticate, in addition to + // TenantID. When TenantID is empty, this option has no effect and the credential will authenticate to + // any requested tenant. Add the wildcard value "*" to allow the credential to authenticate to any tenant. + 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 + + // inDefaultChain is true when the credential is part of DefaultAzureCredential + inDefaultChain bool + // exec is used by tests to fake invoking az + exec executor +} + +// AzureCLICredential authenticates as the identity logged in to the Azure CLI. +type AzureCLICredential struct { + mu *sync.Mutex + opts AzureCLICredentialOptions +} + +// NewAzureCLICredential constructs an AzureCLICredential. Pass nil to accept default options. +func NewAzureCLICredential(options *AzureCLICredentialOptions) (*AzureCLICredential, error) { + cp := AzureCLICredentialOptions{} + if options != nil { + cp = *options + } + for _, r := range cp.Subscription { + if !(alphanumeric(r) || r == '-' || r == '_' || r == ' ' || r == '.') { + return nil, fmt.Errorf( + "%s: Subscription %q contains invalid characters. If this is the name of a subscription, use its ID instead", + credNameAzureCLI, + cp.Subscription, + ) + } + } + if cp.TenantID != "" && !validTenantID(cp.TenantID) { + return nil, errInvalidTenantID + } + if cp.exec == nil { + cp.exec = shellExec + } + cp.AdditionallyAllowedTenants = resolveAdditionalTenants(cp.AdditionallyAllowedTenants) + return &AzureCLICredential{mu: &sync.Mutex{}, opts: cp}, nil +} + +// 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 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 at, err + } + // 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(opts.Scopes[0], defaultSuffix) + command := "az account get-access-token -o json --resource " + resource + tenantArg := "" + if tenant != "" { + tenantArg = " --tenant " + tenant + command += tenantArg + } + if c.opts.Subscription != "" { + // subscription needs quotes because it may contain spaces + command += ` --subscription "` + c.opts.Subscription + `"` + } + if opts.Claims != "" { + encoded := base64.StdEncoding.EncodeToString([]byte(opts.Claims)) + return at, fmt.Errorf( + "%s.GetToken(): Azure CLI requires multifactor authentication or additional claims. Run this command then retry the operation: az login%s --claims-challenge %s", + credNameAzureCLI, + tenantArg, + encoded, + ) + } + + c.mu.Lock() + defer c.mu.Unlock() + + b, err := c.opts.exec(ctx, credNameAzureCLI, command) + if err == nil { + at, err = c.createAccessToken(b) + } + if err != nil { + err = unavailableIfInDAC(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 +} + +func (c *AzureCLICredential) createAccessToken(tk []byte) (azcore.AccessToken, error) { + t := struct { + AccessToken string `json:"accessToken"` + Expires_On int64 `json:"expires_on"` + ExpiresOn string `json:"expiresOn"` + }{} + err := json.Unmarshal(tk, &t) + if err != nil { + return azcore.AccessToken{}, err + } + + exp := time.Unix(t.Expires_On, 0) + if t.Expires_On == 0 { + exp, err = time.ParseInLocation("2006-01-02 15:04:05.999999", t.ExpiresOn, time.Local) + if err != nil { + return azcore.AccessToken{}, fmt.Errorf("%s: error parsing token expiration time %q: %v", credNameAzureCLI, t.ExpiresOn, err) + } + } + + converted := azcore.AccessToken{ + Token: t.AccessToken, + ExpiresOn: exp.UTC(), + } + return converted, nil +} + +var _ azcore.TokenCredential = (*AzureCLICredential)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go new file mode 100644 index 000000000..f97bf95df --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_developer_cli_credential.go @@ -0,0 +1,148 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "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" + mfaRequired = "Azure Developer CLI requires multifactor authentication or additional claims" +) + +// AzureDeveloperCLICredentialOptions contains optional parameters for AzureDeveloperCLICredential. +type AzureDeveloperCLICredentialOptions struct { + // AdditionallyAllowedTenants specifies tenants to which the credential may authenticate, in addition to + // TenantID. When TenantID is empty, this option has no effect and the credential will authenticate to + // any requested tenant. Add the wildcard value "*" to allow the credential to authenticate to any tenant. + 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 + // exec is used by tests to fake invoking azd + exec executor +} + +// 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.exec == nil { + cp.exec = shellExec + } + 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") + } + command := "azd auth token -o json --no-prompt" + for _, scope := range opts.Scopes { + if !validScope(scope) { + return at, fmt.Errorf("%s.GetToken(): invalid scope %q", credNameAzureDeveloperCLI, scope) + } + command += " --scope " + scope + } + tenant, err := resolveTenant(c.opts.TenantID, opts.TenantID, credNameAzureDeveloperCLI, c.opts.AdditionallyAllowedTenants) + if err != nil { + return at, err + } + if tenant != "" { + command += " --tenant-id " + tenant + } + commandNoClaims := command + if opts.Claims != "" { + encoded := base64.StdEncoding.EncodeToString([]byte(opts.Claims)) + command += " --claims " + encoded + } + + c.mu.Lock() + defer c.mu.Unlock() + + b, err := c.opts.exec(ctx, credNameAzureDeveloperCLI, command) + if err == nil { + at, err = c.createAccessToken(b) + } + if err != nil { + msg := err.Error() + switch { + case strings.Contains(msg, "unknown flag: --claims"): + err = newAuthenticationFailedError( + credNameAzureDeveloperCLI, + mfaRequired+", however the installed version doesn't support this. Upgrade to version 1.18.1 or later", + nil, + ) + case opts.Claims != "": + err = newAuthenticationFailedError( + credNameAzureDeveloperCLI, + mfaRequired+". Run this command then retry the operation: "+commandNoClaims, + nil, + ) + case strings.Contains(msg, "azd auth login"): + err = newCredentialUnavailableError(credNameAzureDeveloperCLI, `please run "azd auth login" from a command prompt to authenticate before using this credential`) + } + err = unavailableIfInDAC(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 +} + +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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_pipelines_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_pipelines_credential.go new file mode 100644 index 000000000..a4b8ab6f4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azure_pipelines_credential.go @@ -0,0 +1,157 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "os" + + "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 ( + credNameAzurePipelines = "AzurePipelinesCredential" + oidcAPIVersion = "7.1" + systemOIDCRequestURI = "SYSTEM_OIDCREQUESTURI" + xMsEdgeRef = "x-msedge-ref" + xVssE2eId = "x-vss-e2eid" +) + +// AzurePipelinesCredential authenticates with workload identity federation in an Azure Pipeline. See +// [Azure Pipelines documentation] for more information. +// +// [Azure Pipelines documentation]: https://learn.microsoft.com/azure/devops/pipelines/library/connect-to-azure?view=azure-devops#create-an-azure-resource-manager-service-connection-that-uses-workload-identity-federation +type AzurePipelinesCredential struct { + connectionID, oidcURI, systemAccessToken string + cred *ClientAssertionCredential +} + +// AzurePipelinesCredentialOptions contains optional parameters for AzurePipelinesCredential. +type AzurePipelinesCredentialOptions struct { + azcore.ClientOptions + + // 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 in which the + // application is registered. + AdditionallyAllowedTenants []string + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // 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 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 +} + +// NewAzurePipelinesCredential is the constructor for AzurePipelinesCredential. +// +// - tenantID: tenant ID of the service principal federated with the service connection +// - clientID: client ID of that service principal +// - serviceConnectionID: ID of the service connection to authenticate +// - systemAccessToken: security token for the running build. See [Azure Pipelines documentation] for +// an example showing how to get this value. +// +// [Azure Pipelines documentation]: https://learn.microsoft.com/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#systemaccesstoken +func NewAzurePipelinesCredential(tenantID, clientID, serviceConnectionID, systemAccessToken string, options *AzurePipelinesCredentialOptions) (*AzurePipelinesCredential, error) { + if !validTenantID(tenantID) { + return nil, errInvalidTenantID + } + if clientID == "" { + return nil, errors.New("no client ID specified") + } + if serviceConnectionID == "" { + return nil, errors.New("no service connection ID specified") + } + if systemAccessToken == "" { + return nil, errors.New("no system access token specified") + } + u := os.Getenv(systemOIDCRequestURI) + if u == "" { + return nil, fmt.Errorf("no value for environment variable %s. This should be set by Azure Pipelines", systemOIDCRequestURI) + } + a := AzurePipelinesCredential{ + connectionID: serviceConnectionID, + oidcURI: u, + systemAccessToken: systemAccessToken, + } + if options == nil { + options = &AzurePipelinesCredentialOptions{} + } + // these headers are useful to the DevOps team when debugging OIDC error responses + options.ClientOptions.Logging.AllowedHeaders = append(options.ClientOptions.Logging.AllowedHeaders, xMsEdgeRef, xVssE2eId) + caco := ClientAssertionCredentialOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Cache: options.Cache, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + cred, err := NewClientAssertionCredential(tenantID, clientID, a.getAssertion, &caco) + if err != nil { + return nil, err + } + cred.client.name = credNameAzurePipelines + a.cred = cred + return &a, nil +} + +// GetToken requests an access token from Microsoft Entra ID. Azure SDK clients call this method automatically. +func (a *AzurePipelinesCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) { + var err error + ctx, endSpan := runtime.StartSpan(ctx, credNameAzurePipelines+"."+traceOpGetToken, a.cred.client.azClient.Tracer(), nil) + defer func() { endSpan(err) }() + tk, err := a.cred.GetToken(ctx, opts) + return tk, err +} + +func (a *AzurePipelinesCredential) getAssertion(ctx context.Context) (string, error) { + url := a.oidcURI + "?api-version=" + oidcAPIVersion + "&serviceConnectionId=" + a.connectionID + url, err := runtime.EncodeQueryParams(url) + if err != nil { + return "", newAuthenticationFailedError(credNameAzurePipelines, "couldn't encode OIDC URL: "+err.Error(), nil) + } + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, nil) + if err != nil { + return "", newAuthenticationFailedError(credNameAzurePipelines, "couldn't create OIDC token request: "+err.Error(), nil) + } + req.Header.Set("Authorization", "Bearer "+a.systemAccessToken) + // instruct endpoint to return 401 instead of 302, if the system access token is invalid + req.Header.Set("X-TFS-FedAuthRedirect", "Suppress") + res, err := doForClient(a.cred.client.azClient, req) + if err != nil { + return "", newAuthenticationFailedError(credNameAzurePipelines, "couldn't send OIDC token request: "+err.Error(), nil) + } + if res.StatusCode != http.StatusOK { + msg := res.Status + " response from the OIDC endpoint. Check service connection ID and Pipeline configuration." + for _, h := range []string{xMsEdgeRef, xVssE2eId} { + if v := res.Header.Get(h); v != "" { + msg += fmt.Sprintf("\n%s: %s", h, v) + } + } + // include the response because its body, if any, probably contains an error message. + // OK responses aren't included with errors because they probably contain secrets + return "", newAuthenticationFailedError(credNameAzurePipelines, msg, res) + } + b, err := runtime.Payload(res) + if err != nil { + return "", newAuthenticationFailedError(credNameAzurePipelines, "couldn't read OIDC response content: "+err.Error(), nil) + } + var r struct { + OIDCToken string `json:"oidcToken"` + } + err = json.Unmarshal(b, &r) + if err != nil { + return "", newAuthenticationFailedError(credNameAzurePipelines, "unexpected response from OIDC endpoint", nil) + } + return r.OIDCToken, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/chained_token_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/chained_token_credential.go new file mode 100644 index 000000000..82342a025 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/chained_token_credential.go @@ -0,0 +1,152 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "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" +) + +// ChainedTokenCredentialOptions contains optional parameters for ChainedTokenCredential. +type ChainedTokenCredentialOptions struct { + // RetrySources configures how the credential uses its sources. When true, the credential always attempts to + // authenticate through each source in turn, stopping when one succeeds. When false, the credential authenticates + // only through this first successful source--it never again tries the sources which failed. + RetrySources bool +} + +// ChainedTokenCredential links together multiple credentials and tries them sequentially when authenticating. By default, +// it tries all the credentials until one authenticates, after which it always uses that credential. For more information, +// see [ChainedTokenCredential overview]. +// +// [ChainedTokenCredential overview]: https://aka.ms/azsdk/go/identity/credential-chains#chainedtokencredential-overview +type ChainedTokenCredential struct { + cond *sync.Cond + iterating bool + name string + retrySources bool + sources []azcore.TokenCredential + successfulCredential azcore.TokenCredential +} + +// NewChainedTokenCredential creates a ChainedTokenCredential. Pass nil for options to accept defaults. +func NewChainedTokenCredential(sources []azcore.TokenCredential, options *ChainedTokenCredentialOptions) (*ChainedTokenCredential, error) { + if len(sources) == 0 { + return nil, errors.New("sources must contain at least one TokenCredential") + } + for _, source := range sources { + if source == nil { // cannot have a nil credential in the chain or else the application will panic when GetToken() is called on nil + return nil, errors.New("sources cannot contain nil") + } + if mc, ok := source.(*ManagedIdentityCredential); ok { + mc.mic.chained = true + } + } + cp := make([]azcore.TokenCredential, len(sources)) + copy(cp, sources) + if options == nil { + options = &ChainedTokenCredentialOptions{} + } + return &ChainedTokenCredential{ + cond: sync.NewCond(&sync.Mutex{}), + name: "ChainedTokenCredential", + retrySources: options.RetrySources, + sources: cp, + }, nil +} + +// GetToken calls GetToken on the chained credentials in turn, stopping when one returns a token. +// This method is called automatically by Azure SDK clients. +func (c *ChainedTokenCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) { + if !c.retrySources { + // ensure only one goroutine at a time iterates the sources and perhaps sets c.successfulCredential + c.cond.L.Lock() + for { + if c.successfulCredential != nil { + c.cond.L.Unlock() + return c.successfulCredential.GetToken(ctx, opts) + } + if !c.iterating { + c.iterating = true + // allow other goroutines to wait while this one iterates + c.cond.L.Unlock() + break + } + c.cond.Wait() + } + } + + var ( + err error + errs []error + successfulCredential azcore.TokenCredential + token azcore.AccessToken + unavailableErr credentialUnavailable + ) + for _, cred := range c.sources { + token, err = cred.GetToken(ctx, opts) + if err == nil { + log.Writef(EventAuthentication, "%s authenticated with %s", c.name, extractCredentialName(cred)) + successfulCredential = cred + break + } + errs = append(errs, err) + // continue to the next source iff this one returned credentialUnavailableError + if !errors.As(err, &unavailableErr) { + break + } + } + if c.iterating { + c.cond.L.Lock() + // this is nil when all credentials returned an error + c.successfulCredential = successfulCredential + c.iterating = false + c.cond.L.Unlock() + c.cond.Broadcast() + } + // err is the error returned by the last GetToken call. It will be nil when that call succeeds + if err != nil { + // return credentialUnavailableError iff all sources did so; return AuthenticationFailedError otherwise + msg := createChainedErrorMessage(errs) + var authFailedErr *AuthenticationFailedError + switch { + case errors.As(err, &authFailedErr): + err = newAuthenticationFailedError(c.name, msg, authFailedErr.RawResponse) + if af, ok := err.(*AuthenticationFailedError); ok { + // stop Error() printing the response again; it's already in msg + af.omitResponse = true + } + case errors.As(err, &unavailableErr): + err = newCredentialUnavailableError(c.name, msg) + default: + res := getResponseFromError(err) + err = newAuthenticationFailedError(c.name, msg, res) + } + } + return token, err +} + +func createChainedErrorMessage(errs []error) string { + msg := "failed to acquire a token.\nAttempted credentials:" + for _, err := range errs { + msg += fmt.Sprintf("\n\t%s", strings.ReplaceAll(err.Error(), "\n", "\n\t\t")) + } + return msg +} + +func extractCredentialName(credential azcore.TokenCredential) string { + return strings.TrimPrefix(fmt.Sprintf("%T", credential), "*azidentity.") +} + +var _ azcore.TokenCredential = (*ChainedTokenCredential)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml new file mode 100644 index 000000000..51dd97939 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/ci.yml @@ -0,0 +1,43 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/azidentity/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/azidentity/ + +extends: + template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + CloudConfig: + Public: + SubscriptionConfigurations: + - $(sub-config-identity-test-resources) + EnableRaceDetector: true + Location: westus2 + RunLiveTests: true + ServiceDirectory: azidentity + UsePipelineProxy: false + + ${{ if endsWith(variables['Build.DefinitionName'], 'weekly') }}: + PersistOidcToken: true + MatrixConfigs: + - Name: managed_identity_matrix + GenerateVMJobs: true + Path: sdk/azidentity/managed-identity-matrix.json + Selection: sparse diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_assertion_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_assertion_credential.go new file mode 100644 index 000000000..2307da86f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_assertion_credential.go @@ -0,0 +1,87 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "errors" + + "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 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 +// [Microsoft Entra ID documentation] for details of the assertion format. +// +// [Microsoft Entra ID documentation]: https://learn.microsoft.com/entra/identity-platform/certificate-credentials#assertion-format +type ClientAssertionCredential struct { + client *confidentialClient +} + +// ClientAssertionCredentialOptions contains optional parameters for ClientAssertionCredential. +type ClientAssertionCredentialOptions struct { + azcore.ClientOptions + + // 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 in which the + // application is registered. + AdditionallyAllowedTenants []string + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // 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 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 +} + +// NewClientAssertionCredential constructs a ClientAssertionCredential. The getAssertion function must be thread safe. Pass nil for options to accept defaults. +func NewClientAssertionCredential(tenantID, clientID string, getAssertion func(context.Context) (string, error), options *ClientAssertionCredentialOptions) (*ClientAssertionCredential, error) { + if getAssertion == nil { + return nil, errors.New("getAssertion must be a function that returns assertions") + } + if options == nil { + options = &ClientAssertionCredentialOptions{} + } + cred := confidential.NewCredFromAssertionCallback( + func(ctx context.Context, _ confidential.AssertionRequestOptions) (string, error) { + return getAssertion(ctx) + }, + ) + msalOpts := confidentialClientOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Cache: options.Cache, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + c, err := newConfidentialClient(tenantID, clientID, credNameAssertion, cred, msalOpts) + if err != nil { + return nil, err + } + return &ClientAssertionCredential{client: c}, nil +} + +// 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) { + 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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_certificate_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_certificate_credential.go new file mode 100644 index 000000000..9e6bca1c9 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_certificate_credential.go @@ -0,0 +1,176 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "crypto" + "crypto/x509" + "encoding/pem" + "errors" + + "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" +) + +const credNameCert = "ClientCertificateCredential" + +// ClientCertificateCredentialOptions contains optional parameters for ClientCertificateCredential. +type ClientCertificateCredentialOptions struct { + azcore.ClientOptions + + // 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 in which the + // application is registered. + AdditionallyAllowedTenants []string + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // 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 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 +} + +// ClientCertificateCredential authenticates a service principal with a certificate. +type ClientCertificateCredential struct { + client *confidentialClient +} + +// NewClientCertificateCredential constructs a ClientCertificateCredential. Pass nil for options to accept defaults. See +// [ParseCertificates] for help loading a certificate. +func NewClientCertificateCredential(tenantID string, clientID string, certs []*x509.Certificate, key crypto.PrivateKey, options *ClientCertificateCredentialOptions) (*ClientCertificateCredential, error) { + if len(certs) == 0 { + return nil, errors.New("at least one certificate is required") + } + if options == nil { + options = &ClientCertificateCredentialOptions{} + } + cred, err := confidential.NewCredFromCert(certs, key) + if err != nil { + return nil, err + } + msalOpts := confidentialClientOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Cache: options.Cache, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + SendX5C: options.SendCertificateChain, + } + c, err := newConfidentialClient(tenantID, clientID, credNameCert, cred, msalOpts) + if err != nil { + return nil, err + } + return &ClientCertificateCredential{client: c}, nil +} + +// 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) { + 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 PKCS#12 format, for use with [NewClientCertificateCredential]. +// Pass nil for password if the private key isn't encrypted. This function has limitations, for example it can't decrypt keys in +// PEM format or PKCS#12 certificates that use SHA256 for message authentication. If you encounter such limitations, consider +// using another module to load the certificate and private key. +func ParseCertificates(certData []byte, password []byte) ([]*x509.Certificate, crypto.PrivateKey, error) { + var blocks []*pem.Block + var err error + if len(password) == 0 { + blocks, err = loadPEMCert(certData) + } + if len(blocks) == 0 || err != nil { + blocks, err = loadPKCS12Cert(certData, string(password)) + } + if err != nil { + return nil, nil, err + } + var certs []*x509.Certificate + var pk crypto.PrivateKey + for _, block := range blocks { + switch block.Type { + case "CERTIFICATE": + c, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, nil, err + } + certs = append(certs, c) + case "PRIVATE KEY": + if pk != nil { + return nil, nil, errors.New("certData contains multiple private keys") + } + pk, err = x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + pk, err = x509.ParsePKCS1PrivateKey(block.Bytes) + } + if err != nil { + return nil, nil, err + } + case "RSA PRIVATE KEY": + if pk != nil { + return nil, nil, errors.New("certData contains multiple private keys") + } + pk, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, nil, err + } + } + } + if len(certs) == 0 { + return nil, nil, errors.New("found no certificate") + } + if pk == nil { + return nil, nil, errors.New("found no private key") + } + return certs, pk, nil +} + +func loadPEMCert(certData []byte) ([]*pem.Block, error) { + blocks := []*pem.Block{} + for { + var block *pem.Block + block, certData = pem.Decode(certData) + if block == nil { + break + } + blocks = append(blocks, block) + } + if len(blocks) == 0 { + return nil, errors.New("didn't find any PEM blocks") + } + return blocks, nil +} + +func loadPKCS12Cert(certData []byte, password string) ([]*pem.Block, error) { + blocks, err := pkcs12.ToPEM(certData, password) + if err != nil { + return nil, err + } + if len(blocks) == 0 { + // not mentioning PKCS12 in this message because we end up here when certData is garbage + return nil, errors.New("didn't find any certificate content") + } + return blocks, err +} + +var _ azcore.TokenCredential = (*ClientCertificateCredential)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_secret_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_secret_credential.go new file mode 100644 index 000000000..f0890fe1e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/client_secret_credential.go @@ -0,0 +1,77 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + + "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 credNameSecret = "ClientSecretCredential" + +// ClientSecretCredentialOptions contains optional parameters for ClientSecretCredential. +type ClientSecretCredentialOptions struct { + azcore.ClientOptions + + // 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 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 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 + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache +} + +// ClientSecretCredential authenticates an application with a client secret. +type ClientSecretCredential struct { + client *confidentialClient +} + +// NewClientSecretCredential constructs a ClientSecretCredential. Pass nil for options to accept defaults. +func NewClientSecretCredential(tenantID string, clientID string, clientSecret string, options *ClientSecretCredentialOptions) (*ClientSecretCredential, error) { + if options == nil { + options = &ClientSecretCredentialOptions{} + } + cred, err := confidential.NewCredFromSecret(clientSecret) + if err != nil { + return nil, err + } + msalOpts := confidentialClientOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Cache: options.Cache, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + c, err := newConfidentialClient(tenantID, clientID, credNameSecret, cred, msalOpts) + if err != nil { + return nil, err + } + return &ClientSecretCredential{client: c}, nil +} + +// 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) { + 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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/confidential_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/confidential_client.go new file mode 100644 index 000000000..58c4b585c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/confidential_client.go @@ -0,0 +1,184 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "errors" + "fmt" + "net/http" + "os" + "strings" + "sync" + + "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" +) + +type confidentialClientOptions struct { + azcore.ClientOptions + + AdditionallyAllowedTenants []string + // Assertion for on-behalf-of authentication + Assertion string + Cache Cache + DisableInstanceDiscovery, SendX5C bool +} + +// confidentialClient wraps the MSAL confidential client +type confidentialClient struct { + cae, noCAE msalConfidentialClient + caeMu, noCAEMu, clientMu *sync.Mutex + clientID, tenantID string + cred confidential.Credential + host string + name string + opts confidentialClientOptions + region string + azClient *azcore.Client +} + +func newConfidentialClient(tenantID, clientID, name string, cred confidential.Credential, opts confidentialClientOptions) (*confidentialClient, error) { + if !validTenantID(tenantID) { + return nil, errInvalidTenantID + } + host, err := setAuthorityHost(opts.Cloud) + 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{}, + clientID: clientID, + clientMu: &sync.Mutex{}, + cred: cred, + host: host, + name: name, + noCAEMu: &sync.Mutex{}, + opts: opts, + region: os.Getenv(azureRegionalAuthorityName), + tenantID: tenantID, + azClient: client, + }, nil +} + +// GetToken requests an access token from MSAL, checking the cache first. +func (c *confidentialClient) GetToken(ctx context.Context, tro policy.TokenRequestOptions) (azcore.AccessToken, error) { + if len(tro.Scopes) < 1 { + return azcore.AccessToken{}, fmt.Errorf("%s.GetToken() requires at least one scope", c.name) + } + // we don't resolve the tenant for managed identities because they acquire tokens only from their home tenants + if c.name != credNameManagedIdentity { + tenant, err := c.resolveTenant(tro.TenantID) + if err != nil { + return azcore.AccessToken{}, err + } + tro.TenantID = tenant + } + client, mu, err := c.client(tro) + if err != nil { + return azcore.AccessToken{}, err + } + mu.Lock() + defer mu.Unlock() + var ar confidential.AuthResult + if c.opts.Assertion != "" { + ar, err = client.AcquireTokenOnBehalfOf(ctx, c.opts.Assertion, tro.Scopes, confidential.WithClaims(tro.Claims), confidential.WithTenantID(tro.TenantID)) + } else { + ar, err = client.AcquireTokenSilent(ctx, tro.Scopes, confidential.WithClaims(tro.Claims), confidential.WithTenantID(tro.TenantID)) + if err != nil { + ar, err = client.AcquireTokenByCredential(ctx, tro.Scopes, confidential.WithClaims(tro.Claims), confidential.WithTenantID(tro.TenantID)) + } + } + if err != nil { + var ( + authFailedErr *AuthenticationFailedError + unavailableErr credentialUnavailable + ) + if !(errors.As(err, &unavailableErr) || errors.As(err, &authFailedErr)) { + err = newAuthenticationFailedErrorFromMSAL(c.name, err) + } + } else { + msg := fmt.Sprintf(scopeLogFmt, c.name, strings.Join(ar.GrantedScopes, ", ")) + log.Write(EventAuthentication, msg) + } + 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) { + c.clientMu.Lock() + defer c.clientMu.Unlock() + if tro.EnableCAE { + if c.cae == nil { + client, err := c.newMSALClient(true) + if err != nil { + return nil, nil, err + } + c.cae = client + } + return c.cae, c.caeMu, nil + } + if c.noCAE == nil { + client, err := c.newMSALClient(false) + if err != nil { + return nil, nil, err + } + c.noCAE = client + } + return c.noCAE, c.noCAEMu, nil +} + +func (c *confidentialClient) newMSALClient(enableCAE bool) (msalConfidentialClient, error) { + cache, err := internal.ExportReplace(c.opts.Cache, enableCAE) + if err != nil { + return nil, err + } + authority := runtime.JoinPaths(c.host, c.tenantID) + o := []confidential.Option{ + confidential.WithAzureRegion(c.region), + confidential.WithCache(cache), + confidential.WithHTTPClient(c), + } + if enableCAE { + o = append(o, confidential.WithClientCapabilities(cp1)) + } + if c.opts.SendX5C { + o = append(o, confidential.WithX5C()) + } + if c.opts.DisableInstanceDiscovery || strings.ToLower(c.tenantID) == "adfs" { + o = append(o, confidential.WithInstanceDiscovery(false)) + } + return confidential.New(authority, c.clientID, c.cred, o...) +} + +// 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) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go new file mode 100644 index 000000000..c041a52db --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/default_azure_credential.go @@ -0,0 +1,241 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "fmt" + "os" + "strings" + + "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 azureTokenCredentials = "AZURE_TOKEN_CREDENTIALS" + +// bit flags NewDefaultAzureCredential uses to parse AZURE_TOKEN_CREDENTIALS +const ( + env = uint8(1) << iota + workloadIdentity + managedIdentity + az + azd +) + +// DefaultAzureCredentialOptions contains optional parameters for DefaultAzureCredential. +// These options may not apply to all credentials in the chain. +type DefaultAzureCredentialOptions struct { + // ClientOptions has additional options for credentials that use an Azure SDK HTTP pipeline. These options don't apply + // to credential types that authenticate via external tools such as the Azure CLI. + azcore.ClientOptions + + // AdditionallyAllowedTenants specifies tenants to which the credential may authenticate, in addition to + // TenantID. When TenantID is empty, this option has no effect and the credential will authenticate to + // any requested tenant. Add the wildcard value "*" to allow the credential to authenticate to any tenant. + // This value can also be 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 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 + + // RequireAzureTokenCredentials determines whether NewDefaultAzureCredential returns an error when the environment + // variable AZURE_TOKEN_CREDENTIALS has no value. + RequireAzureTokenCredentials bool + + // TenantID sets the default tenant for authentication via the Azure CLI, Azure Developer CLI, and workload identity. + TenantID string +} + +// DefaultAzureCredential simplifies authentication while developing applications that deploy to Azure by +// combining credentials used in Azure hosting environments and credentials used in local development. In +// production, it's better to use a specific credential type so authentication is more predictable and easier +// to debug. For more information, see [DefaultAzureCredential overview]. +// +// DefaultAzureCredential attempts to authenticate with each of these credential types, in the following order, +// stopping when one provides a token: +// +// - [EnvironmentCredential] +// - [WorkloadIdentityCredential], if environment variable configuration is set by the Azure workload +// identity webhook. Use [WorkloadIdentityCredential] directly when not using the webhook or needing +// 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 +// every subsequent authentication. +// +// # Selecting credentials +// +// Set environment variable AZURE_TOKEN_CREDENTIALS to select a subset of the credential chain described above. +// DefaultAzureCredential will try only the specified credential(s), but its other behavior remains the same. +// Valid values for AZURE_TOKEN_CREDENTIALS are the name of any single type in the above chain, for example +// "EnvironmentCredential" or "AzureCLICredential", and these special values: +// +// - "dev": try [AzureCLICredential] and [AzureDeveloperCLICredential], in that order +// - "prod": try [EnvironmentCredential], [WorkloadIdentityCredential], and [ManagedIdentityCredential], in that order +// +// [DefaultAzureCredentialOptions].RequireAzureTokenCredentials controls whether AZURE_TOKEN_CREDENTIALS must be set. +// NewDefaultAzureCredential returns an error when RequireAzureTokenCredentials is true and AZURE_TOKEN_CREDENTIALS +// has no value. +// +// [DefaultAzureCredential overview]: https://aka.ms/azsdk/go/identity/credential-chains#defaultazurecredential-overview +type DefaultAzureCredential struct { + chain *ChainedTokenCredential +} + +// NewDefaultAzureCredential creates a DefaultAzureCredential. Pass nil for options to accept defaults. +func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*DefaultAzureCredential, error) { + if options == nil { + options = &DefaultAzureCredentialOptions{} + } + + var ( + creds []azcore.TokenCredential + errorMessages []string + selected = env | workloadIdentity | managedIdentity | az | azd + ) + + if atc, ok := os.LookupEnv(azureTokenCredentials); ok { + switch { + case atc == "dev": + selected = az | azd + case atc == "prod": + selected = env | workloadIdentity | managedIdentity + case strings.EqualFold(atc, credNameEnvironment): + selected = env + case strings.EqualFold(atc, credNameWorkloadIdentity): + selected = workloadIdentity + case strings.EqualFold(atc, credNameManagedIdentity): + selected = managedIdentity + case strings.EqualFold(atc, credNameAzureCLI): + selected = az + case strings.EqualFold(atc, credNameAzureDeveloperCLI): + selected = azd + default: + return nil, fmt.Errorf(`invalid %s value %q. Valid values are "dev", "prod", or the name of any credential type in the default chain. See https://aka.ms/azsdk/go/identity/docs#DefaultAzureCredential for more information`, azureTokenCredentials, atc) + } + } else if options.RequireAzureTokenCredentials { + return nil, fmt.Errorf("%s must be set when RequireAzureTokenCredentials is true. See https://aka.ms/azsdk/go/identity/docs#DefaultAzureCredential for more information", azureTokenCredentials) + } + + additionalTenants := options.AdditionallyAllowedTenants + if len(additionalTenants) == 0 { + if tenants := os.Getenv(azureAdditionallyAllowedTenants); tenants != "" { + additionalTenants = strings.Split(tenants, ";") + } + } + if selected&env != 0 { + envCred, err := NewEnvironmentCredential(&EnvironmentCredentialOptions{ + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + additionallyAllowedTenants: additionalTenants, + }) + if err == nil { + creds = append(creds, envCred) + } else { + errorMessages = append(errorMessages, "EnvironmentCredential: "+err.Error()) + creds = append(creds, &defaultCredentialErrorReporter{credType: credNameEnvironment, err: err}) + } + } + if selected&workloadIdentity != 0 { + wic, err := NewWorkloadIdentityCredential(&WorkloadIdentityCredentialOptions{ + AdditionallyAllowedTenants: additionalTenants, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + TenantID: options.TenantID, + }) + if err == nil { + creds = append(creds, wic) + } else { + errorMessages = append(errorMessages, credNameWorkloadIdentity+": "+err.Error()) + creds = append(creds, &defaultCredentialErrorReporter{credType: credNameWorkloadIdentity, err: err}) + } + } + if selected&managedIdentity != 0 { + o := &ManagedIdentityCredentialOptions{ClientOptions: options.ClientOptions, dac: true} + if ID, ok := os.LookupEnv(azureClientID); ok { + o.ID = ClientID(ID) + } + miCred, err := NewManagedIdentityCredential(o) + if err == nil { + creds = append(creds, miCred) + } else { + errorMessages = append(errorMessages, credNameManagedIdentity+": "+err.Error()) + creds = append(creds, &defaultCredentialErrorReporter{credType: credNameManagedIdentity, err: err}) + } + } + if selected&az != 0 { + azCred, err := NewAzureCLICredential(&AzureCLICredentialOptions{ + AdditionallyAllowedTenants: additionalTenants, + TenantID: options.TenantID, + inDefaultChain: true, + }) + if err == nil { + creds = append(creds, azCred) + } else { + errorMessages = append(errorMessages, credNameAzureCLI+": "+err.Error()) + creds = append(creds, &defaultCredentialErrorReporter{credType: credNameAzureCLI, err: err}) + } + } + if selected&azd != 0 { + azdCred, err := NewAzureDeveloperCLICredential(&AzureDeveloperCLICredentialOptions{ + AdditionallyAllowedTenants: additionalTenants, + TenantID: options.TenantID, + inDefaultChain: true, + }) + 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")) + } + + chain, err := NewChainedTokenCredential(creds, nil) + if err != nil { + return nil, err + } + chain.name = "DefaultAzureCredential" + return &DefaultAzureCredential{chain: chain}, nil +} + +// 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) +} + +var _ azcore.TokenCredential = (*DefaultAzureCredential)(nil) + +// defaultCredentialErrorReporter is a substitute for credentials that couldn't be constructed. +// Its GetToken method always returns a credentialUnavailableError having the same message as +// the error that prevented constructing the credential. This ensures the message is present +// in the error returned by ChainedTokenCredential.GetToken() +type defaultCredentialErrorReporter struct { + credType string + err error +} + +func (d *defaultCredentialErrorReporter) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) { + if _, ok := d.err.(credentialUnavailable); ok { + return azcore.AccessToken{}, d.err + } + return azcore.AccessToken{}, newCredentialUnavailableError(d.credType, d.err.Error()) +} + +var _ azcore.TokenCredential = (*defaultCredentialErrorReporter)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go new file mode 100644 index 000000000..14f8a0312 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/developer_credential_util.go @@ -0,0 +1,89 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "bytes" + "context" + "errors" + "os" + "os/exec" + "runtime" + "strings" + "time" +) + +// cliTimeout is the default timeout for authentication attempts via CLI tools +const cliTimeout = 10 * time.Second + +// executor runs a command and returns its output or an error +type executor func(ctx context.Context, credName, command string) ([]byte, error) + +var shellExec = func(ctx context.Context, credName, command string) ([]byte, error) { + // set a default timeout for this authentication iff the caller hasn't done so already + var cancel context.CancelFunc + if _, hasDeadline := ctx.Deadline(); !hasDeadline { + ctx, cancel = context.WithTimeout(ctx, cliTimeout) + defer cancel() + } + var cmd *exec.Cmd + if runtime.GOOS == "windows" { + dir := os.Getenv("SYSTEMROOT") + if dir == "" { + return nil, newCredentialUnavailableError(credName, `environment variable "SYSTEMROOT" has no value`) + } + cmd = exec.CommandContext(ctx, "cmd.exe", "/c", command) + cmd.Dir = dir + } else { + cmd = exec.CommandContext(ctx, "/bin/sh", "-c", command) + cmd.Dir = "/bin" + } + cmd.Env = os.Environ() + stderr := bytes.Buffer{} + cmd.Stderr = &stderr + cmd.WaitDelay = 100 * time.Millisecond + + stdout, err := cmd.Output() + if errors.Is(err, exec.ErrWaitDelay) && len(stdout) > 0 { + // The child process wrote to stdout and exited without closing it. + // Swallow this error and return stdout because it may contain a token. + return stdout, nil + } + if err != nil { + msg := stderr.String() + var exErr *exec.ExitError + if errors.As(err, &exErr) && exErr.ExitCode() == 127 || strings.Contains(msg, "' is not recognized") { + return nil, newCredentialUnavailableError(credName, "CLI executable not found on path") + } + if msg == "" { + msg = err.Error() + } + return nil, newAuthenticationFailedError(credName, msg, nil) + } + + return stdout, nil +} + +// unavailableIfInDAC 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 unavailableIfInDAC(err error, inDefaultChain bool) error { + if err != nil && inDefaultChain && !errors.As(err, new(credentialUnavailable)) { + err = NewCredentialUnavailableError(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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/device_code_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/device_code_credential.go new file mode 100644 index 000000000..53ae9767f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/device_code_credential.go @@ -0,0 +1,145 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "fmt" + + "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" + +// DeviceCodeCredentialOptions contains optional parameters for DeviceCodeCredential. +type DeviceCodeCredentialOptions struct { + azcore.ClientOptions + + // AdditionallyAllowedTenants specifies tenants to which the credential may authenticate, in addition to + // TenantID. When TenantID is empty, this option has no effect and the credential will authenticate to + // any requested tenant. Add the wildcard value "*" to allow the credential to authenticate to 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 + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // ClientID is the ID of the application to which users will authenticate. When not set, users + // will authenticate to an Azure development application, which isn't recommended for production + // scenarios. In production, developers should instead register their applications and assign + // appropriate roles. See https://aka.ms/azsdk/identity/AppRegistrationAndRoleAssignment for more + // information. + ClientID string + + // DisableAutomaticAuthentication prevents the credential from automatically prompting the user to authenticate. + // When this option is true, GetToken will return AuthenticationRequiredError 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 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 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 + + // 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. + UserPrompt func(context.Context, DeviceCodeMessage) error +} + +func (o *DeviceCodeCredentialOptions) init() { + if o.TenantID == "" { + o.TenantID = organizationsTenantID + } + if o.ClientID == "" { + o.ClientID = developerSignOnClientID + } + if o.UserPrompt == nil { + o.UserPrompt = func(ctx context.Context, dc DeviceCodeMessage) error { + fmt.Println(dc.Message) + return nil + } + } +} + +// DeviceCodeMessage contains the information a user needs to complete authentication. +type DeviceCodeMessage struct { + // UserCode is the user code returned by the service. + 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 Microsoft Entra ID. + Message string `json:"message"` +} + +// DeviceCodeCredential acquires tokens for a user via the device code flow, which has the +// 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 +// automatically opens a browser to the login page. +type DeviceCodeCredential struct { + client *publicClient +} + +// NewDeviceCodeCredential creates a DeviceCodeCredential. Pass nil to accept default options. +func NewDeviceCodeCredential(options *DeviceCodeCredentialOptions) (*DeviceCodeCredential, error) { + cp := DeviceCodeCredentialOptions{} + if options != nil { + cp = *options + } + cp.init() + msalOpts := publicClientOptions{ + AdditionallyAllowedTenants: cp.AdditionallyAllowedTenants, + Cache: cp.Cache, + ClientOptions: cp.ClientOptions, + DeviceCodePrompt: cp.UserPrompt, + DisableAutomaticAuthentication: cp.DisableAutomaticAuthentication, + DisableInstanceDiscovery: cp.DisableInstanceDiscovery, + Record: cp.AuthenticationRecord, + } + c, err := newPublicClient(cp.TenantID, cp.ClientID, credNameDeviceCode, msalOpts) + if err != nil { + return nil, err + } + c.name = credNameDeviceCode + return &DeviceCodeCredential{client: c}, nil +} + +// Authenticate prompts a user to log in via the device code flow. Subsequent +// GetToken calls 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) { + 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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go new file mode 100644 index 000000000..f04d40ea4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go @@ -0,0 +1,162 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "errors" + "fmt" + "os" + "strings" + + "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 ( + credNameEnvironment = "EnvironmentCredential" + envVarSendCertChain = "AZURE_CLIENT_SEND_CERTIFICATE_CHAIN" +) + +// EnvironmentCredentialOptions contains optional parameters for EnvironmentCredential +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 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 + // additionallyAllowedTenants is used only by NewDefaultAzureCredential() to enable that constructor's explicit + // option to override the value of AZURE_ADDITIONALLY_ALLOWED_TENANTS. Applications using EnvironmentCredential + // directly should set that variable instead. This field should remain unexported to preserve this credential's + // unambiguous "all configuration from environment variables" design. + additionallyAllowedTenants []string +} + +// EnvironmentCredential authenticates a service principal with a secret or certificate, or a user with a password, depending +// on environment variable configuration. It reads configuration from these variables, in the following order: +// +// # Service principal with client secret +// +// AZURE_TENANT_ID: ID of the service principal's tenant. Also called its "directory" ID. +// +// AZURE_CLIENT_ID: the service principal's client ID +// +// AZURE_CLIENT_SECRET: one of the service principal's client secrets +// +// # Service principal with certificate +// +// AZURE_TENANT_ID: ID of the service principal's tenant. Also called its "directory" ID. +// +// AZURE_CLIENT_ID: the service principal's client ID +// +// AZURE_CLIENT_CERTIFICATE_PATH: path to a PEM or PKCS12 certificate file including the private key. +// +// AZURE_CLIENT_CERTIFICATE_PASSWORD: (optional) password for the certificate file. +// +// 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. +// +// # Configuration for multitenant applications +// +// 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 +} + +// NewEnvironmentCredential creates an EnvironmentCredential. Pass nil to accept default options. +func NewEnvironmentCredential(options *EnvironmentCredentialOptions) (*EnvironmentCredential, error) { + if options == nil { + options = &EnvironmentCredentialOptions{} + } + tenantID := os.Getenv(azureTenantID) + if tenantID == "" { + return nil, errors.New("missing environment variable AZURE_TENANT_ID") + } + clientID := os.Getenv(azureClientID) + if clientID == "" { + return nil, errors.New("missing environment variable " + azureClientID) + } + // tenants set by NewDefaultAzureCredential() override the value of AZURE_ADDITIONALLY_ALLOWED_TENANTS + additionalTenants := options.additionallyAllowedTenants + if len(additionalTenants) == 0 { + if tenants := os.Getenv(azureAdditionallyAllowedTenants); tenants != "" { + additionalTenants = strings.Split(tenants, ";") + } + } + if clientSecret := os.Getenv(azureClientSecret); clientSecret != "" { + log.Write(EventAuthentication, "EnvironmentCredential will authenticate with ClientSecretCredential") + o := &ClientSecretCredentialOptions{ + AdditionallyAllowedTenants: additionalTenants, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + cred, err := NewClientSecretCredential(tenantID, clientID, clientSecret, o) + if err != nil { + return nil, err + } + return &EnvironmentCredential{cred: cred}, nil + } + if certPath := os.Getenv(azureClientCertificatePath); certPath != "" { + log.Write(EventAuthentication, "EnvironmentCredential will authenticate with ClientCertificateCredential") + certData, err := os.ReadFile(certPath) + if err != nil { + return nil, fmt.Errorf(`failed to read certificate file "%s": %v`, certPath, err) + } + var password []byte + if v := os.Getenv(azureClientCertificatePassword); v != "" { + password = []byte(v) + } + certs, key, err := ParseCertificates(certData, password) + if err != nil { + return nil, fmt.Errorf("failed to parse %q due to error %q. This may be due to a limitation of this module's certificate loader. Consider calling NewClientCertificateCredential instead", certPath, err.Error()) + } + o := &ClientCertificateCredentialOptions{ + AdditionallyAllowedTenants: additionalTenants, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + if v, ok := os.LookupEnv(envVarSendCertChain); ok { + o.SendCertificateChain = v == "1" || strings.ToLower(v) == "true" + } + cred, err := NewClientCertificateCredential(tenantID, clientID, certs, key, o) + if err != nil { + return nil, err + } + return &EnvironmentCredential{cred: cred}, nil + } + if username := os.Getenv(azureUsername); username != "" { + if password := os.Getenv(azurePassword); password != "" { + log.Write(EventAuthentication, "EnvironmentCredential will authenticate with UsernamePasswordCredential") + o := &UsernamePasswordCredentialOptions{ + AdditionallyAllowedTenants: additionalTenants, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + cred, err := NewUsernamePasswordCredential(tenantID, clientID, username, password, o) + if err != nil { + return nil, err + } + return &EnvironmentCredential{cred: cred}, nil + } + return nil, errors.New("no value for AZURE_PASSWORD") + } + return nil, errors.New("incomplete environment variable configuration. Only AZURE_TENANT_ID and AZURE_CLIENT_ID are set") +} + +// 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) +} + +var _ azcore.TokenCredential = (*EnvironmentCredential)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/errors.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/errors.go new file mode 100644 index 000000000..a6d7c6cbc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/errors.go @@ -0,0 +1,180 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo" + msal "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors" +) + +// getResponseFromError retrieves the response carried by +// an AuthenticationFailedError or MSAL CallErr, if any +func getResponseFromError(err error) *http.Response { + var a *AuthenticationFailedError + var c msal.CallErr + var res *http.Response + if errors.As(err, &c) { + res = c.Resp + } else if errors.As(err, &a) { + res = a.RawResponse + } + return res +} + +// AuthenticationFailedError indicates an authentication request has failed. +type AuthenticationFailedError struct { + // RawResponse is the HTTP response motivating the error, if available. + RawResponse *http.Response + + credType, message string + omitResponse bool +} + +func newAuthenticationFailedError(credType, message string, resp *http.Response) error { + return &AuthenticationFailedError{credType: credType, message: message, RawResponse: resp} +} + +// newAuthenticationFailedErrorFromMSAL creates an AuthenticationFailedError from an MSAL error. +// If the error is an MSAL CallErr, the new error includes an HTTP response and not the MSAL error +// message, because that message is redundant given the response. If the original error isn't a +// CallErr, the returned error incorporates its message. +func newAuthenticationFailedErrorFromMSAL(credType string, err error) error { + msg := "" + res := getResponseFromError(err) + if res == nil { + msg = err.Error() + } + return newAuthenticationFailedError(credType, msg, res) +} + +// Error implements the error interface. Note that the message contents are not contractual and can change over time. +func (e *AuthenticationFailedError) Error() string { + if e.RawResponse == nil || e.omitResponse { + return e.credType + ": " + e.message + } + msg := &bytes.Buffer{} + fmt.Fprintf(msg, "%s authentication failed. %s\n", e.credType, e.message) + 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 %d: %s\n", e.RawResponse.StatusCode, e.RawResponse.Status) + fmt.Fprintln(msg, "--------------------------------------------------------------------------------") + body, err := runtime.Payload(e.RawResponse) + switch { + case err != nil: + fmt.Fprintf(msg, "Error reading response body: %v", err) + case len(body) > 0: + if err := json.Indent(msg, body, "", " "); err != nil { + // failed to pretty-print so just dump it verbatim + fmt.Fprint(msg, string(body)) + } + default: + fmt.Fprint(msg, "Response contained no body") + } + fmt.Fprintln(msg, "\n--------------------------------------------------------------------------------") + var anchor string + switch e.credType { + case credNameAzureCLI: + anchor = "azure-cli" + case credNameAzureDeveloperCLI: + anchor = "azd" + case credNameAzurePipelines: + anchor = "apc" + case credNameCert: + anchor = "client-cert" + case credNameSecret: + anchor = "client-secret" + case credNameManagedIdentity: + anchor = "managed-id" + case credNameWorkloadIdentity: + anchor = "workload" + } + if anchor != "" { + fmt.Fprintf(msg, "To troubleshoot, visit https://aka.ms/azsdk/go/identity/troubleshoot#%s", anchor) + } + return msg.String() +} + +// NonRetriable indicates the request which provoked this error shouldn't be retried. +func (*AuthenticationFailedError) NonRetriable() { + // marker method +} + +var _ errorinfo.NonRetriable = (*AuthenticationFailedError)(nil) + +// AuthenticationRequiredError indicates a credential's Authenticate method must be called to acquire a token +// because the credential requires user interaction and is configured not to request it automatically. +type AuthenticationRequiredError struct { + credentialUnavailableError + + // TokenRequestOptions for the required token. Pass this to the credential's Authenticate method. + TokenRequestOptions policy.TokenRequestOptions +} + +func newAuthenticationRequiredError(credType string, tro policy.TokenRequestOptions) error { + return &AuthenticationRequiredError{ + credentialUnavailableError: credentialUnavailableError{ + credType + " can't acquire a token without user interaction. Call Authenticate to authenticate a user interactively", + }, + TokenRequestOptions: tro, + } +} + +var ( + _ credentialUnavailable = (*AuthenticationRequiredError)(nil) + _ errorinfo.NonRetriable = (*AuthenticationRequiredError)(nil) +) + +type credentialUnavailable interface { + error + credentialUnavailable() +} + +type credentialUnavailableError struct { + message string +} + +// newCredentialUnavailableError is an internal helper that ensures consistent error message formatting +func newCredentialUnavailableError(credType, message string) error { + msg := fmt.Sprintf("%s: %s", credType, message) + return &credentialUnavailableError{msg} +} + +// NewCredentialUnavailableError constructs an error indicating a credential can't attempt authentication +// because it lacks required data or state. When [ChainedTokenCredential] receives this error it will try +// its next credential, if any. +func NewCredentialUnavailableError(message string) error { + return &credentialUnavailableError{message} +} + +// Error implements the error interface. Note that the message contents are not contractual and can change over time. +func (e *credentialUnavailableError) Error() string { + return e.message +} + +// NonRetriable is a marker method indicating this error should not be retried. It has no implementation. +func (*credentialUnavailableError) NonRetriable() {} + +func (*credentialUnavailableError) credentialUnavailable() {} + +var ( + _ credentialUnavailable = (*credentialUnavailableError)(nil) + _ errorinfo.NonRetriable = (*credentialUnavailableError)(nil) +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work new file mode 100644 index 000000000..6dd5b3d64 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work @@ -0,0 +1,6 @@ +go 1.23.0 + +use ( + . + ./cache +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/interactive_browser_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/interactive_browser_credential.go new file mode 100644 index 000000000..ec89de9b5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/interactive_browser_credential.go @@ -0,0 +1,125 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + + "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" + +// InteractiveBrowserCredentialOptions contains optional parameters for InteractiveBrowserCredential. +type InteractiveBrowserCredentialOptions struct { + azcore.ClientOptions + + // AdditionallyAllowedTenants specifies tenants to which the credential may authenticate, in addition to + // TenantID. When TenantID is empty, this option has no effect and the credential will authenticate to + // any requested tenant. Add the wildcard value "*" to allow the credential to authenticate to 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 + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // ClientID is the ID of the application to which users will authenticate. When not set, users + // will authenticate to an Azure development application, which isn't recommended for production + // scenarios. In production, developers should instead register their applications and assign + // appropriate roles. See https://aka.ms/azsdk/identity/AppRegistrationAndRoleAssignment for more + // information. + ClientID string + + // DisableAutomaticAuthentication prevents the credential from automatically prompting the user to authenticate. + // When this option is true, GetToken will return AuthenticationRequiredError 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 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 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 Microsoft Entra tenant the credential authenticates in. Defaults to the + // "organizations" tenant, which can authenticate work and school accounts. + TenantID string +} + +func (o *InteractiveBrowserCredentialOptions) init() { + if o.TenantID == "" { + o.TenantID = organizationsTenantID + } + if o.ClientID == "" { + o.ClientID = developerSignOnClientID + } +} + +// InteractiveBrowserCredential opens a browser to interactively authenticate a user. +type InteractiveBrowserCredential struct { + client *publicClient +} + +// NewInteractiveBrowserCredential constructs a new InteractiveBrowserCredential. Pass nil to accept default options. +func NewInteractiveBrowserCredential(options *InteractiveBrowserCredentialOptions) (*InteractiveBrowserCredential, error) { + cp := InteractiveBrowserCredentialOptions{} + if options != nil { + cp = *options + } + cp.init() + msalOpts := publicClientOptions{ + AdditionallyAllowedTenants: cp.AdditionallyAllowedTenants, + Cache: cp.Cache, + ClientOptions: cp.ClientOptions, + DisableAutomaticAuthentication: cp.DisableAutomaticAuthentication, + DisableInstanceDiscovery: cp.DisableInstanceDiscovery, + LoginHint: cp.LoginHint, + Record: cp.AuthenticationRecord, + RedirectURL: cp.RedirectURL, + } + c, err := newPublicClient(cp.TenantID, cp.ClientID, credNameBrowser, msalOpts) + if err != nil { + return nil, err + } + return &InteractiveBrowserCredential{client: c}, nil +} + +// Authenticate opens the default browser so a user can log in. Subsequent +// GetToken calls 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) { + 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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal/cache.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal/cache.go new file mode 100644 index 000000000..c0cfe7606 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal/cache.go @@ -0,0 +1,86 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package internal + +import ( + "sync" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache" +) + +// Cache represents a persistent cache that makes authentication data available across processes. +// Construct one with [github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache.New]. This package's +// [persistent user authentication example] shows how to use a persistent cache to reuse user +// logins across application runs. For service principal credential types such as +// [ClientCertificateCredential], simply set the Cache field on the credential options. +// +// [persistent user authentication example]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#example-package-PersistentUserAuthentication +type Cache struct { + // impl is a pointer so a Cache can carry persistent state across copies + impl *impl +} + +// impl is a Cache's private implementation +type impl struct { + // factory constructs storage implementations + factory func(bool) (cache.ExportReplace, error) + // cae and noCAE are previously constructed storage implementations. CAE + // and non-CAE tokens must be stored separately because MSAL's cache doesn't + // observe token claims. If a single storage implementation held both kinds + // of tokens, it could create a reauthentication or error loop by returning + // a non-CAE token lacking a required claim. + cae, noCAE cache.ExportReplace + // mu synchronizes around cae and noCAE + mu *sync.RWMutex +} + +func (i *impl) exportReplace(cae bool) (cache.ExportReplace, error) { + if i == nil { + // zero-value Cache: return a nil ExportReplace and MSAL will cache in memory + return nil, nil + } + var ( + err error + xr cache.ExportReplace + ) + i.mu.RLock() + xr = i.cae + if !cae { + xr = i.noCAE + } + i.mu.RUnlock() + if xr != nil { + return xr, nil + } + i.mu.Lock() + defer i.mu.Unlock() + if cae { + if i.cae == nil { + if xr, err = i.factory(cae); err == nil { + i.cae = xr + } + } + return i.cae, err + } + if i.noCAE == nil { + if xr, err = i.factory(cae); err == nil { + i.noCAE = xr + } + } + return i.noCAE, err +} + +// NewCache is the constructor for Cache. It takes a factory instead of an instance +// because it doesn't know whether the Cache will store both CAE and non-CAE tokens. +func NewCache(factory func(cae bool) (cache.ExportReplace, error)) Cache { + return Cache{&impl{factory: factory, mu: &sync.RWMutex{}}} +} + +// ExportReplace returns an implementation satisfying MSAL's ExportReplace interface. +// It's a function instead of a method on Cache so packages in azidentity and +// azidentity/cache can call it while applications can't. "cae" declares whether the +// caller intends this implementation to store CAE tokens. +func ExportReplace(c Cache, cae bool) (cache.ExportReplace, error) { + return c.impl.exportReplace(cae) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/logging.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/logging.go new file mode 100644 index 000000000..1aa1e0fc7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/logging.go @@ -0,0 +1,14 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import "github.com/Azure/azure-sdk-for-go/sdk/internal/log" + +// EventAuthentication entries contain information about authentication. +// This includes information like the names of environment variables +// used when obtaining credentials and the type of credential used. +const EventAuthentication log.Event = "Authentication" diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json new file mode 100644 index 000000000..063325c69 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json @@ -0,0 +1,16 @@ +{ + "include": [ + { + "Agent": { + "msi_image": { + "ArmTemplateParameters": "@{deployResources = $true}", + "OSVmImage": "env:LINUXVMIMAGE", + "Pool": "env:LINUXPOOL" + } + }, + "GoVersion": [ + "env:GO_VERSION_PREVIOUS" + ] + } + ] +} \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go new file mode 100644 index 000000000..0735d1fcb --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go @@ -0,0 +1,227 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "errors" + "fmt" + "net/http" + "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/internal/log" + msalerrors "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity" +) + +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" + miResID = "mi_res_id" + msiEndpoint = "MSI_ENDPOINT" + msiResID = "msi_res_id" + msiSecret = "MSI_SECRET" + imdsAPIVersion = "2018-02-01" + azureArcAPIVersion = "2020-06-01" + qpClientID = "client_id" + serviceFabricAPIVersion = "2019-07-01-preview" +) + +var imdsProbeTimeout = time.Second + +type managedIdentityClient struct { + 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 + msalClient msalManagedIdentityClient +} + +// setIMDSRetryOptionDefaults sets zero-valued fields to default values appropriate for IMDS +func setIMDSRetryOptionDefaults(o *policy.RetryOptions) { + if o.MaxRetries == 0 { + o.MaxRetries = 6 + } + if o.MaxRetryDelay == 0 { + o.MaxRetryDelay = 25 * time.Second + } + if o.RetryDelay == 0 { + o.RetryDelay = 2 * time.Second + } + if o.StatusCodes == nil { + o.StatusCodes = []int{ + // IMDS docs recommend retrying 404, 410, 429 and 5xx + // https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#error-handling + http.StatusNotFound, // 404 + http.StatusGone, // 410 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusNotImplemented, // 501 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + http.StatusHTTPVersionNotSupported, // 505 + http.StatusVariantAlsoNegotiates, // 506 + http.StatusInsufficientStorage, // 507 + http.StatusLoopDetected, // 508 + http.StatusNotExtended, // 510 + http.StatusNetworkAuthenticationRequired, // 511 + } + } + if o.TryTimeout == 0 { + o.TryTimeout = 1 * time.Minute + } +} + +// newManagedIdentityClient creates a new instance of the ManagedIdentityClient with the ManagedIdentityCredentialOptions +// that are passed into it along with a default pipeline. +// options: ManagedIdentityCredentialOptions configure policies for the pipeline and the authority host that +// will be used to retrieve tokens and authenticate +func newManagedIdentityClient(options *ManagedIdentityCredentialOptions) (*managedIdentityClient, error) { + if options == nil { + options = &ManagedIdentityCredentialOptions{} + } + cp := options.ClientOptions + 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) + } + + c.azClient, err = azcore.NewClient(module, version, azruntime.PipelineOptions{ + Tracing: azruntime.TracingOptions{ + Namespace: traceNamespace, + }, + }, &cp) + if err != nil { + return nil, err + } + + 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) { + 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 +} + +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) 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 { + // send a malformed request (no Metadata header) to IMDS to determine whether the endpoint is available + cx, cancel := context.WithTimeout(ctx, imdsProbeTimeout) + defer cancel() + cx = policy.WithRetryOptions(cx, policy.RetryOptions{MaxRetries: -1}) + req, err := azruntime.NewRequest(cx, http.MethodGet, imdsEndpoint) + if err != nil { + return azcore.AccessToken{}, fmt.Errorf("failed to create IMDS probe request: %s", err) + } + if _, err = c.azClient.Pipeline().Do(req); err != nil { + msg := err.Error() + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + msg = "managed identity timed out. See https://aka.ms/azsdk/go/identity/troubleshoot#dac for more information" + } + return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, msg) + } + // send normal token requests from now on because something responded + c.probeIMDS = false + } + + 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 + } + 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 + return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, err.Error()) + } + resp := getResponseFromError(err) + if resp == nil { + return azcore.AccessToken{}, newAuthenticationFailedErrorFromMSAL(credNameManagedIdentity, err) + } + switch resp.StatusCode { + case http.StatusBadRequest: + 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" + if body, err := azruntime.Payload(resp); err == nil && len(body) > 0 { + msg += fmt.Sprintf(". The endpoint responded with %s", body) + } + return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, msg) + case http.StatusForbidden: + // Docker Desktop runs a proxy that responds 403 to IMDS token requests. If we get that response, + // we return credentialUnavailableError so credential chains continue to their next credential + body, err := azruntime.Payload(resp) + if err == nil && strings.Contains(string(body), "unreachable") { + return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, fmt.Sprintf("unexpected response %q", string(body))) + } + } + } + err = newAuthenticationFailedErrorFromMSAL(credNameManagedIdentity, err) + return azcore.AccessToken{}, err +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_credential.go new file mode 100644 index 000000000..11b686ccd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_credential.go @@ -0,0 +1,142 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "fmt" + "strings" + + "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 credNameManagedIdentity = "ManagedIdentityCredential" + +type managedIdentityIDKind int + +const ( + miClientID managedIdentityIDKind = iota + miObjectID + miResourceID +) + +// ManagedIDKind identifies the ID of a managed identity as either a client or resource ID +type ManagedIDKind interface { + fmt.Stringer + idKind() managedIdentityIDKind +} + +// ClientID is the client ID of a user-assigned managed identity. [NewManagedIdentityCredential] +// returns an error when a ClientID is specified on the following platforms: +// +// - Azure Arc +// - Cloud Shell +// - Service Fabric +type ClientID string + +func (ClientID) idKind() managedIdentityIDKind { + return miClientID +} + +// String returns the string value of the ID. +func (c ClientID) String() string { + return string(c) +} + +// ObjectID is the object ID of a user-assigned managed identity. [NewManagedIdentityCredential] +// returns an error when an ObjectID is specified on the following platforms: +// +// - Azure Arc +// - Azure ML +// - Cloud Shell +// - Service Fabric +type ObjectID string + +func (ObjectID) idKind() managedIdentityIDKind { + return miObjectID +} + +// String returns the string value of the ID. +func (o ObjectID) String() string { + return string(o) +} + +// ResourceID is the resource ID of a user-assigned managed identity. [NewManagedIdentityCredential] +// returns an error when a ResourceID is specified on the following platforms: +// +// - Azure Arc +// - Azure ML +// - Cloud Shell +// - Service Fabric +type ResourceID string + +func (ResourceID) idKind() managedIdentityIDKind { + return miResourceID +} + +// String returns the string value of the ID. +func (r ResourceID) String() string { + return string(r) +} + +// ManagedIdentityCredentialOptions contains optional parameters for ManagedIdentityCredential. +type ManagedIdentityCredentialOptions struct { + azcore.ClientOptions + + // ID of a managed identity the credential should authenticate. Set this field to use a specific identity instead of + // the hosting environment's default. The value may be the identity's client, object, or resource ID. + // NewManagedIdentityCredential returns an error when the hosting environment doesn't support user-assigned managed + // identities, or the specified kind of ID. + ID ManagedIDKind + + // dac indicates whether the credential is part of DefaultAzureCredential. When true, and the environment doesn't have + // configuration for a specific managed identity API, the credential tries to determine whether IMDS is available before + // sending its first token request. It does this by sending a malformed request with a short timeout. Any response to that + // request is taken to mean IMDS is available, in which case the credential will send ordinary token requests thereafter + // with no special timeout. The purpose of this behavior is to prevent a very long timeout when IMDS isn't available. + dac bool +} + +// 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. +// +// [Azure managed identity]: https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview +type ManagedIdentityCredential struct { + mic *managedIdentityClient +} + +// NewManagedIdentityCredential creates a ManagedIdentityCredential. Pass nil to accept default options. +func NewManagedIdentityCredential(options *ManagedIdentityCredentialOptions) (*ManagedIdentityCredential, error) { + if options == nil { + options = &ManagedIdentityCredentialOptions{} + } + mic, err := newManagedIdentityClient(options) + if err != nil { + return nil, err + } + 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.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 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.mic.GetToken(ctx, opts) +} + +var _ azcore.TokenCredential = (*ManagedIdentityCredential)(nil) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/on_behalf_of_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/on_behalf_of_credential.go new file mode 100644 index 000000000..9dcc82f01 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/on_behalf_of_credential.go @@ -0,0 +1,113 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "crypto" + "crypto/x509" + "errors" + + "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 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 [Microsoft Entra ID documentation] for more details. +// +// [Microsoft Entra ID documentation]: https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow +type OnBehalfOfCredential struct { + client *confidentialClient +} + +// OnBehalfOfCredentialOptions contains optional parameters for OnBehalfOfCredential +type OnBehalfOfCredentialOptions struct { + azcore.ClientOptions + + // 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 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 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. + SendCertificateChain bool +} + +// NewOnBehalfOfCredentialWithCertificate constructs an OnBehalfOfCredential that authenticates with a certificate. +// See [ParseCertificates] for help loading a certificate. +func NewOnBehalfOfCredentialWithCertificate(tenantID, clientID, userAssertion string, certs []*x509.Certificate, key crypto.PrivateKey, options *OnBehalfOfCredentialOptions) (*OnBehalfOfCredential, error) { + cred, err := confidential.NewCredFromCert(certs, key) + if err != nil { + return nil, err + } + return newOnBehalfOfCredential(tenantID, clientID, userAssertion, cred, options) +} + +// NewOnBehalfOfCredentialWithClientAssertions constructs an OnBehalfOfCredential that authenticates with client assertions. +// userAssertion is the user's access token for the application. The getAssertion function should return client assertions +// that authenticate the application to Microsoft Entra ID, such as federated credentials. +func NewOnBehalfOfCredentialWithClientAssertions(tenantID, clientID, userAssertion string, getAssertion func(context.Context) (string, error), options *OnBehalfOfCredentialOptions) (*OnBehalfOfCredential, error) { + if getAssertion == nil { + return nil, errors.New("getAssertion can't be nil. It must be a function that returns client assertions") + } + cred := confidential.NewCredFromAssertionCallback(func(ctx context.Context, _ confidential.AssertionRequestOptions) (string, error) { + return getAssertion(ctx) + }) + return newOnBehalfOfCredential(tenantID, clientID, userAssertion, cred, options) +} + +// NewOnBehalfOfCredentialWithSecret constructs an OnBehalfOfCredential that authenticates with a client secret. +func NewOnBehalfOfCredentialWithSecret(tenantID, clientID, userAssertion, clientSecret string, options *OnBehalfOfCredentialOptions) (*OnBehalfOfCredential, error) { + cred, err := confidential.NewCredFromSecret(clientSecret) + if err != nil { + return nil, err + } + return newOnBehalfOfCredential(tenantID, clientID, userAssertion, cred, options) +} + +func newOnBehalfOfCredential(tenantID, clientID, userAssertion string, cred confidential.Credential, options *OnBehalfOfCredentialOptions) (*OnBehalfOfCredential, error) { + if options == nil { + options = &OnBehalfOfCredentialOptions{} + } + opts := confidentialClientOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Assertion: userAssertion, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + SendX5C: options.SendCertificateChain, + } + c, err := newConfidentialClient(tenantID, clientID, credNameOBO, cred, opts) + if err != nil { + return nil, err + } + return &OnBehalfOfCredential{c}, nil +} + +// 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) { + 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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/public_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/public_client.go new file mode 100644 index 000000000..053d1785f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/public_client.go @@ -0,0 +1,269 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +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 + Cache Cache + DeviceCodePrompt func(context.Context, DeviceCodeMessage) error + DisableAutomaticAuthentication bool + DisableInstanceDiscovery bool + LoginHint, RedirectURL string + Record AuthenticationRecord + Username, Password string +} + +// publicClient wraps the MSAL public client +type publicClient struct { + 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 + } + host, err := setAuthorityHost(o.Cloud) + 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{}, + 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 { + return azcore.AccessToken{}, fmt.Errorf("%s.GetToken() requires at least one scope", p.name) + } + tenant, err := p.resolveTenant(tro.TenantID) + if err != nil { + return azcore.AccessToken{}, err + } + client, mu, err := p.client(tro) + if err != nil { + return azcore.AccessToken{}, err + } + mu.Lock() + defer mu.Unlock() + 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{}, newAuthenticationRequiredError(p.name, tro) + } + return p.reqToken(ctx, client, tro) +} + +// reqToken requests a token from the MSAL public client. It's separate from GetToken() to enable Authenticate() to bypass the cache. +func (p *publicClient) reqToken(ctx context.Context, c msalPublicClient, tro policy.TokenRequestOptions) (azcore.AccessToken, error) { + tenant, err := p.resolveTenant(tro.TenantID) + if err != nil { + return azcore.AccessToken{}, err + } + var ar public.AuthResult + switch p.name { + case credNameBrowser: + ar, err = c.AcquireTokenInteractive(ctx, tro.Scopes, + public.WithClaims(tro.Claims), + public.WithLoginHint(p.opts.LoginHint), + public.WithRedirectURI(p.opts.RedirectURL), + public.WithTenantID(tenant), + ) + case credNameDeviceCode: + dc, e := c.AcquireTokenByDeviceCode(ctx, tro.Scopes, public.WithClaims(tro.Claims), public.WithTenantID(tenant)) + if e != nil { + return azcore.AccessToken{}, e + } + err = p.opts.DeviceCodePrompt(ctx, DeviceCodeMessage{ + Message: dc.Result.Message, + UserCode: dc.Result.UserCode, + VerificationURL: dc.Result.VerificationURL, + }) + if err == nil { + ar, err = dc.AuthenticationResult(ctx) + } + case credNameUserPassword: + ar, err = c.AcquireTokenByUsernamePassword(ctx, tro.Scopes, p.opts.Username, p.opts.Password, public.WithClaims(tro.Claims), public.WithTenantID(tenant)) + default: + return azcore.AccessToken{}, fmt.Errorf("unknown credential %q", p.name) + } + return p.token(ar, err) +} + +func (p *publicClient) client(tro policy.TokenRequestOptions) (msalPublicClient, *sync.Mutex, error) { + p.clientMu.Lock() + defer p.clientMu.Unlock() + if tro.EnableCAE { + if p.cae == nil { + client, err := p.newMSALClient(true) + if err != nil { + return nil, nil, err + } + p.cae = client + } + return p.cae, p.caeMu, nil + } + if p.noCAE == nil { + client, err := p.newMSALClient(false) + if err != nil { + return nil, nil, err + } + p.noCAE = client + } + return p.noCAE, p.noCAEMu, nil +} + +func (p *publicClient) newMSALClient(enableCAE bool) (msalPublicClient, error) { + c, err := internal.ExportReplace(p.opts.Cache, enableCAE) + if err != nil { + return nil, err + } + o := []public.Option{ + public.WithAuthority(runtime.JoinPaths(p.host, p.tenantID)), + public.WithCache(c), + public.WithHTTPClient(p), + } + if enableCAE { + o = append(o, public.WithClientCapabilities(cp1)) + } + if p.opts.DisableInstanceDiscovery || strings.ToLower(p.tenantID) == "adfs" { + o = append(o, public.WithInstanceDiscovery(false)) + } + return public.New(p.clientID, o...) +} + +func (p *publicClient) token(ar public.AuthResult, err error) (azcore.AccessToken, error) { + if err == nil { + msg := fmt.Sprintf(scopeLogFmt, p.name, strings.Join(ar.GrantedScopes, ", ")) + log.Write(EventAuthentication, msg) + p.record, err = newAuthenticationRecord(ar) + } else { + err = newAuthenticationFailedErrorFromMSAL(p.name, 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 +// configuration, or an error when that configuration doesn't allow the specified tenant +func (p *publicClient) resolveTenant(specified string) (string, error) { + 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) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1 b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1 new file mode 100644 index 000000000..c5634cd21 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1 @@ -0,0 +1,168 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# IMPORTANT: Do not invoke this file directly. Please instead run eng/common/TestResources/New-TestResources.ps1 from the repository root. + +param ( + [hashtable] $AdditionalParameters = @{}, + [hashtable] $DeploymentOutputs, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $SubscriptionId, + + [Parameter(ParameterSetName = 'Provisioner', Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $TenantId, + + [Parameter()] + [ValidatePattern('^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$')] + [string] $TestApplicationId, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [string] $Environment, + + # Captures any arguments from eng/New-TestResources.ps1 not declared here (no parameter errors). + [Parameter(ValueFromRemainingArguments = $true)] + $RemainingArguments +) + +$ErrorActionPreference = 'Stop' +$PSNativeCommandUseErrorActionPreference = $true + +if ($CI) { + if (!$AdditionalParameters['deployResources']) { + Write-Host "Skipping post-provisioning script because resources weren't deployed" + return + } + az cloud set -n $Environment + az login --federated-token $env:ARM_OIDC_TOKEN --service-principal -t $TenantId -u $TestApplicationId + az account set --subscription $SubscriptionId +} + +Write-Host "##[group]Building container" +$image = "$($DeploymentOutputs['AZIDENTITY_ACR_LOGIN_SERVER'])/azidentity-managed-id-test" +Set-Content -Path "$PSScriptRoot/Dockerfile" -Value @" +FROM mcr.microsoft.com/oss/go/microsoft/golang:latest AS builder +ENV GOARCH=amd64 GOWORK=off +COPY . /azidentity +WORKDIR /azidentity/testdata/managed-id-test +RUN go mod tidy +RUN go build -o /build/managed-id-test . +RUN GOOS=windows go build -o /build/managed-id-test.exe . + +FROM mcr.microsoft.com/mirror/docker/library/alpine:3.16 +RUN apk add gcompat +COPY --from=builder /build/* . +RUN chmod +x managed-id-test +CMD ["./managed-id-test"] +"@ +# build from sdk/azidentity because we need that dir in the context (because the test app uses local azidentity) +docker build -t $image "$PSScriptRoot" +az acr login -n $DeploymentOutputs['AZIDENTITY_ACR_NAME'] +docker push $image +Write-Host "##[endgroup]" + +$rg = $DeploymentOutputs['AZIDENTITY_RESOURCE_GROUP'] + +Write-Host "##[group]Deploying to VM" +# az will return 0 when the script fails on the VM, so the script prints a UUID to indicate all commands succeeded +$uuid = [guid]::NewGuid().ToString() +$vmScript = @" +az acr login -n $($DeploymentOutputs['AZIDENTITY_ACR_NAME']) && \ +sudo docker run \ +-e AZIDENTITY_STORAGE_NAME=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME']) \ +-e AZIDENTITY_STORAGE_NAME_USER_ASSIGNED=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME_USER_ASSIGNED']) \ +-e AZIDENTITY_USER_ASSIGNED_IDENTITY=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) \ +-e AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID']) \ +-e AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID']) \ +-p 80:8080 -d \ +$image && \ +/usr/bin/echo $uuid +"@ +$output = az vm run-command invoke -g $rg -n $DeploymentOutputs['AZIDENTITY_VM_NAME'] --command-id RunShellScript --scripts "$vmScript" | Out-String +Write-Host $output +if (-not $output.Contains($uuid)) { + throw "couldn't start container on VM" +} +Write-Host "##[endgroup]" + +# ACI is easier to provision here than in the bicep file because the image isn't available before now +Write-Host "##[group]Deploying Azure Container Instance" +$aciName = "azidentity-test" +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" ` + --scope $($DeploymentOutputs['AZIDENTITY_STORAGE_ID']) ` + -e AZIDENTITY_STORAGE_NAME=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME']) ` + AZIDENTITY_STORAGE_NAME_USER_ASSIGNED=$($DeploymentOutputs['AZIDENTITY_STORAGE_NAME_USER_ASSIGNED']) ` + AZIDENTITY_USER_ASSIGNED_IDENTITY=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) ` + 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 +$aciIP = az container show -g $rg -n $aciName --query ipAddress.ip --output tsv +Write-Host "##vso[task.setvariable variable=AZIDENTITY_ACI_IP;]$aciIP" +Write-Host "##[endgroup]" + +# Azure Functions deployment: copy the Windows binary from the Docker image, deploy it in a zip +Write-Host "##[group]Deploying to Azure Functions" +$container = docker create $image +docker cp ${container}:managed-id-test.exe "$PSScriptRoot/testdata/managed-id-test/" +docker rm -v $container +Compress-Archive -Path "$PSScriptRoot/testdata/managed-id-test/*" -DestinationPath func.zip -Force +az functionapp deploy -g $rg -n $DeploymentOutputs['AZIDENTITY_FUNCTION_NAME'] --src-path func.zip --type zip +Write-Host "##[endgroup]" + +Write-Host "##[group]Creating federated identity" +$aksName = $DeploymentOutputs['AZIDENTITY_AKS_NAME'] +$idName = $DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_NAME'] +$issuer = az aks show -g $rg -n $aksName --query "oidcIssuerProfile.issuerUrl" -otsv +$podName = "azidentity-test" +$serviceAccountName = "workload-identity-sa" +az identity federated-credential create -g $rg --identity-name $idName --issuer $issuer --name $idName --subject system:serviceaccount:default:$serviceAccountName --audiences api://AzureADTokenExchange +Write-Host "##[endgroup]" + +Write-Host "##[group]Deploying to AKS" +az aks get-credentials -g $rg -n $aksName +az aks update --attach-acr $DeploymentOutputs['AZIDENTITY_ACR_NAME'] -g $rg -n $aksName +Set-Content -Path "$PSScriptRoot/k8s.yaml" -Value @" +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + azure.workload.identity/client-id: $($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID']) + name: $serviceAccountName + namespace: default +--- +apiVersion: v1 +kind: Pod +metadata: + name: $podName + namespace: default + labels: + app: $podName + azure.workload.identity/use: "true" +spec: + serviceAccountName: $serviceAccountName + containers: + - name: $podName + image: $image + env: + - name: AZIDENTITY_STORAGE_NAME + value: $($DeploymentOutputs['AZIDENTITY_STORAGE_NAME_USER_ASSIGNED']) + - name: AZIDENTITY_USE_WORKLOAD_IDENTITY + value: "true" + - name: FUNCTIONS_CUSTOMHANDLER_PORT + value: "80" + nodeSelector: + kubernetes.io/os: linux +"@ +kubectl apply -f "$PSScriptRoot/k8s.yaml" +Write-Host "##vso[task.setvariable variable=AZIDENTITY_POD_NAME;]$podName" +Write-Host "##[endgroup]" diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-pre.ps1 b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-pre.ps1 new file mode 100644 index 000000000..58766d0a0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-pre.ps1 @@ -0,0 +1,44 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +# IMPORTANT: Do not invoke this file directly. Please instead run eng/common/TestResources/New-TestResources.ps1 from the repository root. + +[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] +param ( + [hashtable] $AdditionalParameters = @{}, + + # Captures any arguments from eng/New-TestResources.ps1 not declared here (no parameter errors). + [Parameter(ValueFromRemainingArguments = $true)] + $RemainingArguments +) + +if (-not (Test-Path "$PSScriptRoot/sshkey.pub")) { + ssh-keygen -t rsa -b 4096 -f "$PSScriptRoot/sshkey" -N '' -C '' +} +$templateFileParameters['sshPubKey'] = Get-Content "$PSScriptRoot/sshkey.pub" + +if (!$CI) { + # TODO: Remove this once auto-cloud config downloads are supported locally + Write-Host "Skipping cert setup in local testing mode" + return +} + +if ($null -eq $EnvironmentVariables -or $EnvironmentVariables.Count -eq 0) { + throw "EnvironmentVariables must be set in the calling script New-TestResources.ps1" +} + +$tmp = $env:TEMP ? $env:TEMP : [System.IO.Path]::GetTempPath() +$pfxPath = Join-Path $tmp "test.pfx" +$pemPath = Join-Path $tmp "test.pem" + +Write-Host "Creating identity test files: $pfxPath $pemPath" + +[System.Convert]::FromBase64String($EnvironmentVariables['PFX_CONTENTS']) | Set-Content -Path $pfxPath -AsByteStream +Set-Content -Path $pemPath -Value $EnvironmentVariables['PEM_CONTENTS'] + +# Set for pipeline +Write-Host "##vso[task.setvariable variable=IDENTITY_SP_CERT_PFX;]$pfxPath" +Write-Host "##vso[task.setvariable variable=IDENTITY_SP_CERT_PEM;]$pemPath" +# Set for local +$env:IDENTITY_SP_CERT_PFX = $pfxPath +$env:IDENTITY_SP_CERT_PEM = $pemPath diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep new file mode 100644 index 000000000..cb3b5f4df --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources.bicep @@ -0,0 +1,390 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +@description('Kubernetes cluster admin user name.') +param adminUser string = 'azureuser' + +@minLength(6) +@maxLength(23) +@description('The base resource name.') +param baseName string = resourceGroup().name + +@description('Whether to deploy resources. When set to false, this file deploys nothing.') +param deployResources bool = false + +param sshPubKey string = '' + +@description('The location of the resource. By default, this is the same as the resource group.') +param location string = resourceGroup().location + +// https://learn.microsoft.com/azure/role-based-access-control/built-in-roles +var acrPull = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') +var blobReader = subscriptionResourceId( + 'Microsoft.Authorization/roleDefinitions', + '2a2b9908-6ea1-4ae2-8e65-a410df84e7d1' +) + +resource sa 'Microsoft.Storage/storageAccounts@2021-08-01' = if (deployResources) { + kind: 'StorageV2' + location: location + name: 'sa${uniqueString(baseName)}' + properties: { + accessTier: 'Hot' + } + sku: { + name: 'Standard_LRS' + } +} + +resource saUserAssigned 'Microsoft.Storage/storageAccounts@2021-08-01' = if (deployResources) { + kind: 'StorageV2' + location: location + name: 'sa2${uniqueString(baseName)}' + properties: { + accessTier: 'Hot' + } + sku: { + name: 'Standard_LRS' + } +} + +resource usermgdid 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = if (deployResources) { + location: location + name: baseName +} + +resource acrPullContainerInstance 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) { + name: guid(resourceGroup().id, acrPull, 'containerInstance') + properties: { + principalId: deployResources ? usermgdid.properties.principalId : '' + principalType: 'ServicePrincipal' + roleDefinitionId: acrPull + } + scope: containerRegistry +} + +resource acrPullVM 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) { + name: guid(resourceGroup().id, acrPull, 'vm') + properties: { + principalId: deployResources ? vm.identity.principalId : '' + principalType: 'ServicePrincipal' + roleDefinitionId: acrPull + } + scope: containerRegistry +} + +resource blobRoleUserAssigned 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) { + scope: saUserAssigned + name: guid(resourceGroup().id, blobReader, usermgdid.id) + properties: { + principalId: deployResources ? usermgdid.properties.principalId : '' + principalType: 'ServicePrincipal' + roleDefinitionId: blobReader + } +} + +resource blobRoleFunc 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) { + name: guid(resourceGroup().id, blobReader, 'azfunc') + properties: { + principalId: deployResources ? azfunc.identity.principalId : '' + roleDefinitionId: blobReader + principalType: 'ServicePrincipal' + } + scope: sa +} + +resource blobRoleVM 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (deployResources) { + scope: sa + name: guid(resourceGroup().id, blobReader, 'vm') + properties: { + principalId: deployResources ? vm.identity.principalId : '' + roleDefinitionId: blobReader + principalType: 'ServicePrincipal' + } +} + +resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = if (deployResources) { + location: location + name: uniqueString(resourceGroup().id) + properties: { + adminUserEnabled: true + } + sku: { + name: 'Basic' + } +} + +resource farm 'Microsoft.Web/serverfarms@2021-03-01' = if (deployResources) { + kind: 'app' + location: location + name: '${baseName}_asp' + properties: {} + sku: { + capacity: 1 + family: 'B' + name: 'B1' + size: 'B1' + tier: 'Basic' + } +} + +resource azfunc 'Microsoft.Web/sites@2021-03-01' = if (deployResources) { + identity: { + type: 'SystemAssigned, UserAssigned' + userAssignedIdentities: { + '${deployResources ? usermgdid.id : ''}': {} + } + } + kind: 'functionapp' + location: location + name: '${baseName}func' + properties: { + enabled: true + httpsOnly: true + keyVaultReferenceIdentity: 'SystemAssigned' + serverFarmId: farm.id + siteConfig: { + alwaysOn: true + appSettings: [ + { + name: 'AZIDENTITY_STORAGE_NAME' + value: deployResources ? sa.name : null + } + { + name: 'AZIDENTITY_STORAGE_NAME_USER_ASSIGNED' + value: deployResources ? saUserAssigned.name : null + } + { + name: 'AZIDENTITY_USER_ASSIGNED_IDENTITY' + value: deployResources ? usermgdid.id : null + } + { + name: 'AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID' + value: deployResources ? usermgdid.properties.clientId : null + } + { + name: 'AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID' + value: deployResources ? usermgdid.properties.principalId : null + } + { + name: 'AzureWebJobsStorage' + value: 'DefaultEndpointsProtocol=https;AccountName=${deployResources ? sa.name : ''};EndpointSuffix=${deployResources ? environment().suffixes.storage : ''};AccountKey=${deployResources ? sa.listKeys().keys[0].value : ''}' + } + { + name: 'FUNCTIONS_EXTENSION_VERSION' + value: '~4' + } + { + name: 'FUNCTIONS_WORKER_RUNTIME' + value: 'custom' + } + { + name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING' + value: 'DefaultEndpointsProtocol=https;AccountName=${deployResources ? sa.name : ''};EndpointSuffix=${deployResources ? environment().suffixes.storage : ''};AccountKey=${deployResources ? sa.listKeys().keys[0].value : ''}' + } + { + name: 'WEBSITE_CONTENTSHARE' + value: toLower('${baseName}-func') + } + ] + http20Enabled: true + minTlsVersion: '1.2' + } + } +} + +resource aks 'Microsoft.ContainerService/managedClusters@2023-06-01' = if (deployResources) { + name: baseName + location: location + identity: { + type: 'SystemAssigned' + } + properties: { + agentPoolProfiles: [ + { + count: 1 + enableAutoScaling: false + kubeletDiskType: 'OS' + mode: 'System' + name: 'agentpool' + osDiskSizeGB: 128 + osDiskType: 'Managed' + osSKU: 'Ubuntu' + osType: 'Linux' + type: 'VirtualMachineScaleSets' + vmSize: 'Standard_D2s_v3' + } + ] + dnsPrefix: 'identitytest' + enableRBAC: true + linuxProfile: { + adminUsername: adminUser + ssh: { + publicKeys: [ + { + keyData: sshPubKey + } + ] + } + } + oidcIssuerProfile: { + enabled: true + } + securityProfile: { + workloadIdentity: { + enabled: true + } + } + } +} + +resource publicIP 'Microsoft.Network/publicIPAddresses@2023-05-01' = if (deployResources) { + name: '${baseName}PublicIP' + location: location + sku: { + name: 'Standard' + } + properties: { + publicIPAllocationMethod: 'Static' + } +} + +resource nsg 'Microsoft.Network/networkSecurityGroups@2024-07-01' = if (deployResources) { + name: '${baseName}NSG' + location: location + properties: { + securityRules: [ + { + name: 'AllowHTTP' + properties: { + description: 'Allow HTTP traffic on port 80' + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '80' + sourceAddressPrefix: '*' + destinationAddressPrefix: '*' + access: 'Allow' + priority: 1000 + direction: 'Inbound' + } + } + ] + } +} + +resource vnet 'Microsoft.Network/virtualNetworks@2024-07-01' = if (deployResources) { + name: '${baseName}vnet' + location: location + properties: { + addressSpace: { + addressPrefixes: [ + '10.0.0.0/16' + ] + } + subnets: [ + { + name: '${baseName}subnet' + properties: { + addressPrefix: '10.0.0.0/24' + defaultOutboundAccess: false + networkSecurityGroup: { + id: deployResources ? nsg.id : '' + } + } + } + ] + } +} + +resource nic 'Microsoft.Network/networkInterfaces@2024-07-01' = if (deployResources) { + name: '${baseName}NIC' + location: location + properties: { + ipConfigurations: [ + { + name: 'myIPConfig' + properties: { + privateIPAllocationMethod: 'Dynamic' + publicIPAddress: { + id: deployResources ? publicIP.id : '' + } + subnet: { + id: deployResources ? vnet.properties.subnets[0].id : '' + } + } + } + ] + } +} + +resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = if (deployResources) { + name: '${baseName}vm' + location: location + identity: { + type: 'SystemAssigned, UserAssigned' + userAssignedIdentities: { + '${deployResources ? usermgdid.id: ''}': {} + } + } + properties: { + hardwareProfile: { + vmSize: 'Standard_DS1_v2' + } + osProfile: { + adminUsername: adminUser + computerName: '${baseName}vm' + customData: base64(''' +#cloud-config +package_update: true +packages: + - docker.io +runcmd: + - curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + - az login --identity --allow-no-subscriptions +''') + linuxConfiguration: { + disablePasswordAuthentication: true + ssh: { + publicKeys: [ + { + path: '/home/${adminUser}/.ssh/authorized_keys' + keyData: sshPubKey + } + ] + } + } + } + networkProfile: { + networkInterfaces: [ + { + id: deployResources ? nic.id : '' + } + ] + } + storageProfile: { + imageReference: { + publisher: 'Canonical' + offer: 'ubuntu-24_04-lts' + sku: 'server' + version: 'latest' + } + osDisk: { + createOption: 'FromImage' + } + } + } +} + +output AZIDENTITY_ACR_LOGIN_SERVER string = deployResources ? containerRegistry.properties.loginServer : '' +output AZIDENTITY_ACR_NAME string = deployResources ? containerRegistry.name : '' +output AZIDENTITY_AKS_NAME string = deployResources ? aks.name : '' +output AZIDENTITY_FUNCTION_NAME string = deployResources ? azfunc.name : '' +output AZIDENTITY_STORAGE_ID string = deployResources ? sa.id : '' +output AZIDENTITY_STORAGE_NAME string = deployResources ? sa.name : '' +output AZIDENTITY_STORAGE_NAME_USER_ASSIGNED string = deployResources ? saUserAssigned.name : '' +output AZIDENTITY_USER_ASSIGNED_IDENTITY string = deployResources ? usermgdid.id : '' +output AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID string = deployResources ? usermgdid.properties.clientId : '' +output AZIDENTITY_USER_ASSIGNED_IDENTITY_NAME string = deployResources ? usermgdid.name : '' +output AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID string = deployResources ? usermgdid.properties.principalId : '' +output AZIDENTITY_VM_NAME string = deployResources ? vm.name : '' +output AZIDENTITY_VM_IP string = deployResources ? publicIP.properties.ipAddress : '' diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/username_password_credential.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/username_password_credential.go new file mode 100644 index 000000000..5791e7d22 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/username_password_credential.go @@ -0,0 +1,102 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + + "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" + +// 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 + + // 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 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 + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // 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 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 +} + +// 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 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 +} + +// NewUsernamePasswordCredential creates a UsernamePasswordCredential. clientID is the ID of the application the user +// will authenticate to. Pass nil for options to accept defaults. +func NewUsernamePasswordCredential(tenantID string, clientID string, username string, password string, options *UsernamePasswordCredentialOptions) (*UsernamePasswordCredential, error) { + if options == nil { + options = &UsernamePasswordCredentialOptions{} + } + opts := publicClientOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Cache: options.Cache, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + Password: password, + Record: options.AuthenticationRecord, + Username: username, + } + c, err := newPublicClient(tenantID, clientID, credNameUserPassword, opts) + if err != nil { + return nil, err + } + return &UsernamePasswordCredential{client: c}, err +} + +// 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) { + 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) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go new file mode 100644 index 000000000..4c8860536 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go @@ -0,0 +1,18 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +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.12.0" +) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/workload_identity.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/workload_identity.go new file mode 100644 index 000000000..6fecada2f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/workload_identity.go @@ -0,0 +1,141 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package azidentity + +import ( + "context" + "errors" + "os" + "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/azcore/runtime" +) + +const credNameWorkloadIdentity = "WorkloadIdentityCredential" + +// WorkloadIdentityCredential supports Azure workload identity on Kubernetes. +// See [Azure Kubernetes Service documentation] for more information. +// +// [Azure Kubernetes Service documentation]: https://learn.microsoft.com/azure/aks/workload-identity-overview +type WorkloadIdentityCredential struct { + assertion, file string + cred *ClientAssertionCredential + expires time.Time + mtx *sync.RWMutex +} + +// WorkloadIdentityCredentialOptions contains optional parameters for WorkloadIdentityCredential. +type WorkloadIdentityCredentialOptions struct { + azcore.ClientOptions + + // 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 in which the + // application is registered. + AdditionallyAllowedTenants []string + + // Cache is a persistent cache the credential will use to store the tokens it acquires, making + // them available to other processes and credential instances. The default, zero value means the + // credential will store tokens in memory and not share them with any other credential instance. + Cache Cache + + // 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 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 of the service principal. Defaults to the value of the environment variable AZURE_TENANT_ID. + TenantID string + + // TokenFilePath is the path of a file containing a Kubernetes service account token. Defaults to the value of the + // environment variable AZURE_FEDERATED_TOKEN_FILE. + TokenFilePath string +} + +// NewWorkloadIdentityCredential constructs a WorkloadIdentityCredential. Service principal configuration is read +// from environment variables as set by the Azure workload identity webhook. Set options to override those values. +func NewWorkloadIdentityCredential(options *WorkloadIdentityCredentialOptions) (*WorkloadIdentityCredential, error) { + if options == nil { + options = &WorkloadIdentityCredentialOptions{} + } + ok := false + clientID := options.ClientID + if clientID == "" { + if clientID, ok = os.LookupEnv(azureClientID); !ok { + return nil, errors.New("no client ID specified. Check pod configuration or set ClientID in the options") + } + } + file := options.TokenFilePath + if file == "" { + if file, ok = os.LookupEnv(azureFederatedTokenFile); !ok { + return nil, errors.New("no token file specified. Check pod configuration or set TokenFilePath in the options") + } + } + tenantID := options.TenantID + if tenantID == "" { + if tenantID, ok = os.LookupEnv(azureTenantID); !ok { + return nil, errors.New("no tenant ID specified. Check pod configuration or set TenantID in the options") + } + } + w := WorkloadIdentityCredential{file: file, mtx: &sync.RWMutex{}} + caco := ClientAssertionCredentialOptions{ + AdditionallyAllowedTenants: options.AdditionallyAllowedTenants, + Cache: options.Cache, + ClientOptions: options.ClientOptions, + DisableInstanceDiscovery: options.DisableInstanceDiscovery, + } + cred, err := NewClientAssertionCredential(tenantID, clientID, w.getAssertion, &caco) + if err != nil { + return nil, err + } + // we want "WorkloadIdentityCredential" in log messages, not "ClientAssertionCredential" + cred.client.name = credNameWorkloadIdentity + w.cred = cred + return &w, nil +} + +// 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) { + 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. +// Kubernetes is responsible for updating the file as service account tokens expire. +func (w *WorkloadIdentityCredential) getAssertion(context.Context) (string, error) { + w.mtx.RLock() + if w.expires.Before(time.Now()) { + // ensure only one goroutine at a time updates the assertion + w.mtx.RUnlock() + w.mtx.Lock() + defer w.mtx.Unlock() + // double check because another goroutine may have acquired the write lock first and done the update + if now := time.Now(); w.expires.Before(now) { + content, err := os.ReadFile(w.file) + if err != nil { + return "", err + } + w.assertion = string(content) + // Kubernetes rotates service account tokens when they reach 80% of their total TTL. The shortest TTL + // is 1 hour. That implies the token we just read is valid for at least 12 minutes (20% of 1 hour), + // but we add some margin for safety. + w.expires = now.Add(10 * time.Minute) + } + } else { + defer w.mtx.RUnlock() + } + return w.assertion, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/LICENSE.txt new file mode 100644 index 000000000..48ea6616b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/diag/diag.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/diag/diag.go new file mode 100644 index 000000000..245af7d2b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/diag/diag.go @@ -0,0 +1,51 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package diag + +import ( + "fmt" + "runtime" + "strings" +) + +// Caller returns the file and line number of a frame on the caller's stack. +// If the funtion fails an empty string is returned. +// skipFrames - the number of frames to skip when determining the caller. +// Passing a value of 0 will return the immediate caller of this function. +func Caller(skipFrames int) string { + if pc, file, line, ok := runtime.Caller(skipFrames + 1); ok { + // the skipFrames + 1 is to skip ourselves + frame := runtime.FuncForPC(pc) + return fmt.Sprintf("%s()\n\t%s:%d", frame.Name(), file, line) + } + return "" +} + +// StackTrace returns a formatted stack trace string. +// If the funtion fails an empty string is returned. +// skipFrames - the number of stack frames to skip before composing the trace string. +// totalFrames - the maximum number of stack frames to include in the trace string. +func StackTrace(skipFrames, totalFrames int) string { + pcCallers := make([]uintptr, totalFrames) + if frames := runtime.Callers(skipFrames, pcCallers); frames == 0 { + return "" + } + frames := runtime.CallersFrames(pcCallers) + sb := strings.Builder{} + for { + frame, more := frames.Next() + sb.WriteString(frame.Function) + sb.WriteString("()\n\t") + sb.WriteString(frame.File) + sb.WriteRune(':') + sb.WriteString(fmt.Sprintf("%d\n", frame.Line)) + if !more { + break + } + } + return sb.String() +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/diag/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/diag/doc.go new file mode 100644 index 000000000..66bf13e5f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/diag/doc.go @@ -0,0 +1,7 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package diag diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/doc.go new file mode 100644 index 000000000..8c6eacb61 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/doc.go @@ -0,0 +1,7 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package errorinfo diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go new file mode 100644 index 000000000..779657b23 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo/errorinfo.go @@ -0,0 +1,52 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package errorinfo + +import "errors" + +// NonRetriable represents a non-transient error. This works in +// conjunction with the retry policy, indicating that the error condition +// is idempotent, so no retries will be attempted. +// Use errors.As() to access this interface in the error chain. +type NonRetriable interface { + error + NonRetriable() +} + +// NonRetriableError ensures the specified error is [NonRetriable]. If +// the error is already [NonRetriable], it returns that error unchanged. +// Otherwise, it returns a new, [NonRetriable] error. +func NonRetriableError(err error) error { + if !errors.As(err, new(NonRetriable)) { + err = &nonRetriableError{err} + } + return err +} + +// nonRetriableError is a struct that embeds the error interface. +// It is used to represent errors that should not be retried. +type nonRetriableError struct { + error +} + +// Error method for nonRetriableError struct. +// It returns the error message of the embedded error. +func (p *nonRetriableError) Error() string { + return p.error.Error() +} + +// NonRetriable is a marker method for nonRetriableError struct. +// Non-functional and indicates that the error is non-retriable. +func (*nonRetriableError) NonRetriable() { + // marker method +} + +// Unwrap method for nonRetriableError struct. +// It returns the original error that was marked as non-retriable. +func (p *nonRetriableError) Unwrap() error { + return p.error +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/exported/exported.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/exported/exported.go new file mode 100644 index 000000000..9948f604b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/exported/exported.go @@ -0,0 +1,129 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package exported + +import ( + "errors" + "io" + "net/http" +) + +// HasStatusCode returns true if the Response's status code is one of the specified values. +// Exported as runtime.HasStatusCode(). +func HasStatusCode(resp *http.Response, statusCodes ...int) bool { + if resp == nil { + return false + } + for _, sc := range statusCodes { + if resp.StatusCode == sc { + return true + } + } + return false +} + +// PayloadOptions contains the optional values for the Payload func. +// NOT exported but used by azcore. +type PayloadOptions struct { + // BytesModifier receives the downloaded byte slice and returns an updated byte slice. + // Use this to modify the downloaded bytes in a payload (e.g. removing a BOM). + BytesModifier func([]byte) []byte +} + +// Payload reads and returns the response body or an error. +// On a successful read, the response body is cached. +// Subsequent reads will access the cached value. +// 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 + } + + // r.Body won't be a nopClosingBytesReader if downloading was skipped + if buf, ok := resp.Body.(*nopClosingBytesReader); ok { + bytesBody := modifyBytes(buf.Bytes()) + buf.Set(bytesBody) + return bytesBody, nil + } + + bytesBody, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return nil, err + } + + bytesBody = modifyBytes(bytesBody) + resp.Body = &nopClosingBytesReader{s: bytesBody} + return bytesBody, nil +} + +// PayloadDownloaded returns true if the response body has already been downloaded. +// This implies that the Payload() func above has been previously called. +// NOT exported but used by azcore. +func PayloadDownloaded(resp *http.Response) bool { + _, ok := resp.Body.(*nopClosingBytesReader) + return ok +} + +// nopClosingBytesReader is an io.ReadSeekCloser around a byte slice. +// It also provides direct access to the byte slice to avoid rereading. +type nopClosingBytesReader struct { + s []byte + i int64 +} + +// Bytes returns the underlying byte slice. +func (r *nopClosingBytesReader) Bytes() []byte { + return r.s +} + +// Close implements the io.Closer interface. +func (*nopClosingBytesReader) Close() error { + return nil +} + +// Read implements the io.Reader interface. +func (r *nopClosingBytesReader) Read(b []byte) (n int, err error) { + if r.i >= int64(len(r.s)) { + return 0, io.EOF + } + n = copy(b, r.s[r.i:]) + r.i += int64(n) + return +} + +// Set replaces the existing byte slice with the specified byte slice and resets the reader. +func (r *nopClosingBytesReader) Set(b []byte) { + r.s = b + r.i = 0 +} + +// Seek implements the io.Seeker interface. +func (r *nopClosingBytesReader) Seek(offset int64, whence int) (int64, error) { + var i int64 + switch whence { + case io.SeekStart: + i = offset + case io.SeekCurrent: + i = r.i + offset + case io.SeekEnd: + i = int64(len(r.s)) + offset + default: + return 0, errors.New("nopClosingBytesReader: invalid whence") + } + if i < 0 { + return 0, errors.New("nopClosingBytesReader: negative position") + } + r.i = i + return i, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/doc.go new file mode 100644 index 000000000..d7876d297 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/doc.go @@ -0,0 +1,7 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package log diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/log.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/log.go new file mode 100644 index 000000000..76dadf7d3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/log.go @@ -0,0 +1,104 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package log + +import ( + "fmt" + "os" + "time" +) + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// NOTE: The following are exported as public surface area from azcore. DO NOT MODIFY +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// Event is used to group entries. Each group can be toggled on or off. +type Event string + +// SetEvents is used to control which events are written to +// the log. By default all log events are writen. +func SetEvents(cls ...Event) { + log.cls = cls +} + +// SetListener will set the Logger to write to the specified listener. +func SetListener(lst func(Event, string)) { + log.lst = lst +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// END PUBLIC SURFACE AREA +/////////////////////////////////////////////////////////////////////////////////////////////////// + +// Should returns true if the specified log event should be written to the log. +// By default all log events will be logged. Call SetEvents() to limit +// the log events for logging. +// If no listener has been set this will return false. +// Calling this method is useful when the message to log is computationally expensive +// and you want to avoid the overhead if its log event is not enabled. +func Should(cls Event) bool { + if log.lst == nil { + return false + } + if len(log.cls) == 0 { + return true + } + for _, c := range log.cls { + if c == cls { + return true + } + } + return false +} + +// Write invokes the underlying listener with the specified event and message. +// If the event shouldn't be logged or there is no listener then Write does nothing. +func Write(cls Event, message string) { + if !Should(cls) { + return + } + log.lst(cls, message) +} + +// Writef invokes the underlying listener with the specified event and formatted message. +// If the event shouldn't be logged or there is no listener then Writef does nothing. +func Writef(cls Event, format string, a ...interface{}) { + if !Should(cls) { + return + } + log.lst(cls, fmt.Sprintf(format, a...)) +} + +// TestResetEvents is used for TESTING PURPOSES ONLY. +func TestResetEvents() { + log.cls = nil +} + +// logger controls which events to log and writing to the underlying log. +type logger struct { + cls []Event + lst func(Event, string) +} + +// the process-wide logger +var log logger + +func init() { + initLogging() +} + +// split out for testing purposes +func initLogging() { + if cls := os.Getenv("AZURE_SDK_GO_LOGGING"); cls == "all" { + // cls could be enhanced to support a comma-delimited list of log events + log.lst = func(cls Event, msg string) { + // simple console logger, it writes to stderr in the following format: + // [time-stamp] Event: message + fmt.Fprintf(os.Stderr, "[%s] %s: %s\n", time.Now().Format(time.StampMicro), cls, msg) + } + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/poller/util.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/poller/util.go new file mode 100644 index 000000000..db8269627 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/poller/util.go @@ -0,0 +1,155 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package poller + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/exported" +) + +// the well-known set of LRO status/provisioning state values. +const ( + StatusSucceeded = "Succeeded" + StatusCanceled = "Canceled" + StatusFailed = "Failed" + StatusInProgress = "InProgress" +) + +// these are non-conformant states that we've seen in the wild. +// we support them for back-compat. +const ( + StatusCancelled = "Cancelled" + StatusCompleted = "Completed" +) + +// IsTerminalState returns true if the LRO's state is terminal. +func IsTerminalState(s string) bool { + return Failed(s) || Succeeded(s) +} + +// Failed returns true if the LRO's state is terminal failure. +func Failed(s string) bool { + return strings.EqualFold(s, StatusFailed) || strings.EqualFold(s, StatusCanceled) || strings.EqualFold(s, StatusCancelled) +} + +// Succeeded returns true if the LRO's state is terminal success. +func Succeeded(s string) bool { + return strings.EqualFold(s, StatusSucceeded) || strings.EqualFold(s, StatusCompleted) +} + +// returns true if the LRO response contains a valid HTTP status code +func StatusCodeValid(resp *http.Response) bool { + return exported.HasStatusCode(resp, http.StatusOK, http.StatusAccepted, http.StatusCreated, http.StatusNoContent) +} + +// IsValidURL verifies that the URL is valid and absolute. +func IsValidURL(s string) bool { + u, err := url.Parse(s) + return err == nil && u.IsAbs() +} + +// ErrNoBody is returned if the response didn't contain a body. +var ErrNoBody = errors.New("the response did not contain a body") + +// GetJSON reads the response body into a raw JSON object. +// It returns ErrNoBody if there was no content. +func GetJSON(resp *http.Response) (map[string]any, error) { + body, err := exported.Payload(resp, nil) + if err != nil { + return nil, err + } + if len(body) == 0 { + return nil, ErrNoBody + } + // unmarshall the body to get the value + var jsonBody map[string]any + if err = json.Unmarshal(body, &jsonBody); err != nil { + return nil, err + } + return jsonBody, nil +} + +// provisioningState returns the provisioning state from the response or the empty string. +func provisioningState(jsonBody map[string]any) string { + jsonProps, ok := jsonBody["properties"] + if !ok { + return "" + } + props, ok := jsonProps.(map[string]any) + if !ok { + return "" + } + rawPs, ok := props["provisioningState"] + if !ok { + return "" + } + ps, ok := rawPs.(string) + if !ok { + return "" + } + return ps +} + +// status returns the status from the response or the empty string. +func status(jsonBody map[string]any) string { + rawStatus, ok := jsonBody["status"] + if !ok { + return "" + } + status, ok := rawStatus.(string) + if !ok { + return "" + } + return status +} + +// GetStatus returns the LRO's status from the response body. +// Typically used for Azure-AsyncOperation flows. +// If there is no status in the response body the empty string is returned. +func GetStatus(resp *http.Response) (string, error) { + jsonBody, err := GetJSON(resp) + if err != nil { + return "", err + } + return status(jsonBody), nil +} + +// GetProvisioningState returns the LRO's state from the response body. +// If there is no state in the response body the empty string is returned. +func GetProvisioningState(resp *http.Response) (string, error) { + jsonBody, err := GetJSON(resp) + if err != nil { + return "", err + } + return provisioningState(jsonBody), nil +} + +// GetResourceLocation returns the LRO's resourceLocation value from the response body. +// Typically used for Operation-Location flows. +// If there is no resourceLocation in the response body the empty string is returned. +func GetResourceLocation(resp *http.Response) (string, error) { + jsonBody, err := GetJSON(resp) + if err != nil { + return "", err + } + v, ok := jsonBody["resourceLocation"] + if !ok { + // it might be ok if the field doesn't exist, the caller must make that determination + return "", nil + } + vv, ok := v.(string) + if !ok { + return "", fmt.Errorf("the resourceLocation value %v was not in string format", v) + } + return vv, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/temporal/resource.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/temporal/resource.go new file mode 100644 index 000000000..02aa1fb3b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/temporal/resource.go @@ -0,0 +1,154 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package temporal + +import ( + "sync" + "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 + cond *sync.Cond + + // acquiring indicates that some thread/goroutine is in the process of acquiring/updating the resource + acquiring bool + + // resource contains the value of the shared resource + resource TResource + + // expiration indicates when the shared resource expires; it is 0 if the resource was never acquired + expiration time.Time + + // 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] { + 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) { + now, acquire, expired := time.Now(), false, false + + // acquire exclusive lock + er.cond.L.Lock() + resource := er.resource + + for { + expired = er.expiration.IsZero() || er.expiration.Before(now) + if expired { + // The resource was never acquired or has expired + if !er.acquiring { + // If another thread/goroutine is not acquiring/updating the resource, this thread/goroutine will do it + er.acquiring, acquire = true, true + break + } + // Getting here means that this thread/goroutine will wait for the updated resource + } 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 + break + } + // This thread/goroutine will use the existing resource value while another updates it + resource = er.resource + break + } else { + // The resource is not close to expiring, this thread/goroutine should use its current value + resource = er.resource + break + } + // If we get here, wait for the new resource value to be acquired/updated + er.cond.Wait() + } + er.cond.L.Unlock() // Release the lock so no threads/goroutines are blocked + + var err error + if acquire { + // This thread/goroutine has been selected to acquire/update the resource + var expiration time.Time + var newValue TResource + er.lastAttempt = now + newValue, expiration, err = er.acquireResource(state) + + // Atomically, update the shared resource's new value & expiration. + er.cond.L.Lock() + if err == nil { + // Update resource & expiration, return the new value + resource = newValue + er.resource, er.expiration = resource, expiration + } else if !expired { + // An eager update failed. Discard the error and return the current--still valid--resource value + err = nil + } + er.acquiring = false // Indicate that no thread/goroutine is currently acquiring the resource + + // Wake up any waiting threads/goroutines since there is a resource they can ALL use + er.cond.L.Unlock() + er.cond.Broadcast() + } + return resource, err // Return the resource this thread/goroutine can use +} + +// Expire marks the resource as expired, ensuring it's refreshed on the next call to Get(). +func (er *Resource[TResource, TState]) Expire() { + er.cond.L.Lock() + defer er.cond.L.Unlock() + + // 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()) +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/uuid/doc.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/uuid/doc.go new file mode 100644 index 000000000..a3824bee8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/uuid/doc.go @@ -0,0 +1,7 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package uuid diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/uuid/uuid.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/uuid/uuid.go new file mode 100644 index 000000000..278ac9cd1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/uuid/uuid.go @@ -0,0 +1,76 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package uuid + +import ( + "crypto/rand" + "errors" + "fmt" + "strconv" +) + +// The UUID reserved variants. +const ( + reservedRFC4122 byte = 0x40 +) + +// A UUID representation compliant with specification in RFC4122 document. +type UUID [16]byte + +// New returns a new UUID using the RFC4122 algorithm. +func New() (UUID, error) { + u := UUID{} + // Set all bits to pseudo-random values. + // NOTE: this takes a process-wide lock + _, err := rand.Read(u[:]) + if err != nil { + return u, err + } + u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122) + + var version byte = 4 + u[6] = (u[6] & 0xF) | (version << 4) // u.setVersion(4) + return u, nil +} + +// String returns the UUID in "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" format. +func (u UUID) String() string { + return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} + +// Parse parses a string formatted as "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +// or "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" into a UUID. +func Parse(s string) (UUID, error) { + var uuid UUID + // ensure format + switch len(s) { + case 36: + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 38: + // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + s = s[1:37] + default: + return uuid, errors.New("invalid UUID format") + } + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + // parse chunks + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34} { + b, err := strconv.ParseUint(s[x:x+2], 16, 8) + if err != nil { + return uuid, fmt.Errorf("invalid UUID format: %s", err) + } + uuid[i] = byte(b) + } + return uuid, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/CHANGELOG.md new file mode 100644 index 000000000..bd9c8c90c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/CHANGELOG.md @@ -0,0 +1,320 @@ +# Release History + +## 2.2.0 (2023-11-24) +### Features Added + +- Support for test fakes and OpenTelemetry trace spans. + + +## 3.0.0-beta.1 (2023-07-28) +### Breaking Changes + +- Field `EffectiveRules` of struct `RoleManagementPolicyAssignmentProperties` has been removed + +### Features Added + +- New enum type `AccessRecommendationType` with values `AccessRecommendationTypeApprove`, `AccessRecommendationTypeDeny`, `AccessRecommendationTypeNoInfoAvailable` +- New enum type `AccessReviewActorIdentityType` with values `AccessReviewActorIdentityTypeServicePrincipal`, `AccessReviewActorIdentityTypeUser` +- New enum type `AccessReviewApplyResult` with values `AccessReviewApplyResultAppliedSuccessfully`, `AccessReviewApplyResultAppliedSuccessfullyButObjectNotFound`, `AccessReviewApplyResultAppliedWithUnknownFailure`, `AccessReviewApplyResultApplyNotSupported`, `AccessReviewApplyResultApplying`, `AccessReviewApplyResultNew` +- New enum type `AccessReviewDecisionInsightType` with values `AccessReviewDecisionInsightTypeUserSignInInsight` +- New enum type `AccessReviewDecisionPrincipalResourceMembershipType` with values `AccessReviewDecisionPrincipalResourceMembershipTypeDirect`, `AccessReviewDecisionPrincipalResourceMembershipTypeIndirect` +- New enum type `AccessReviewHistoryDefinitionStatus` with values `AccessReviewHistoryDefinitionStatusDone`, `AccessReviewHistoryDefinitionStatusError`, `AccessReviewHistoryDefinitionStatusInProgress`, `AccessReviewHistoryDefinitionStatusRequested` +- New enum type `AccessReviewInstanceReviewersType` with values `AccessReviewInstanceReviewersTypeAssigned`, `AccessReviewInstanceReviewersTypeManagers`, `AccessReviewInstanceReviewersTypeSelf` +- New enum type `AccessReviewInstanceStatus` with values `AccessReviewInstanceStatusApplied`, `AccessReviewInstanceStatusApplying`, `AccessReviewInstanceStatusAutoReviewed`, `AccessReviewInstanceStatusAutoReviewing`, `AccessReviewInstanceStatusCompleted`, `AccessReviewInstanceStatusCompleting`, `AccessReviewInstanceStatusInProgress`, `AccessReviewInstanceStatusInitializing`, `AccessReviewInstanceStatusNotStarted`, `AccessReviewInstanceStatusScheduled`, `AccessReviewInstanceStatusStarting` +- New enum type `AccessReviewRecurrencePatternType` with values `AccessReviewRecurrencePatternTypeAbsoluteMonthly`, `AccessReviewRecurrencePatternTypeWeekly` +- New enum type `AccessReviewRecurrenceRangeType` with values `AccessReviewRecurrenceRangeTypeEndDate`, `AccessReviewRecurrenceRangeTypeNoEnd`, `AccessReviewRecurrenceRangeTypeNumbered` +- New enum type `AccessReviewResult` with values `AccessReviewResultApprove`, `AccessReviewResultDeny`, `AccessReviewResultDontKnow`, `AccessReviewResultNotNotified`, `AccessReviewResultNotReviewed` +- New enum type `AccessReviewReviewerType` with values `AccessReviewReviewerTypeServicePrincipal`, `AccessReviewReviewerTypeUser` +- New enum type `AccessReviewScheduleDefinitionReviewersType` with values `AccessReviewScheduleDefinitionReviewersTypeAssigned`, `AccessReviewScheduleDefinitionReviewersTypeManagers`, `AccessReviewScheduleDefinitionReviewersTypeSelf` +- New enum type `AccessReviewScheduleDefinitionStatus` with values `AccessReviewScheduleDefinitionStatusApplied`, `AccessReviewScheduleDefinitionStatusApplying`, `AccessReviewScheduleDefinitionStatusAutoReviewed`, `AccessReviewScheduleDefinitionStatusAutoReviewing`, `AccessReviewScheduleDefinitionStatusCompleted`, `AccessReviewScheduleDefinitionStatusCompleting`, `AccessReviewScheduleDefinitionStatusInProgress`, `AccessReviewScheduleDefinitionStatusInitializing`, `AccessReviewScheduleDefinitionStatusNotStarted`, `AccessReviewScheduleDefinitionStatusScheduled`, `AccessReviewScheduleDefinitionStatusStarting` +- New enum type `AccessReviewScopeAssignmentState` with values `AccessReviewScopeAssignmentStateActive`, `AccessReviewScopeAssignmentStateEligible` +- New enum type `AccessReviewScopePrincipalType` with values `AccessReviewScopePrincipalTypeGuestUser`, `AccessReviewScopePrincipalTypeRedeemedGuestUser`, `AccessReviewScopePrincipalTypeServicePrincipal`, `AccessReviewScopePrincipalTypeUser`, `AccessReviewScopePrincipalTypeUserGroup` +- New enum type `DecisionResourceType` with values `DecisionResourceTypeAzureRole` +- New enum type `DecisionTargetType` with values `DecisionTargetTypeServicePrincipal`, `DecisionTargetTypeUser` +- New enum type `DefaultDecisionType` with values `DefaultDecisionTypeApprove`, `DefaultDecisionTypeDeny`, `DefaultDecisionTypeRecommendation` +- New enum type `RecordAllDecisionsResult` with values `RecordAllDecisionsResultApprove`, `RecordAllDecisionsResultDeny` +- New enum type `SeverityLevel` with values `SeverityLevelHigh`, `SeverityLevelLow`, `SeverityLevelMedium` +- New function `*AccessReviewDecisionIdentity.GetAccessReviewDecisionIdentity() *AccessReviewDecisionIdentity` +- New function `*AccessReviewDecisionInsightProperties.GetAccessReviewDecisionInsightProperties() *AccessReviewDecisionInsightProperties` +- New function `*AccessReviewDecisionServicePrincipalIdentity.GetAccessReviewDecisionIdentity() *AccessReviewDecisionIdentity` +- New function `*AccessReviewDecisionUserIdentity.GetAccessReviewDecisionIdentity() *AccessReviewDecisionIdentity` +- New function `*AccessReviewDecisionUserSignInInsightProperties.GetAccessReviewDecisionInsightProperties() *AccessReviewDecisionInsightProperties` +- New function `NewAccessReviewDefaultSettingsClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewDefaultSettingsClient, error)` +- New function `*AccessReviewDefaultSettingsClient.Get(context.Context, *AccessReviewDefaultSettingsClientGetOptions) (AccessReviewDefaultSettingsClientGetResponse, error)` +- New function `*AccessReviewDefaultSettingsClient.Put(context.Context, AccessReviewScheduleSettings, *AccessReviewDefaultSettingsClientPutOptions) (AccessReviewDefaultSettingsClientPutResponse, error)` +- New function `NewAccessReviewHistoryDefinitionClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewHistoryDefinitionClient, error)` +- New function `*AccessReviewHistoryDefinitionClient.Create(context.Context, string, AccessReviewHistoryDefinitionProperties, *AccessReviewHistoryDefinitionClientCreateOptions) (AccessReviewHistoryDefinitionClientCreateResponse, error)` +- New function `*AccessReviewHistoryDefinitionClient.DeleteByID(context.Context, string, *AccessReviewHistoryDefinitionClientDeleteByIDOptions) (AccessReviewHistoryDefinitionClientDeleteByIDResponse, error)` +- New function `NewAccessReviewHistoryDefinitionInstanceClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewHistoryDefinitionInstanceClient, error)` +- New function `*AccessReviewHistoryDefinitionInstanceClient.GenerateDownloadURI(context.Context, string, string, *AccessReviewHistoryDefinitionInstanceClientGenerateDownloadURIOptions) (AccessReviewHistoryDefinitionInstanceClientGenerateDownloadURIResponse, error)` +- New function `NewAccessReviewHistoryDefinitionInstancesClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewHistoryDefinitionInstancesClient, error)` +- New function `*AccessReviewHistoryDefinitionInstancesClient.NewListPager(string, *AccessReviewHistoryDefinitionInstancesClientListOptions) *runtime.Pager[AccessReviewHistoryDefinitionInstancesClientListResponse]` +- New function `NewAccessReviewHistoryDefinitionsClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewHistoryDefinitionsClient, error)` +- New function `*AccessReviewHistoryDefinitionsClient.GetByID(context.Context, string, *AccessReviewHistoryDefinitionsClientGetByIDOptions) (AccessReviewHistoryDefinitionsClientGetByIDResponse, error)` +- New function `*AccessReviewHistoryDefinitionsClient.NewListPager(*AccessReviewHistoryDefinitionsClientListOptions) *runtime.Pager[AccessReviewHistoryDefinitionsClientListResponse]` +- New function `NewAccessReviewInstanceClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewInstanceClient, error)` +- New function `*AccessReviewInstanceClient.AcceptRecommendations(context.Context, string, string, *AccessReviewInstanceClientAcceptRecommendationsOptions) (AccessReviewInstanceClientAcceptRecommendationsResponse, error)` +- New function `*AccessReviewInstanceClient.ApplyDecisions(context.Context, string, string, *AccessReviewInstanceClientApplyDecisionsOptions) (AccessReviewInstanceClientApplyDecisionsResponse, error)` +- New function `*AccessReviewInstanceClient.ResetDecisions(context.Context, string, string, *AccessReviewInstanceClientResetDecisionsOptions) (AccessReviewInstanceClientResetDecisionsResponse, error)` +- New function `*AccessReviewInstanceClient.SendReminders(context.Context, string, string, *AccessReviewInstanceClientSendRemindersOptions) (AccessReviewInstanceClientSendRemindersResponse, error)` +- New function `*AccessReviewInstanceClient.Stop(context.Context, string, string, *AccessReviewInstanceClientStopOptions) (AccessReviewInstanceClientStopResponse, error)` +- New function `NewAccessReviewInstanceContactedReviewersClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewInstanceContactedReviewersClient, error)` +- New function `*AccessReviewInstanceContactedReviewersClient.NewListPager(string, string, *AccessReviewInstanceContactedReviewersClientListOptions) *runtime.Pager[AccessReviewInstanceContactedReviewersClientListResponse]` +- New function `NewAccessReviewInstanceDecisionsClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewInstanceDecisionsClient, error)` +- New function `*AccessReviewInstanceDecisionsClient.NewListPager(string, string, *AccessReviewInstanceDecisionsClientListOptions) *runtime.Pager[AccessReviewInstanceDecisionsClientListResponse]` +- New function `NewAccessReviewInstanceMyDecisionsClient(azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewInstanceMyDecisionsClient, error)` +- New function `*AccessReviewInstanceMyDecisionsClient.GetByID(context.Context, string, string, string, *AccessReviewInstanceMyDecisionsClientGetByIDOptions) (AccessReviewInstanceMyDecisionsClientGetByIDResponse, error)` +- New function `*AccessReviewInstanceMyDecisionsClient.NewListPager(string, string, *AccessReviewInstanceMyDecisionsClientListOptions) *runtime.Pager[AccessReviewInstanceMyDecisionsClientListResponse]` +- New function `*AccessReviewInstanceMyDecisionsClient.Patch(context.Context, string, string, string, AccessReviewDecisionProperties, *AccessReviewInstanceMyDecisionsClientPatchOptions) (AccessReviewInstanceMyDecisionsClientPatchResponse, error)` +- New function `NewAccessReviewInstancesAssignedForMyApprovalClient(azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewInstancesAssignedForMyApprovalClient, error)` +- New function `*AccessReviewInstancesAssignedForMyApprovalClient.GetByID(context.Context, string, string, *AccessReviewInstancesAssignedForMyApprovalClientGetByIDOptions) (AccessReviewInstancesAssignedForMyApprovalClientGetByIDResponse, error)` +- New function `*AccessReviewInstancesAssignedForMyApprovalClient.NewListPager(string, *AccessReviewInstancesAssignedForMyApprovalClientListOptions) *runtime.Pager[AccessReviewInstancesAssignedForMyApprovalClientListResponse]` +- New function `NewAccessReviewInstancesClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewInstancesClient, error)` +- New function `*AccessReviewInstancesClient.Create(context.Context, string, string, AccessReviewInstanceProperties, *AccessReviewInstancesClientCreateOptions) (AccessReviewInstancesClientCreateResponse, error)` +- New function `*AccessReviewInstancesClient.GetByID(context.Context, string, string, *AccessReviewInstancesClientGetByIDOptions) (AccessReviewInstancesClientGetByIDResponse, error)` +- New function `*AccessReviewInstancesClient.NewListPager(string, *AccessReviewInstancesClientListOptions) *runtime.Pager[AccessReviewInstancesClientListResponse]` +- New function `NewAccessReviewScheduleDefinitionsAssignedForMyApprovalClient(azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewScheduleDefinitionsAssignedForMyApprovalClient, error)` +- New function `*AccessReviewScheduleDefinitionsAssignedForMyApprovalClient.NewListPager(*AccessReviewScheduleDefinitionsAssignedForMyApprovalClientListOptions) *runtime.Pager[AccessReviewScheduleDefinitionsAssignedForMyApprovalClientListResponse]` +- New function `NewAccessReviewScheduleDefinitionsClient(string, azcore.TokenCredential, *arm.ClientOptions) (*AccessReviewScheduleDefinitionsClient, error)` +- New function `*AccessReviewScheduleDefinitionsClient.CreateOrUpdateByID(context.Context, string, AccessReviewScheduleDefinitionProperties, *AccessReviewScheduleDefinitionsClientCreateOrUpdateByIDOptions) (AccessReviewScheduleDefinitionsClientCreateOrUpdateByIDResponse, error)` +- New function `*AccessReviewScheduleDefinitionsClient.DeleteByID(context.Context, string, *AccessReviewScheduleDefinitionsClientDeleteByIDOptions) (AccessReviewScheduleDefinitionsClientDeleteByIDResponse, error)` +- New function `*AccessReviewScheduleDefinitionsClient.GetByID(context.Context, string, *AccessReviewScheduleDefinitionsClientGetByIDOptions) (AccessReviewScheduleDefinitionsClientGetByIDResponse, error)` +- New function `*AccessReviewScheduleDefinitionsClient.NewListPager(*AccessReviewScheduleDefinitionsClientListOptions) *runtime.Pager[AccessReviewScheduleDefinitionsClientListResponse]` +- New function `*AccessReviewScheduleDefinitionsClient.Stop(context.Context, string, *AccessReviewScheduleDefinitionsClientStopOptions) (AccessReviewScheduleDefinitionsClientStopResponse, error)` +- New function `*AlertConfigurationProperties.GetAlertConfigurationProperties() *AlertConfigurationProperties` +- New function `NewAlertConfigurationsClient(azcore.TokenCredential, *arm.ClientOptions) (*AlertConfigurationsClient, error)` +- New function `*AlertConfigurationsClient.Get(context.Context, string, string, *AlertConfigurationsClientGetOptions) (AlertConfigurationsClientGetResponse, error)` +- New function `*AlertConfigurationsClient.NewListForScopePager(string, *AlertConfigurationsClientListForScopeOptions) *runtime.Pager[AlertConfigurationsClientListForScopeResponse]` +- New function `*AlertConfigurationsClient.Update(context.Context, string, string, AlertConfiguration, *AlertConfigurationsClientUpdateOptions) (AlertConfigurationsClientUpdateResponse, error)` +- New function `NewAlertDefinitionsClient(azcore.TokenCredential, *arm.ClientOptions) (*AlertDefinitionsClient, error)` +- New function `*AlertDefinitionsClient.Get(context.Context, string, string, *AlertDefinitionsClientGetOptions) (AlertDefinitionsClientGetResponse, error)` +- New function `*AlertDefinitionsClient.NewListForScopePager(string, *AlertDefinitionsClientListForScopeOptions) *runtime.Pager[AlertDefinitionsClientListForScopeResponse]` +- New function `*AlertIncidentProperties.GetAlertIncidentProperties() *AlertIncidentProperties` +- New function `NewAlertIncidentsClient(azcore.TokenCredential, *arm.ClientOptions) (*AlertIncidentsClient, error)` +- New function `*AlertIncidentsClient.Get(context.Context, string, string, string, *AlertIncidentsClientGetOptions) (AlertIncidentsClientGetResponse, error)` +- New function `*AlertIncidentsClient.NewListForScopePager(string, string, *AlertIncidentsClientListForScopeOptions) *runtime.Pager[AlertIncidentsClientListForScopeResponse]` +- New function `*AlertIncidentsClient.Remediate(context.Context, string, string, string, *AlertIncidentsClientRemediateOptions) (AlertIncidentsClientRemediateResponse, error)` +- New function `NewAlertOperationClient(azcore.TokenCredential, *arm.ClientOptions) (*AlertOperationClient, error)` +- New function `*AlertOperationClient.Get(context.Context, string, string, *AlertOperationClientGetOptions) (AlertOperationClientGetResponse, error)` +- New function `NewAlertsClient(azcore.TokenCredential, *arm.ClientOptions) (*AlertsClient, error)` +- New function `*AlertsClient.Get(context.Context, string, string, *AlertsClientGetOptions) (AlertsClientGetResponse, error)` +- New function `*AlertsClient.NewListForScopePager(string, *AlertsClientListForScopeOptions) *runtime.Pager[AlertsClientListForScopeResponse]` +- New function `*AlertsClient.BeginRefresh(context.Context, string, string, *AlertsClientBeginRefreshOptions) (*runtime.Poller[AlertsClientRefreshResponse], error)` +- New function `*AlertsClient.BeginRefreshAll(context.Context, string, *AlertsClientBeginRefreshAllOptions) (*runtime.Poller[AlertsClientRefreshAllResponse], error)` +- New function `*AlertsClient.Update(context.Context, string, string, Alert, *AlertsClientUpdateOptions) (AlertsClientUpdateResponse, error)` +- New function `*AzureRolesAssignedOutsidePimAlertConfigurationProperties.GetAlertConfigurationProperties() *AlertConfigurationProperties` +- New function `*AzureRolesAssignedOutsidePimAlertIncidentProperties.GetAlertIncidentProperties() *AlertIncidentProperties` +- New function `*ClientFactory.NewAccessReviewDefaultSettingsClient() *AccessReviewDefaultSettingsClient` +- New function `*ClientFactory.NewAccessReviewHistoryDefinitionClient() *AccessReviewHistoryDefinitionClient` +- New function `*ClientFactory.NewAccessReviewHistoryDefinitionInstanceClient() *AccessReviewHistoryDefinitionInstanceClient` +- New function `*ClientFactory.NewAccessReviewHistoryDefinitionInstancesClient() *AccessReviewHistoryDefinitionInstancesClient` +- New function `*ClientFactory.NewAccessReviewHistoryDefinitionsClient() *AccessReviewHistoryDefinitionsClient` +- New function `*ClientFactory.NewAccessReviewInstanceClient() *AccessReviewInstanceClient` +- New function `*ClientFactory.NewAccessReviewInstanceContactedReviewersClient() *AccessReviewInstanceContactedReviewersClient` +- New function `*ClientFactory.NewAccessReviewInstanceDecisionsClient() *AccessReviewInstanceDecisionsClient` +- New function `*ClientFactory.NewAccessReviewInstanceMyDecisionsClient() *AccessReviewInstanceMyDecisionsClient` +- New function `*ClientFactory.NewAccessReviewInstancesAssignedForMyApprovalClient() *AccessReviewInstancesAssignedForMyApprovalClient` +- New function `*ClientFactory.NewAccessReviewInstancesClient() *AccessReviewInstancesClient` +- New function `*ClientFactory.NewAccessReviewScheduleDefinitionsAssignedForMyApprovalClient() *AccessReviewScheduleDefinitionsAssignedForMyApprovalClient` +- New function `*ClientFactory.NewAccessReviewScheduleDefinitionsClient() *AccessReviewScheduleDefinitionsClient` +- New function `*ClientFactory.NewAlertConfigurationsClient() *AlertConfigurationsClient` +- New function `*ClientFactory.NewAlertDefinitionsClient() *AlertDefinitionsClient` +- New function `*ClientFactory.NewAlertIncidentsClient() *AlertIncidentsClient` +- New function `*ClientFactory.NewAlertOperationClient() *AlertOperationClient` +- New function `*ClientFactory.NewAlertsClient() *AlertsClient` +- New function `*ClientFactory.NewOperationsClient() *OperationsClient` +- New function `*ClientFactory.NewScopeAccessReviewDefaultSettingsClient() *ScopeAccessReviewDefaultSettingsClient` +- New function `*ClientFactory.NewScopeAccessReviewHistoryDefinitionClient() *ScopeAccessReviewHistoryDefinitionClient` +- New function `*ClientFactory.NewScopeAccessReviewHistoryDefinitionInstanceClient() *ScopeAccessReviewHistoryDefinitionInstanceClient` +- New function `*ClientFactory.NewScopeAccessReviewHistoryDefinitionInstancesClient() *ScopeAccessReviewHistoryDefinitionInstancesClient` +- New function `*ClientFactory.NewScopeAccessReviewHistoryDefinitionsClient() *ScopeAccessReviewHistoryDefinitionsClient` +- New function `*ClientFactory.NewScopeAccessReviewInstanceClient() *ScopeAccessReviewInstanceClient` +- New function `*ClientFactory.NewScopeAccessReviewInstanceContactedReviewersClient() *ScopeAccessReviewInstanceContactedReviewersClient` +- New function `*ClientFactory.NewScopeAccessReviewInstanceDecisionsClient() *ScopeAccessReviewInstanceDecisionsClient` +- New function `*ClientFactory.NewScopeAccessReviewInstancesClient() *ScopeAccessReviewInstancesClient` +- New function `*ClientFactory.NewScopeAccessReviewScheduleDefinitionsClient() *ScopeAccessReviewScheduleDefinitionsClient` +- New function `*ClientFactory.NewTenantLevelAccessReviewInstanceContactedReviewersClient() *TenantLevelAccessReviewInstanceContactedReviewersClient` +- New function `*DuplicateRoleCreatedAlertConfigurationProperties.GetAlertConfigurationProperties() *AlertConfigurationProperties` +- New function `*DuplicateRoleCreatedAlertIncidentProperties.GetAlertIncidentProperties() *AlertIncidentProperties` +- New function `NewOperationsClient(azcore.TokenCredential, *arm.ClientOptions) (*OperationsClient, error)` +- New function `*OperationsClient.NewListPager(*OperationsClientListOptions) *runtime.Pager[OperationsClientListResponse]` +- New function `NewScopeAccessReviewDefaultSettingsClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewDefaultSettingsClient, error)` +- New function `*ScopeAccessReviewDefaultSettingsClient.Get(context.Context, string, *ScopeAccessReviewDefaultSettingsClientGetOptions) (ScopeAccessReviewDefaultSettingsClientGetResponse, error)` +- New function `*ScopeAccessReviewDefaultSettingsClient.Put(context.Context, string, AccessReviewScheduleSettings, *ScopeAccessReviewDefaultSettingsClientPutOptions) (ScopeAccessReviewDefaultSettingsClientPutResponse, error)` +- New function `NewScopeAccessReviewHistoryDefinitionClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewHistoryDefinitionClient, error)` +- New function `*ScopeAccessReviewHistoryDefinitionClient.Create(context.Context, string, string, AccessReviewHistoryDefinitionProperties, *ScopeAccessReviewHistoryDefinitionClientCreateOptions) (ScopeAccessReviewHistoryDefinitionClientCreateResponse, error)` +- New function `*ScopeAccessReviewHistoryDefinitionClient.DeleteByID(context.Context, string, string, *ScopeAccessReviewHistoryDefinitionClientDeleteByIDOptions) (ScopeAccessReviewHistoryDefinitionClientDeleteByIDResponse, error)` +- New function `NewScopeAccessReviewHistoryDefinitionInstanceClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewHistoryDefinitionInstanceClient, error)` +- New function `*ScopeAccessReviewHistoryDefinitionInstanceClient.GenerateDownloadURI(context.Context, string, string, string, *ScopeAccessReviewHistoryDefinitionInstanceClientGenerateDownloadURIOptions) (ScopeAccessReviewHistoryDefinitionInstanceClientGenerateDownloadURIResponse, error)` +- New function `NewScopeAccessReviewHistoryDefinitionInstancesClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewHistoryDefinitionInstancesClient, error)` +- New function `*ScopeAccessReviewHistoryDefinitionInstancesClient.NewListPager(string, string, *ScopeAccessReviewHistoryDefinitionInstancesClientListOptions) *runtime.Pager[ScopeAccessReviewHistoryDefinitionInstancesClientListResponse]` +- New function `NewScopeAccessReviewHistoryDefinitionsClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewHistoryDefinitionsClient, error)` +- New function `*ScopeAccessReviewHistoryDefinitionsClient.GetByID(context.Context, string, string, *ScopeAccessReviewHistoryDefinitionsClientGetByIDOptions) (ScopeAccessReviewHistoryDefinitionsClientGetByIDResponse, error)` +- New function `*ScopeAccessReviewHistoryDefinitionsClient.NewListPager(string, *ScopeAccessReviewHistoryDefinitionsClientListOptions) *runtime.Pager[ScopeAccessReviewHistoryDefinitionsClientListResponse]` +- New function `NewScopeAccessReviewInstanceClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewInstanceClient, error)` +- New function `*ScopeAccessReviewInstanceClient.ApplyDecisions(context.Context, string, string, string, *ScopeAccessReviewInstanceClientApplyDecisionsOptions) (ScopeAccessReviewInstanceClientApplyDecisionsResponse, error)` +- New function `*ScopeAccessReviewInstanceClient.RecordAllDecisions(context.Context, string, string, string, RecordAllDecisionsProperties, *ScopeAccessReviewInstanceClientRecordAllDecisionsOptions) (ScopeAccessReviewInstanceClientRecordAllDecisionsResponse, error)` +- New function `*ScopeAccessReviewInstanceClient.ResetDecisions(context.Context, string, string, string, *ScopeAccessReviewInstanceClientResetDecisionsOptions) (ScopeAccessReviewInstanceClientResetDecisionsResponse, error)` +- New function `*ScopeAccessReviewInstanceClient.SendReminders(context.Context, string, string, string, *ScopeAccessReviewInstanceClientSendRemindersOptions) (ScopeAccessReviewInstanceClientSendRemindersResponse, error)` +- New function `*ScopeAccessReviewInstanceClient.Stop(context.Context, string, string, string, *ScopeAccessReviewInstanceClientStopOptions) (ScopeAccessReviewInstanceClientStopResponse, error)` +- New function `NewScopeAccessReviewInstanceContactedReviewersClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewInstanceContactedReviewersClient, error)` +- New function `*ScopeAccessReviewInstanceContactedReviewersClient.NewListPager(string, string, string, *ScopeAccessReviewInstanceContactedReviewersClientListOptions) *runtime.Pager[ScopeAccessReviewInstanceContactedReviewersClientListResponse]` +- New function `NewScopeAccessReviewInstanceDecisionsClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewInstanceDecisionsClient, error)` +- New function `*ScopeAccessReviewInstanceDecisionsClient.NewListPager(string, string, string, *ScopeAccessReviewInstanceDecisionsClientListOptions) *runtime.Pager[ScopeAccessReviewInstanceDecisionsClientListResponse]` +- New function `NewScopeAccessReviewInstancesClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewInstancesClient, error)` +- New function `*ScopeAccessReviewInstancesClient.Create(context.Context, string, string, string, AccessReviewInstanceProperties, *ScopeAccessReviewInstancesClientCreateOptions) (ScopeAccessReviewInstancesClientCreateResponse, error)` +- New function `*ScopeAccessReviewInstancesClient.GetByID(context.Context, string, string, string, *ScopeAccessReviewInstancesClientGetByIDOptions) (ScopeAccessReviewInstancesClientGetByIDResponse, error)` +- New function `*ScopeAccessReviewInstancesClient.NewListPager(string, string, *ScopeAccessReviewInstancesClientListOptions) *runtime.Pager[ScopeAccessReviewInstancesClientListResponse]` +- New function `NewScopeAccessReviewScheduleDefinitionsClient(azcore.TokenCredential, *arm.ClientOptions) (*ScopeAccessReviewScheduleDefinitionsClient, error)` +- New function `*ScopeAccessReviewScheduleDefinitionsClient.CreateOrUpdateByID(context.Context, string, string, AccessReviewScheduleDefinitionProperties, *ScopeAccessReviewScheduleDefinitionsClientCreateOrUpdateByIDOptions) (ScopeAccessReviewScheduleDefinitionsClientCreateOrUpdateByIDResponse, error)` +- New function `*ScopeAccessReviewScheduleDefinitionsClient.DeleteByID(context.Context, string, string, *ScopeAccessReviewScheduleDefinitionsClientDeleteByIDOptions) (ScopeAccessReviewScheduleDefinitionsClientDeleteByIDResponse, error)` +- New function `*ScopeAccessReviewScheduleDefinitionsClient.GetByID(context.Context, string, string, *ScopeAccessReviewScheduleDefinitionsClientGetByIDOptions) (ScopeAccessReviewScheduleDefinitionsClientGetByIDResponse, error)` +- New function `*ScopeAccessReviewScheduleDefinitionsClient.NewListPager(string, *ScopeAccessReviewScheduleDefinitionsClientListOptions) *runtime.Pager[ScopeAccessReviewScheduleDefinitionsClientListResponse]` +- New function `*ScopeAccessReviewScheduleDefinitionsClient.Stop(context.Context, string, string, *ScopeAccessReviewScheduleDefinitionsClientStopOptions) (ScopeAccessReviewScheduleDefinitionsClientStopResponse, error)` +- New function `NewTenantLevelAccessReviewInstanceContactedReviewersClient(azcore.TokenCredential, *arm.ClientOptions) (*TenantLevelAccessReviewInstanceContactedReviewersClient, error)` +- New function `*TenantLevelAccessReviewInstanceContactedReviewersClient.NewListPager(string, string, *TenantLevelAccessReviewInstanceContactedReviewersClientListOptions) *runtime.Pager[TenantLevelAccessReviewInstanceContactedReviewersClientListResponse]` +- New function `*TooManyOwnersAssignedToResourceAlertConfigurationProperties.GetAlertConfigurationProperties() *AlertConfigurationProperties` +- New function `*TooManyOwnersAssignedToResourceAlertIncidentProperties.GetAlertIncidentProperties() *AlertIncidentProperties` +- New function `*TooManyPermanentOwnersAssignedToResourceAlertConfigurationProperties.GetAlertConfigurationProperties() *AlertConfigurationProperties` +- New function `*TooManyPermanentOwnersAssignedToResourceAlertIncidentProperties.GetAlertIncidentProperties() *AlertIncidentProperties` +- New struct `AccessReviewActorIdentity` +- New struct `AccessReviewContactedReviewer` +- New struct `AccessReviewContactedReviewerListResult` +- New struct `AccessReviewContactedReviewerProperties` +- New struct `AccessReviewDecision` +- New struct `AccessReviewDecisionInsight` +- New struct `AccessReviewDecisionListResult` +- New struct `AccessReviewDecisionPrincipalResourceMembership` +- New struct `AccessReviewDecisionProperties` +- New struct `AccessReviewDecisionResource` +- New struct `AccessReviewDecisionServicePrincipalIdentity` +- New struct `AccessReviewDecisionUserIdentity` +- New struct `AccessReviewDecisionUserSignInInsightProperties` +- New struct `AccessReviewDefaultSettings` +- New struct `AccessReviewHistoryDefinition` +- New struct `AccessReviewHistoryDefinitionInstanceListResult` +- New struct `AccessReviewHistoryDefinitionListResult` +- New struct `AccessReviewHistoryDefinitionProperties` +- New struct `AccessReviewHistoryInstance` +- New struct `AccessReviewHistoryInstanceProperties` +- New struct `AccessReviewHistoryScheduleSettings` +- New struct `AccessReviewInstance` +- New struct `AccessReviewInstanceListResult` +- New struct `AccessReviewInstanceProperties` +- New struct `AccessReviewRecurrencePattern` +- New struct `AccessReviewRecurrenceRange` +- New struct `AccessReviewRecurrenceSettings` +- New struct `AccessReviewReviewer` +- New struct `AccessReviewScheduleDefinition` +- New struct `AccessReviewScheduleDefinitionListResult` +- New struct `AccessReviewScheduleDefinitionProperties` +- New struct `AccessReviewScheduleSettings` +- New struct `AccessReviewScope` +- New struct `Alert` +- New struct `AlertConfiguration` +- New struct `AlertConfigurationListResult` +- New struct `AlertDefinition` +- New struct `AlertDefinitionListResult` +- New struct `AlertDefinitionProperties` +- New struct `AlertIncident` +- New struct `AlertIncidentListResult` +- New struct `AlertListResult` +- New struct `AlertOperationResult` +- New struct `AlertProperties` +- New struct `AzureRolesAssignedOutsidePimAlertConfigurationProperties` +- New struct `AzureRolesAssignedOutsidePimAlertIncidentProperties` +- New struct `DuplicateRoleCreatedAlertConfigurationProperties` +- New struct `DuplicateRoleCreatedAlertIncidentProperties` +- New struct `ErrorDefinition` +- New struct `ErrorDefinitionProperties` +- New struct `Operation` +- New struct `OperationDisplay` +- New struct `OperationListResult` +- New struct `RecordAllDecisionsProperties` +- New struct `TooManyOwnersAssignedToResourceAlertConfigurationProperties` +- New struct `TooManyOwnersAssignedToResourceAlertIncidentProperties` +- New struct `TooManyPermanentOwnersAssignedToResourceAlertConfigurationProperties` +- New struct `TooManyPermanentOwnersAssignedToResourceAlertIncidentProperties` +- New field `Condition`, `ConditionVersion`, `CreatedBy`, `CreatedOn`, `UpdatedBy`, `UpdatedOn` in struct `DenyAssignmentProperties` +- New field `Condition`, `ConditionVersion` in struct `Permission` +- New field `CreatedBy`, `CreatedOn`, `UpdatedBy`, `UpdatedOn` in struct `RoleDefinitionProperties` + + +## 2.1.1 (2023-04-14) +### Bug Fixes + +- Fix serialization bug of empty value of `any` type. + +## 2.1.0 (2023-03-27) +### Features Added + +- New struct `ClientFactory` which is a client factory used to create any client in this module + + +## 2.0.0 (2022-09-26) +### Breaking Changes + +- Function `*RoleAssignmentsClient.NewListForResourcePager` parameter(s) have been changed from `(string, string, string, string, string, *RoleAssignmentsClientListForResourceOptions)` to `(string, string, string, string, *RoleAssignmentsClientListForResourceOptions)` +- Type of `RoleAssignment.Properties` has been changed from `*RoleAssignmentPropertiesWithScope` to `*RoleAssignmentProperties` +- Function `*RoleAssignmentsClient.NewListPager` has been renamed to `*RoleAssignmentsClient.NewListForSubscriptionPager` + +### Features Added + +- New function `*DenyAssignmentsClient.Get(context.Context, string, string, *DenyAssignmentsClientGetOptions) (DenyAssignmentsClientGetResponse, error)` +- New function `*DenyAssignmentsClient.NewListForScopePager(string, *DenyAssignmentsClientListForScopeOptions) *runtime.Pager[DenyAssignmentsClientListForScopeResponse]` +- New function `*DenyAssignmentsClient.NewListForResourcePager(string, string, string, string, string, *DenyAssignmentsClientListForResourceOptions) *runtime.Pager[DenyAssignmentsClientListForResourceResponse]` +- New function `*DenyAssignmentsClient.NewListForResourceGroupPager(string, *DenyAssignmentsClientListForResourceGroupOptions) *runtime.Pager[DenyAssignmentsClientListForResourceGroupResponse]` +- New function `*DenyAssignmentsClient.GetByID(context.Context, string, *DenyAssignmentsClientGetByIDOptions) (DenyAssignmentsClientGetByIDResponse, error)` +- New function `*DenyAssignmentsClient.NewListPager(*DenyAssignmentsClientListOptions) *runtime.Pager[DenyAssignmentsClientListResponse]` +- New function `NewDenyAssignmentsClient(string, azcore.TokenCredential, *arm.ClientOptions) (*DenyAssignmentsClient, error)` +- New struct `DenyAssignment` +- New struct `DenyAssignmentFilter` +- New struct `DenyAssignmentListResult` +- New struct `DenyAssignmentPermission` +- New struct `DenyAssignmentProperties` +- New struct `DenyAssignmentsClient` +- New struct `DenyAssignmentsClientGetByIDOptions` +- New struct `DenyAssignmentsClientGetByIDResponse` +- New struct `DenyAssignmentsClientGetOptions` +- New struct `DenyAssignmentsClientGetResponse` +- New struct `DenyAssignmentsClientListForResourceGroupOptions` +- New struct `DenyAssignmentsClientListForResourceGroupResponse` +- New struct `DenyAssignmentsClientListForResourceOptions` +- New struct `DenyAssignmentsClientListForResourceResponse` +- New struct `DenyAssignmentsClientListForScopeOptions` +- New struct `DenyAssignmentsClientListForScopeResponse` +- New struct `DenyAssignmentsClientListOptions` +- New struct `DenyAssignmentsClientListResponse` +- New struct `ValidationResponse` +- New struct `ValidationResponseErrorInfo` +- New field `TenantID` in struct `RoleAssignmentsClientGetByIDOptions` +- New field `DataActions` in struct `Permission` +- New field `NotDataActions` in struct `Permission` +- New field `TenantID` in struct `RoleAssignmentsClientListForResourceOptions` +- New field `UpdatedBy` in struct `RoleAssignmentProperties` +- New field `Condition` in struct `RoleAssignmentProperties` +- New field `CreatedOn` in struct `RoleAssignmentProperties` +- New field `UpdatedOn` in struct `RoleAssignmentProperties` +- New field `CreatedBy` in struct `RoleAssignmentProperties` +- New field `ConditionVersion` in struct `RoleAssignmentProperties` +- New field `DelegatedManagedIdentityResourceID` in struct `RoleAssignmentProperties` +- New field `Description` in struct `RoleAssignmentProperties` +- New field `PrincipalType` in struct `RoleAssignmentProperties` +- New field `Scope` in struct `RoleAssignmentProperties` +- New field `TenantID` in struct `RoleAssignmentsClientDeleteByIDOptions` +- New field `IsDataAction` in struct `ProviderOperation` +- New field `TenantID` in struct `RoleAssignmentsClientDeleteOptions` +- New field `Type` in struct `RoleDefinitionFilter` +- New field `TenantID` in struct `RoleAssignmentsClientListForResourceGroupOptions` +- New field `TenantID` in struct `RoleAssignmentsClientGetOptions` +- New field `SkipToken` in struct `RoleAssignmentsClientListForScopeOptions` +- New field `TenantID` in struct `RoleAssignmentsClientListForScopeOptions` + + +## 1.0.0 (2022-06-02) + +The package of `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization` is using our [next generation design principles](https://azure.github.io/azure-sdk/general_introduction.html) since version 1.0.0, which contains breaking changes. + +To migrate the existing applications to the latest version, please refer to [Migration Guide](https://aka.ms/azsdk/go/mgmt/migration). + +To learn more, please refer to our documentation [Quick Start](https://aka.ms/azsdk/go/mgmt). diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/LICENSE.txt new file mode 100644 index 000000000..dc0c2ffb3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/README.md new file mode 100644 index 000000000..84ccf4ab1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/README.md @@ -0,0 +1,170 @@ +# Azure Authorization Module for Go + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization) + +The `armauthorization` module provides operations for working with Azure Authorization. + +[Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/resourcemanager/authorization/armauthorization) + +# Getting started + +## Prerequisites + +- an [Azure subscription](https://azure.microsoft.com/free/) +- 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 + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Install the Azure Authorization module: + +```sh +go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization +``` + +## Authorization + +When creating a client, you will need to provide a credential for authenticating with Azure Authorization. The `azidentity` module provides facilities for various ways of authenticating with Azure including client/secret, certificate, managed identity, and more. + +```go +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). + +## Client Factory + +Azure Authorization module consists of one or more clients. We provide a client factory which could be used to create any client in this module. + +```go +clientFactory, err := armauthorization.NewClientFactory(, 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). + +```go +options := arm.ClientOptions { + ClientOptions: azcore.ClientOptions { + Cloud: cloud.AzureChina, + }, +} +clientFactory, err := armauthorization.NewClientFactory(, cred, &options) +``` + +## Client Factory + +Azure XXX module consists of one or more clients. We provide a client factory which could be used to create any client in this module. + +```go +clientFactory, err := armX.NewClientFactory(, 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). + +```go +options := arm.ClientOptions { + ClientOptions: azcore.ClientOptions { + Cloud: cloud.AzureChina, + }, +} +clientFactory, err := armX.NewClientFactory(, 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.NewXClient() + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization) + +The `armauthorization` module provides operations for working with Azure Authorization. + +[Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/resourcemanager/authorization/armauthorization) + +# Getting started + +## Prerequisites + +- an [Azure subscription](https://azure.microsoft.com/free/) +- 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 + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Install the Azure Authorization module: + +```sh +go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization +``` + +## 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. + +## Authorization + +When creating a client, you will need to provide a credential for authenticating with Azure Authorization. The `azidentity` module provides facilities for various ways of authenticating with Azure including client/secret, certificate, managed identity, and more. + +```go +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). + +## Client Factory + +Azure Authorization module consists of one or more clients. We provide a client factory which could be used to create any client in this module. + +```go +clientFactory, err := armauthorization.NewClientFactory(, 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). + +```go +options := arm.ClientOptions { + ClientOptions: azcore.ClientOptions { + Cloud: cloud.AzureChina, + }, +} +clientFactory, err := armauthorization.NewClientFactory(, 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.NewPermissionsClient() +``` + +## Provide Feedback + +If you encounter bugs or have suggestions, please +[open an issue](https://github.com/Azure/azure-sdk-for-go/issues) and assign the `Authorization` label. + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. +For details, visit [https://cla.microsoft.com](https://cla.microsoft.com). + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only +need to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information, see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/autorest.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/autorest.md new file mode 100644 index 000000000..ef18c345b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/autorest.md @@ -0,0 +1,13 @@ +### AutoRest Configuration + +> see https://aka.ms/autorest + +``` yaml +azure-arm: true +require: +- https://github.com/Azure/azure-rest-api-specs/blob/53b1affe357b3bfbb53721d0a2002382a046d3b0/specification/authorization/resource-manager/readme.md +- https://github.com/Azure/azure-rest-api-specs/blob/53b1affe357b3bfbb53721d0a2002382a046d3b0/specification/authorization/resource-manager/readme.go.md +license-header: MICROSOFT_MIT_NO_VERSION +module-version: 2.2.0 +tag: package-2022-04-01 +``` \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/build.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/build.go new file mode 100644 index 000000000..6d9616df8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/build.go @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// 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 ../../../../eng/scripts/build.ps1 -skipBuild -cleanGenerated -format -tidy -generate resourcemanager/authorization/armauthorization + +package armauthorization diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/ci.yml new file mode 100644 index 000000000..af58b0f74 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/ci.yml @@ -0,0 +1,28 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/authorization/armauthorization/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/authorization/armauthorization/ + +stages: +- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + IncludeRelease: true + ServiceDirectory: 'resourcemanager/authorization/armauthorization' diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/classicadministrators_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/classicadministrators_client.go new file mode 100644 index 000000000..b10e91fa1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/classicadministrators_client.go @@ -0,0 +1,99 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// ClassicAdministratorsClient contains the methods for the ClassicAdministrators group. +// Don't use this type directly, use NewClassicAdministratorsClient() instead. +type ClassicAdministratorsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewClassicAdministratorsClient creates a new instance of ClassicAdministratorsClient with the specified values. +// - subscriptionID - The ID of the target subscription. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewClassicAdministratorsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ClassicAdministratorsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &ClassicAdministratorsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// NewListPager - Gets service administrator, account administrator, and co-administrators for the subscription. +// +// Generated from API version 2015-07-01 +// - options - ClassicAdministratorsClientListOptions contains the optional parameters for the ClassicAdministratorsClient.NewListPager +// method. +func (client *ClassicAdministratorsClient) NewListPager(options *ClassicAdministratorsClientListOptions) *runtime.Pager[ClassicAdministratorsClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[ClassicAdministratorsClientListResponse]{ + More: func(page ClassicAdministratorsClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *ClassicAdministratorsClientListResponse) (ClassicAdministratorsClientListResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "ClassicAdministratorsClient.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 ClassicAdministratorsClientListResponse{}, err + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *ClassicAdministratorsClient) listCreateRequest(ctx context.Context, options *ClassicAdministratorsClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/classicAdministrators" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2015-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *ClassicAdministratorsClient) listHandleResponse(resp *http.Response) (ClassicAdministratorsClientListResponse, error) { + result := ClassicAdministratorsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ClassicAdministratorListResult); err != nil { + return ClassicAdministratorsClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/client_factory.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/client_factory.go new file mode 100644 index 000000000..0bd46c858 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/client_factory.go @@ -0,0 +1,134 @@ +//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 armauthorization + +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 ID of the target subscription. +// - 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 +} + +// NewClassicAdministratorsClient creates a new instance of ClassicAdministratorsClient. +func (c *ClientFactory) NewClassicAdministratorsClient() *ClassicAdministratorsClient { + subClient, _ := NewClassicAdministratorsClient(c.subscriptionID, c.credential, c.options) + return subClient +} + +// NewDenyAssignmentsClient creates a new instance of DenyAssignmentsClient. +func (c *ClientFactory) NewDenyAssignmentsClient() *DenyAssignmentsClient { + subClient, _ := NewDenyAssignmentsClient(c.subscriptionID, c.credential, c.options) + return subClient +} + +// NewEligibleChildResourcesClient creates a new instance of EligibleChildResourcesClient. +func (c *ClientFactory) NewEligibleChildResourcesClient() *EligibleChildResourcesClient { + subClient, _ := NewEligibleChildResourcesClient(c.credential, c.options) + return subClient +} + +// NewGlobalAdministratorClient creates a new instance of GlobalAdministratorClient. +func (c *ClientFactory) NewGlobalAdministratorClient() *GlobalAdministratorClient { + subClient, _ := NewGlobalAdministratorClient(c.credential, c.options) + return subClient +} + +// NewPermissionsClient creates a new instance of PermissionsClient. +func (c *ClientFactory) NewPermissionsClient() *PermissionsClient { + subClient, _ := NewPermissionsClient(c.subscriptionID, c.credential, c.options) + return subClient +} + +// NewProviderOperationsMetadataClient creates a new instance of ProviderOperationsMetadataClient. +func (c *ClientFactory) NewProviderOperationsMetadataClient() *ProviderOperationsMetadataClient { + subClient, _ := NewProviderOperationsMetadataClient(c.credential, c.options) + return subClient +} + +// NewRoleAssignmentScheduleInstancesClient creates a new instance of RoleAssignmentScheduleInstancesClient. +func (c *ClientFactory) NewRoleAssignmentScheduleInstancesClient() *RoleAssignmentScheduleInstancesClient { + subClient, _ := NewRoleAssignmentScheduleInstancesClient(c.credential, c.options) + return subClient +} + +// NewRoleAssignmentScheduleRequestsClient creates a new instance of RoleAssignmentScheduleRequestsClient. +func (c *ClientFactory) NewRoleAssignmentScheduleRequestsClient() *RoleAssignmentScheduleRequestsClient { + subClient, _ := NewRoleAssignmentScheduleRequestsClient(c.credential, c.options) + return subClient +} + +// NewRoleAssignmentSchedulesClient creates a new instance of RoleAssignmentSchedulesClient. +func (c *ClientFactory) NewRoleAssignmentSchedulesClient() *RoleAssignmentSchedulesClient { + subClient, _ := NewRoleAssignmentSchedulesClient(c.credential, c.options) + return subClient +} + +// NewRoleAssignmentsClient creates a new instance of RoleAssignmentsClient. +func (c *ClientFactory) NewRoleAssignmentsClient() *RoleAssignmentsClient { + subClient, _ := NewRoleAssignmentsClient(c.subscriptionID, c.credential, c.options) + return subClient +} + +// NewRoleDefinitionsClient creates a new instance of RoleDefinitionsClient. +func (c *ClientFactory) NewRoleDefinitionsClient() *RoleDefinitionsClient { + subClient, _ := NewRoleDefinitionsClient(c.credential, c.options) + return subClient +} + +// NewRoleEligibilityScheduleInstancesClient creates a new instance of RoleEligibilityScheduleInstancesClient. +func (c *ClientFactory) NewRoleEligibilityScheduleInstancesClient() *RoleEligibilityScheduleInstancesClient { + subClient, _ := NewRoleEligibilityScheduleInstancesClient(c.credential, c.options) + return subClient +} + +// NewRoleEligibilityScheduleRequestsClient creates a new instance of RoleEligibilityScheduleRequestsClient. +func (c *ClientFactory) NewRoleEligibilityScheduleRequestsClient() *RoleEligibilityScheduleRequestsClient { + subClient, _ := NewRoleEligibilityScheduleRequestsClient(c.credential, c.options) + return subClient +} + +// NewRoleEligibilitySchedulesClient creates a new instance of RoleEligibilitySchedulesClient. +func (c *ClientFactory) NewRoleEligibilitySchedulesClient() *RoleEligibilitySchedulesClient { + subClient, _ := NewRoleEligibilitySchedulesClient(c.credential, c.options) + return subClient +} + +// NewRoleManagementPoliciesClient creates a new instance of RoleManagementPoliciesClient. +func (c *ClientFactory) NewRoleManagementPoliciesClient() *RoleManagementPoliciesClient { + subClient, _ := NewRoleManagementPoliciesClient(c.credential, c.options) + return subClient +} + +// NewRoleManagementPolicyAssignmentsClient creates a new instance of RoleManagementPolicyAssignmentsClient. +func (c *ClientFactory) NewRoleManagementPolicyAssignmentsClient() *RoleManagementPolicyAssignmentsClient { + subClient, _ := NewRoleManagementPolicyAssignmentsClient(c.credential, c.options) + return subClient +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/constants.go new file mode 100644 index 000000000..bdc378893 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/constants.go @@ -0,0 +1,300 @@ +//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 armauthorization + +const ( + moduleName = "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization" + moduleVersion = "v2.2.0" +) + +// ApprovalMode - The type of rule +type ApprovalMode string + +const ( + ApprovalModeNoApproval ApprovalMode = "NoApproval" + ApprovalModeParallel ApprovalMode = "Parallel" + ApprovalModeSerial ApprovalMode = "Serial" + ApprovalModeSingleStage ApprovalMode = "SingleStage" +) + +// PossibleApprovalModeValues returns the possible values for the ApprovalMode const type. +func PossibleApprovalModeValues() []ApprovalMode { + return []ApprovalMode{ + ApprovalModeNoApproval, + ApprovalModeParallel, + ApprovalModeSerial, + ApprovalModeSingleStage, + } +} + +// AssignmentType - Assignment type of the role assignment schedule +type AssignmentType string + +const ( + AssignmentTypeActivated AssignmentType = "Activated" + AssignmentTypeAssigned AssignmentType = "Assigned" +) + +// PossibleAssignmentTypeValues returns the possible values for the AssignmentType const type. +func PossibleAssignmentTypeValues() []AssignmentType { + return []AssignmentType{ + AssignmentTypeActivated, + AssignmentTypeAssigned, + } +} + +// EnablementRules - The type of enablement rule +type EnablementRules string + +const ( + EnablementRulesJustification EnablementRules = "Justification" + EnablementRulesMultiFactorAuthentication EnablementRules = "MultiFactorAuthentication" + EnablementRulesTicketing EnablementRules = "Ticketing" +) + +// PossibleEnablementRulesValues returns the possible values for the EnablementRules const type. +func PossibleEnablementRulesValues() []EnablementRules { + return []EnablementRules{ + EnablementRulesJustification, + EnablementRulesMultiFactorAuthentication, + EnablementRulesTicketing, + } +} + +// MemberType - Membership type of the role assignment schedule +type MemberType string + +const ( + MemberTypeDirect MemberType = "Direct" + MemberTypeGroup MemberType = "Group" + MemberTypeInherited MemberType = "Inherited" +) + +// PossibleMemberTypeValues returns the possible values for the MemberType const type. +func PossibleMemberTypeValues() []MemberType { + return []MemberType{ + MemberTypeDirect, + MemberTypeGroup, + MemberTypeInherited, + } +} + +// NotificationDeliveryMechanism - The type of notification. +type NotificationDeliveryMechanism string + +const ( + NotificationDeliveryMechanismEmail NotificationDeliveryMechanism = "Email" +) + +// PossibleNotificationDeliveryMechanismValues returns the possible values for the NotificationDeliveryMechanism const type. +func PossibleNotificationDeliveryMechanismValues() []NotificationDeliveryMechanism { + return []NotificationDeliveryMechanism{ + NotificationDeliveryMechanismEmail, + } +} + +// NotificationLevel - The notification level. +type NotificationLevel string + +const ( + NotificationLevelAll NotificationLevel = "All" + NotificationLevelCritical NotificationLevel = "Critical" + NotificationLevelNone NotificationLevel = "None" +) + +// PossibleNotificationLevelValues returns the possible values for the NotificationLevel const type. +func PossibleNotificationLevelValues() []NotificationLevel { + return []NotificationLevel{ + NotificationLevelAll, + NotificationLevelCritical, + NotificationLevelNone, + } +} + +// PrincipalType - The principal type of the assigned principal ID. +type PrincipalType string + +const ( + PrincipalTypeDevice PrincipalType = "Device" + PrincipalTypeForeignGroup PrincipalType = "ForeignGroup" + PrincipalTypeGroup PrincipalType = "Group" + PrincipalTypeServicePrincipal PrincipalType = "ServicePrincipal" + PrincipalTypeUser PrincipalType = "User" +) + +// PossiblePrincipalTypeValues returns the possible values for the PrincipalType const type. +func PossiblePrincipalTypeValues() []PrincipalType { + return []PrincipalType{ + PrincipalTypeDevice, + PrincipalTypeForeignGroup, + PrincipalTypeGroup, + PrincipalTypeServicePrincipal, + PrincipalTypeUser, + } +} + +// RecipientType - The recipient type. +type RecipientType string + +const ( + RecipientTypeAdmin RecipientType = "Admin" + RecipientTypeApprover RecipientType = "Approver" + RecipientTypeRequestor RecipientType = "Requestor" +) + +// PossibleRecipientTypeValues returns the possible values for the RecipientType const type. +func PossibleRecipientTypeValues() []RecipientType { + return []RecipientType{ + RecipientTypeAdmin, + RecipientTypeApprover, + RecipientTypeRequestor, + } +} + +// RequestType - The type of the role assignment schedule request. Eg: SelfActivate, AdminAssign etc +type RequestType string + +const ( + RequestTypeAdminAssign RequestType = "AdminAssign" + RequestTypeAdminExtend RequestType = "AdminExtend" + RequestTypeAdminRemove RequestType = "AdminRemove" + RequestTypeAdminRenew RequestType = "AdminRenew" + RequestTypeAdminUpdate RequestType = "AdminUpdate" + RequestTypeSelfActivate RequestType = "SelfActivate" + RequestTypeSelfDeactivate RequestType = "SelfDeactivate" + RequestTypeSelfExtend RequestType = "SelfExtend" + RequestTypeSelfRenew RequestType = "SelfRenew" +) + +// PossibleRequestTypeValues returns the possible values for the RequestType const type. +func PossibleRequestTypeValues() []RequestType { + return []RequestType{ + RequestTypeAdminAssign, + RequestTypeAdminExtend, + RequestTypeAdminRemove, + RequestTypeAdminRenew, + RequestTypeAdminUpdate, + RequestTypeSelfActivate, + RequestTypeSelfDeactivate, + RequestTypeSelfExtend, + RequestTypeSelfRenew, + } +} + +// RoleManagementPolicyRuleType - The type of rule +type RoleManagementPolicyRuleType string + +const ( + RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule RoleManagementPolicyRuleType = "RoleManagementPolicyApprovalRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule RoleManagementPolicyRuleType = "RoleManagementPolicyAuthenticationContextRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule RoleManagementPolicyRuleType = "RoleManagementPolicyEnablementRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule RoleManagementPolicyRuleType = "RoleManagementPolicyExpirationRule" + RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule RoleManagementPolicyRuleType = "RoleManagementPolicyNotificationRule" +) + +// PossibleRoleManagementPolicyRuleTypeValues returns the possible values for the RoleManagementPolicyRuleType const type. +func PossibleRoleManagementPolicyRuleTypeValues() []RoleManagementPolicyRuleType { + return []RoleManagementPolicyRuleType{ + RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule, + RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule, + RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule, + RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule, + RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule, + } +} + +// Status - The status of the role assignment schedule. +type Status string + +const ( + StatusAccepted Status = "Accepted" + StatusAdminApproved Status = "AdminApproved" + StatusAdminDenied Status = "AdminDenied" + StatusCanceled Status = "Canceled" + StatusDenied Status = "Denied" + StatusFailed Status = "Failed" + StatusFailedAsResourceIsLocked Status = "FailedAsResourceIsLocked" + StatusGranted Status = "Granted" + StatusInvalid Status = "Invalid" + StatusPendingAdminDecision Status = "PendingAdminDecision" + StatusPendingApproval Status = "PendingApproval" + StatusPendingApprovalProvisioning Status = "PendingApprovalProvisioning" + StatusPendingEvaluation Status = "PendingEvaluation" + StatusPendingExternalProvisioning Status = "PendingExternalProvisioning" + StatusPendingProvisioning Status = "PendingProvisioning" + StatusPendingRevocation Status = "PendingRevocation" + StatusPendingScheduleCreation Status = "PendingScheduleCreation" + StatusProvisioned Status = "Provisioned" + StatusProvisioningStarted Status = "ProvisioningStarted" + StatusRevoked Status = "Revoked" + StatusScheduleCreated Status = "ScheduleCreated" + StatusTimedOut Status = "TimedOut" +) + +// PossibleStatusValues returns the possible values for the Status const type. +func PossibleStatusValues() []Status { + return []Status{ + StatusAccepted, + StatusAdminApproved, + StatusAdminDenied, + StatusCanceled, + StatusDenied, + StatusFailed, + StatusFailedAsResourceIsLocked, + StatusGranted, + StatusInvalid, + StatusPendingAdminDecision, + StatusPendingApproval, + StatusPendingApprovalProvisioning, + StatusPendingEvaluation, + StatusPendingExternalProvisioning, + StatusPendingProvisioning, + StatusPendingRevocation, + StatusPendingScheduleCreation, + StatusProvisioned, + StatusProvisioningStarted, + StatusRevoked, + StatusScheduleCreated, + StatusTimedOut, + } +} + +// Type - Type of the role assignment schedule expiration +type Type string + +const ( + TypeAfterDateTime Type = "AfterDateTime" + TypeAfterDuration Type = "AfterDuration" + TypeNoExpiration Type = "NoExpiration" +) + +// PossibleTypeValues returns the possible values for the Type const type. +func PossibleTypeValues() []Type { + return []Type{ + TypeAfterDateTime, + TypeAfterDuration, + TypeNoExpiration, + } +} + +// UserType - The type of user. +type UserType string + +const ( + UserTypeGroup UserType = "Group" + UserTypeUser UserType = "User" +) + +// PossibleUserTypeValues returns the possible values for the UserType const type. +func PossibleUserTypeValues() []UserType { + return []UserType{ + UserTypeGroup, + UserTypeUser, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/denyassignments_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/denyassignments_client.go new file mode 100644 index 000000000..16e58650f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/denyassignments_client.go @@ -0,0 +1,406 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// DenyAssignmentsClient contains the methods for the DenyAssignments group. +// Don't use this type directly, use NewDenyAssignmentsClient() instead. +type DenyAssignmentsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewDenyAssignmentsClient creates a new instance of DenyAssignmentsClient with the specified values. +// - subscriptionID - The ID of the target subscription. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewDenyAssignmentsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*DenyAssignmentsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &DenyAssignmentsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// Get - Get the specified deny assignment. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the deny assignment. +// - denyAssignmentID - The ID of the deny assignment to get. +// - options - DenyAssignmentsClientGetOptions contains the optional parameters for the DenyAssignmentsClient.Get method. +func (client *DenyAssignmentsClient) Get(ctx context.Context, scope string, denyAssignmentID string, options *DenyAssignmentsClientGetOptions) (DenyAssignmentsClientGetResponse, error) { + var err error + const operationName = "DenyAssignmentsClient.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, scope, denyAssignmentID, options) + if err != nil { + return DenyAssignmentsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DenyAssignmentsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DenyAssignmentsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *DenyAssignmentsClient) getCreateRequest(ctx context.Context, scope string, denyAssignmentID string, options *DenyAssignmentsClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/denyAssignments/{denyAssignmentId}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if denyAssignmentID == "" { + return nil, errors.New("parameter denyAssignmentID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{denyAssignmentId}", url.PathEscape(denyAssignmentID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *DenyAssignmentsClient) getHandleResponse(resp *http.Response) (DenyAssignmentsClientGetResponse, error) { + result := DenyAssignmentsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DenyAssignment); err != nil { + return DenyAssignmentsClientGetResponse{}, err + } + return result, nil +} + +// GetByID - Gets a deny assignment by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - denyAssignmentID - The fully qualified deny assignment ID. For example, use the format, /subscriptions/{guid}/providers/Microsoft.Authorization/denyAssignments/{denyAssignmentId} +// for subscription level deny assignments, +// or /providers/Microsoft.Authorization/denyAssignments/{denyAssignmentId} for tenant level deny assignments. +// - options - DenyAssignmentsClientGetByIDOptions contains the optional parameters for the DenyAssignmentsClient.GetByID method. +func (client *DenyAssignmentsClient) GetByID(ctx context.Context, denyAssignmentID string, options *DenyAssignmentsClientGetByIDOptions) (DenyAssignmentsClientGetByIDResponse, error) { + var err error + const operationName = "DenyAssignmentsClient.GetByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getByIDCreateRequest(ctx, denyAssignmentID, options) + if err != nil { + return DenyAssignmentsClientGetByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DenyAssignmentsClientGetByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DenyAssignmentsClientGetByIDResponse{}, err + } + resp, err := client.getByIDHandleResponse(httpResp) + return resp, err +} + +// getByIDCreateRequest creates the GetByID request. +func (client *DenyAssignmentsClient) getByIDCreateRequest(ctx context.Context, denyAssignmentID string, options *DenyAssignmentsClientGetByIDOptions) (*policy.Request, error) { + urlPath := "/{denyAssignmentId}" + urlPath = strings.ReplaceAll(urlPath, "{denyAssignmentId}", denyAssignmentID) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getByIDHandleResponse handles the GetByID response. +func (client *DenyAssignmentsClient) getByIDHandleResponse(resp *http.Response) (DenyAssignmentsClientGetByIDResponse, error) { + result := DenyAssignmentsClientGetByIDResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DenyAssignment); err != nil { + return DenyAssignmentsClientGetByIDResponse{}, err + } + return result, nil +} + +// NewListPager - Gets all deny assignments for the subscription. +// +// Generated from API version 2022-04-01 +// - options - DenyAssignmentsClientListOptions contains the optional parameters for the DenyAssignmentsClient.NewListPager +// method. +func (client *DenyAssignmentsClient) NewListPager(options *DenyAssignmentsClientListOptions) *runtime.Pager[DenyAssignmentsClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[DenyAssignmentsClientListResponse]{ + More: func(page DenyAssignmentsClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DenyAssignmentsClientListResponse) (DenyAssignmentsClientListResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DenyAssignmentsClient.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 DenyAssignmentsClientListResponse{}, err + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *DenyAssignmentsClient) listCreateRequest(ctx context.Context, options *DenyAssignmentsClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/denyAssignments" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *DenyAssignmentsClient) listHandleResponse(resp *http.Response) (DenyAssignmentsClientListResponse, error) { + result := DenyAssignmentsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DenyAssignmentListResult); err != nil { + return DenyAssignmentsClientListResponse{}, err + } + return result, nil +} + +// NewListForResourcePager - Gets deny assignments for a resource. +// +// Generated from API version 2022-04-01 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type of the resource. +// - resourceName - The name of the resource to get deny assignments for. +// - options - DenyAssignmentsClientListForResourceOptions contains the optional parameters for the DenyAssignmentsClient.NewListForResourcePager +// method. +func (client *DenyAssignmentsClient) NewListForResourcePager(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, options *DenyAssignmentsClientListForResourceOptions) *runtime.Pager[DenyAssignmentsClientListForResourceResponse] { + return runtime.NewPager(runtime.PagingHandler[DenyAssignmentsClientListForResourceResponse]{ + More: func(page DenyAssignmentsClientListForResourceResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DenyAssignmentsClientListForResourceResponse) (DenyAssignmentsClientListForResourceResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DenyAssignmentsClient.NewListForResourcePager") + 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.listForResourceCreateRequest(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, options) + }, nil) + if err != nil { + return DenyAssignmentsClientListForResourceResponse{}, err + } + return client.listForResourceHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForResourceCreateRequest creates the ListForResource request. +func (client *DenyAssignmentsClient) listForResourceCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, options *DenyAssignmentsClientListForResourceOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}/providers/Microsoft.Authorization/denyAssignments" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", resourceProviderNamespace) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForResourceHandleResponse handles the ListForResource response. +func (client *DenyAssignmentsClient) listForResourceHandleResponse(resp *http.Response) (DenyAssignmentsClientListForResourceResponse, error) { + result := DenyAssignmentsClientListForResourceResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DenyAssignmentListResult); err != nil { + return DenyAssignmentsClientListForResourceResponse{}, err + } + return result, nil +} + +// NewListForResourceGroupPager - Gets deny assignments for a resource group. +// +// Generated from API version 2022-04-01 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - options - DenyAssignmentsClientListForResourceGroupOptions contains the optional parameters for the DenyAssignmentsClient.NewListForResourceGroupPager +// method. +func (client *DenyAssignmentsClient) NewListForResourceGroupPager(resourceGroupName string, options *DenyAssignmentsClientListForResourceGroupOptions) *runtime.Pager[DenyAssignmentsClientListForResourceGroupResponse] { + return runtime.NewPager(runtime.PagingHandler[DenyAssignmentsClientListForResourceGroupResponse]{ + More: func(page DenyAssignmentsClientListForResourceGroupResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DenyAssignmentsClientListForResourceGroupResponse) (DenyAssignmentsClientListForResourceGroupResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DenyAssignmentsClient.NewListForResourceGroupPager") + 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.listForResourceGroupCreateRequest(ctx, resourceGroupName, options) + }, nil) + if err != nil { + return DenyAssignmentsClientListForResourceGroupResponse{}, err + } + return client.listForResourceGroupHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForResourceGroupCreateRequest creates the ListForResourceGroup request. +func (client *DenyAssignmentsClient) listForResourceGroupCreateRequest(ctx context.Context, resourceGroupName string, options *DenyAssignmentsClientListForResourceGroupOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Authorization/denyAssignments" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForResourceGroupHandleResponse handles the ListForResourceGroup response. +func (client *DenyAssignmentsClient) listForResourceGroupHandleResponse(resp *http.Response) (DenyAssignmentsClientListForResourceGroupResponse, error) { + result := DenyAssignmentsClientListForResourceGroupResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DenyAssignmentListResult); err != nil { + return DenyAssignmentsClientListForResourceGroupResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets deny assignments for a scope. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the deny assignments. +// - options - DenyAssignmentsClientListForScopeOptions contains the optional parameters for the DenyAssignmentsClient.NewListForScopePager +// method. +func (client *DenyAssignmentsClient) NewListForScopePager(scope string, options *DenyAssignmentsClientListForScopeOptions) *runtime.Pager[DenyAssignmentsClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[DenyAssignmentsClientListForScopeResponse]{ + More: func(page DenyAssignmentsClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DenyAssignmentsClientListForScopeResponse) (DenyAssignmentsClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DenyAssignmentsClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return DenyAssignmentsClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *DenyAssignmentsClient) listForScopeCreateRequest(ctx context.Context, scope string, options *DenyAssignmentsClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/denyAssignments" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *DenyAssignmentsClient) listForScopeHandleResponse(resp *http.Response) (DenyAssignmentsClientListForScopeResponse, error) { + result := DenyAssignmentsClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DenyAssignmentListResult); err != nil { + return DenyAssignmentsClientListForScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/eligiblechildresources_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/eligiblechildresources_client.go new file mode 100644 index 000000000..64efb1036 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/eligiblechildresources_client.go @@ -0,0 +1,95 @@ +//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 armauthorization + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "strings" +) + +// EligibleChildResourcesClient contains the methods for the EligibleChildResources group. +// Don't use this type directly, use NewEligibleChildResourcesClient() instead. +type EligibleChildResourcesClient struct { + internal *arm.Client +} + +// NewEligibleChildResourcesClient creates a new instance of EligibleChildResourcesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewEligibleChildResourcesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*EligibleChildResourcesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &EligibleChildResourcesClient{ + internal: cl, + } + return client, nil +} + +// NewGetPager - Get the child resources of a resource on which user has eligible access +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy. +// - options - EligibleChildResourcesClientGetOptions contains the optional parameters for the EligibleChildResourcesClient.NewGetPager +// method. +func (client *EligibleChildResourcesClient) NewGetPager(scope string, options *EligibleChildResourcesClientGetOptions) *runtime.Pager[EligibleChildResourcesClientGetResponse] { + return runtime.NewPager(runtime.PagingHandler[EligibleChildResourcesClientGetResponse]{ + More: func(page EligibleChildResourcesClientGetResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *EligibleChildResourcesClientGetResponse) (EligibleChildResourcesClientGetResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "EligibleChildResourcesClient.NewGetPager") + 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.getCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return EligibleChildResourcesClientGetResponse{}, err + } + return client.getHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// getCreateRequest creates the Get request. +func (client *EligibleChildResourcesClient) getCreateRequest(ctx context.Context, scope string, options *EligibleChildResourcesClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/eligibleChildResources" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *EligibleChildResourcesClient) getHandleResponse(resp *http.Response) (EligibleChildResourcesClientGetResponse, error) { + result := EligibleChildResourcesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.EligibleChildResourcesListResult); err != nil { + return EligibleChildResourcesClientGetResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/globaladministrator_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/globaladministrator_client.go new file mode 100644 index 000000000..7cc75f42f --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/globaladministrator_client.go @@ -0,0 +1,79 @@ +//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 armauthorization + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" +) + +// GlobalAdministratorClient contains the methods for the GlobalAdministrator group. +// Don't use this type directly, use NewGlobalAdministratorClient() instead. +type GlobalAdministratorClient struct { + internal *arm.Client +} + +// NewGlobalAdministratorClient creates a new instance of GlobalAdministratorClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewGlobalAdministratorClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*GlobalAdministratorClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &GlobalAdministratorClient{ + internal: cl, + } + return client, nil +} + +// ElevateAccess - Elevates access for a Global Administrator. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2015-07-01 +// - options - GlobalAdministratorClientElevateAccessOptions contains the optional parameters for the GlobalAdministratorClient.ElevateAccess +// method. +func (client *GlobalAdministratorClient) ElevateAccess(ctx context.Context, options *GlobalAdministratorClientElevateAccessOptions) (GlobalAdministratorClientElevateAccessResponse, error) { + var err error + const operationName = "GlobalAdministratorClient.ElevateAccess" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.elevateAccessCreateRequest(ctx, options) + if err != nil { + return GlobalAdministratorClientElevateAccessResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return GlobalAdministratorClientElevateAccessResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return GlobalAdministratorClientElevateAccessResponse{}, err + } + return GlobalAdministratorClientElevateAccessResponse{}, nil +} + +// elevateAccessCreateRequest creates the ElevateAccess request. +func (client *GlobalAdministratorClient) elevateAccessCreateRequest(ctx context.Context, options *GlobalAdministratorClientElevateAccessOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Authorization/elevateAccess" + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2015-07-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/interfaces.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/interfaces.go new file mode 100644 index 000000000..7d6c52181 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/interfaces.go @@ -0,0 +1,19 @@ +//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 armauthorization + +// RoleManagementPolicyRuleClassification provides polymorphic access to related types. +// Call the interface's GetRoleManagementPolicyRule() method to access the common type. +// Use a type switch to determine the concrete type. The possible types are: +// - *RoleManagementPolicyApprovalRule, *RoleManagementPolicyAuthenticationContextRule, *RoleManagementPolicyEnablementRule, +// - *RoleManagementPolicyExpirationRule, *RoleManagementPolicyNotificationRule, *RoleManagementPolicyRule +type RoleManagementPolicyRuleClassification interface { + // GetRoleManagementPolicyRule returns the RoleManagementPolicyRule content of the underlying type. + GetRoleManagementPolicyRule() *RoleManagementPolicyRule +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/models.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/models.go new file mode 100644 index 000000000..2ee2c7c3c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/models.go @@ -0,0 +1,1475 @@ +//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 armauthorization + +import "time" + +// ApprovalSettings - The approval settings. +type ApprovalSettings struct { + // The type of rule + ApprovalMode *ApprovalMode + + // The approval stages of the request. + ApprovalStages []*ApprovalStage + + // Determines whether approval is required or not. + IsApprovalRequired *bool + + // Determines whether approval is required for assignment extension. + IsApprovalRequiredForExtension *bool + + // Determine whether requestor justification is required. + IsRequestorJustificationRequired *bool +} + +// ApprovalStage - The approval stage. +type ApprovalStage struct { + // The time in days when approval request would be timed out + ApprovalStageTimeOutInDays *int32 + + // The escalation approver of the request. + EscalationApprovers []*UserSet + + // The time in minutes when the approval request would be escalated if the primary approver does not approve + EscalationTimeInMinutes *int32 + + // Determines whether approver need to provide justification for his decision. + IsApproverJustificationRequired *bool + + // The value determine whether escalation feature is enabled. + IsEscalationEnabled *bool + + // The primary approver of the request. + PrimaryApprovers []*UserSet +} + +// ClassicAdministrator - Classic Administrators +type ClassicAdministrator struct { + // The ID of the administrator. + ID *string + + // The name of the administrator. + Name *string + + // Properties for the classic administrator. + Properties *ClassicAdministratorProperties + + // The type of the administrator. + Type *string +} + +// ClassicAdministratorListResult - ClassicAdministrator list result information. +type ClassicAdministratorListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // An array of administrators. + Value []*ClassicAdministrator +} + +// ClassicAdministratorProperties - Classic Administrator properties. +type ClassicAdministratorProperties struct { + // The email address of the administrator. + EmailAddress *string + + // The role of the administrator. + Role *string +} + +// DenyAssignment - Deny Assignment +type DenyAssignment struct { + // Deny assignment properties. + Properties *DenyAssignmentProperties + + // READ-ONLY; The deny assignment ID. + ID *string + + // READ-ONLY; The deny assignment name. + Name *string + + // READ-ONLY; The deny assignment type. + Type *string +} + +// DenyAssignmentFilter - Deny Assignments filter +type DenyAssignmentFilter struct { + // Return deny assignment with specified name. + DenyAssignmentName *string + + // Return all deny assignments where the specified principal is listed either in the principals list or exclude principals + // list of deny assignments. + GdprExportPrincipalID *string + + // Return all deny assignments where the specified principal is listed in the principals list of deny assignments. + PrincipalID *string +} + +// DenyAssignmentListResult - Deny assignment list operation result. +type DenyAssignmentListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Deny assignment list. + Value []*DenyAssignment +} + +// DenyAssignmentPermission - Deny assignment permissions. +type DenyAssignmentPermission struct { + // Actions to which the deny assignment does not grant access. + Actions []*string + + // The conditions on the Deny assignment permission. This limits the resources it applies to. + Condition *string + + // Version of the condition. + ConditionVersion *string + + // Data actions to which the deny assignment does not grant access. + DataActions []*string + + // Actions to exclude from that the deny assignment does not grant access. + NotActions []*string + + // Data actions to exclude from that the deny assignment does not grant access. + NotDataActions []*string +} + +// DenyAssignmentProperties - Deny assignment properties. +type DenyAssignmentProperties struct { + // The display name of the deny assignment. + DenyAssignmentName *string + + // The description of the deny assignment. + Description *string + + // Determines if the deny assignment applies to child scopes. Default value is false. + DoNotApplyToChildScopes *bool + + // Array of principals to which the deny assignment does not apply. + ExcludePrincipals []*Principal + + // Specifies whether this deny assignment was created by Azure and cannot be edited or deleted. + IsSystemProtected *bool + + // An array of permissions that are denied by the deny assignment. + Permissions []*DenyAssignmentPermission + + // Array of principals to which the deny assignment applies. + Principals []*Principal + + // The deny assignment scope. + Scope *string +} + +// EligibleChildResource - Eligible child resource +type EligibleChildResource struct { + // READ-ONLY; The resource scope Id. + ID *string + + // READ-ONLY; The resource name. + Name *string + + // READ-ONLY; The resource type. + Type *string +} + +// EligibleChildResourcesListResult - Eligible child resources list operation result. +type EligibleChildResourcesListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Eligible child resource list. + Value []*EligibleChildResource +} + +// ErrorAdditionalInfo - The resource management error additional info. +type ErrorAdditionalInfo struct { + // READ-ONLY; The additional info. + Info any + + // READ-ONLY; The additional info type. + Type *string +} + +// ErrorDetail - The error detail. +type ErrorDetail struct { + // READ-ONLY; The error additional info. + AdditionalInfo []*ErrorAdditionalInfo + + // READ-ONLY; The error code. + Code *string + + // READ-ONLY; The error details. + Details []*ErrorDetail + + // READ-ONLY; The error message. + Message *string + + // READ-ONLY; The error target. + Target *string +} + +// ErrorResponse - Common error response for all Azure Resource Manager APIs to return error details for failed operations. +// (This also follows the OData error response format.). +type ErrorResponse struct { + // The error object. + Error *ErrorDetail +} + +type ExpandedProperties struct { + // Details of the principal + Principal *ExpandedPropertiesPrincipal + + // Details of role definition + RoleDefinition *ExpandedPropertiesRoleDefinition + + // Details of the resource scope + Scope *ExpandedPropertiesScope +} + +// ExpandedPropertiesPrincipal - Details of the principal +type ExpandedPropertiesPrincipal struct { + // Display name of the principal + DisplayName *string + + // Email id of the principal + Email *string + + // Id of the principal + ID *string + + // Type of the principal + Type *string +} + +// ExpandedPropertiesRoleDefinition - Details of role definition +type ExpandedPropertiesRoleDefinition struct { + // Display name of the role definition + DisplayName *string + + // Id of the role definition + ID *string + + // Type of the role definition + Type *string +} + +// ExpandedPropertiesScope - Details of the resource scope +type ExpandedPropertiesScope struct { + // Display name of the resource + DisplayName *string + + // Scope id of the resource + ID *string + + // Type of the resource + Type *string +} + +// Permission - Role definition permissions. +type Permission struct { + // Allowed actions. + Actions []*string + + // Allowed Data actions. + DataActions []*string + + // Denied actions. + NotActions []*string + + // Denied Data actions. + NotDataActions []*string +} + +// PermissionGetResult - Permissions information. +type PermissionGetResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // An array of permissions. + Value []*Permission +} + +// PolicyAssignmentProperties - Expanded info of resource scope, role definition and policy +type PolicyAssignmentProperties struct { + // Details of the policy + Policy *PolicyAssignmentPropertiesPolicy + + // Details of role definition + RoleDefinition *PolicyAssignmentPropertiesRoleDefinition + + // Details of the resource scope + Scope *PolicyAssignmentPropertiesScope +} + +// PolicyAssignmentPropertiesPolicy - Details of the policy +type PolicyAssignmentPropertiesPolicy struct { + // Id of the policy + ID *string + + // The last modified date time. + LastModifiedDateTime *time.Time + + // READ-ONLY; The name of the entity last modified it + LastModifiedBy *Principal +} + +// PolicyAssignmentPropertiesRoleDefinition - Details of role definition +type PolicyAssignmentPropertiesRoleDefinition struct { + // Display name of the role definition + DisplayName *string + + // Id of the role definition + ID *string + + // Type of the role definition + Type *string +} + +// PolicyAssignmentPropertiesScope - Details of the resource scope +type PolicyAssignmentPropertiesScope struct { + // Display name of the resource + DisplayName *string + + // Scope id of the resource + ID *string + + // Type of the resource + Type *string +} + +// PolicyProperties - Expanded info of resource scope +type PolicyProperties struct { + // READ-ONLY; Details of the resource scope + Scope *PolicyPropertiesScope +} + +// PolicyPropertiesScope - Details of the resource scope +type PolicyPropertiesScope struct { + // Display name of the resource + DisplayName *string + + // Scope id of the resource + ID *string + + // Type of the resource + Type *string +} + +// Principal - The name of the entity last modified it +type Principal struct { + // The name of the principal made changes + DisplayName *string + + // Email of principal + Email *string + + // The id of the principal made changes + ID *string + + // Type of principal such as user , group etc + Type *string +} + +// ProviderOperation - Operation +type ProviderOperation struct { + // The operation description. + Description *string + + // The operation display name. + DisplayName *string + + // The dataAction flag to specify the operation type. + IsDataAction *bool + + // The operation name. + Name *string + + // The operation origin. + Origin *string + + // The operation properties. + Properties any +} + +// ProviderOperationsMetadata - Provider Operations metadata +type ProviderOperationsMetadata struct { + // The provider display name. + DisplayName *string + + // The provider id. + ID *string + + // The provider name. + Name *string + + // The provider operations. + Operations []*ProviderOperation + + // The provider resource types + ResourceTypes []*ResourceType + + // The provider type. + Type *string +} + +// ProviderOperationsMetadataListResult - Provider operations metadata list +type ProviderOperationsMetadataListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // The list of providers. + Value []*ProviderOperationsMetadata +} + +// ResourceType - Resource Type +type ResourceType struct { + // The resource type display name. + DisplayName *string + + // The resource type name. + Name *string + + // The resource type operations. + Operations []*ProviderOperation +} + +// RoleAssignment - Role Assignments +type RoleAssignment struct { + // Role assignment properties. + Properties *RoleAssignmentProperties + + // READ-ONLY; The role assignment ID. + ID *string + + // READ-ONLY; The role assignment name. + Name *string + + // READ-ONLY; The role assignment type. + Type *string +} + +// RoleAssignmentCreateParameters - Role assignment create parameters. +type RoleAssignmentCreateParameters struct { + // REQUIRED; Role assignment properties. + Properties *RoleAssignmentProperties +} + +// RoleAssignmentFilter - Role Assignments filter +type RoleAssignmentFilter struct { + // Returns role assignment of the specific principal. + PrincipalID *string +} + +// RoleAssignmentListResult - Role assignment list operation result. +type RoleAssignmentListResult struct { + // Role assignment list. + Value []*RoleAssignment + + // READ-ONLY; The skipToken to use for getting the next set of results. + NextLink *string +} + +// RoleAssignmentProperties - Role assignment properties. +type RoleAssignmentProperties struct { + // REQUIRED; The principal ID. + PrincipalID *string + + // REQUIRED; The role definition ID. + RoleDefinitionID *string + + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently the only accepted value is '2.0' + ConditionVersion *string + + // Id of the delegated managed identity resource + DelegatedManagedIdentityResourceID *string + + // Description of role assignment + Description *string + + // The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // READ-ONLY; Id of the user who created the assignment + CreatedBy *string + + // READ-ONLY; Time it was created + CreatedOn *time.Time + + // READ-ONLY; The role assignment scope. + Scope *string + + // READ-ONLY; Id of the user who updated the assignment + UpdatedBy *string + + // READ-ONLY; Time it was updated + UpdatedOn *time.Time +} + +// RoleAssignmentSchedule - Role Assignment schedule +type RoleAssignmentSchedule struct { + // Role assignment schedule properties. + Properties *RoleAssignmentScheduleProperties + + // READ-ONLY; The role assignment schedule Id. + ID *string + + // READ-ONLY; The role assignment schedule name. + Name *string + + // READ-ONLY; The role assignment schedule type. + Type *string +} + +// RoleAssignmentScheduleFilter - Role assignment schedule filter +type RoleAssignmentScheduleFilter struct { + // Returns role assignment schedule of the specific principal. + PrincipalID *string + + // Returns role assignment schedule of the specific role definition. + RoleDefinitionID *string + + // Returns role assignment schedule instances of the specific status. + Status *string +} + +// RoleAssignmentScheduleInstance - Information about current or upcoming role assignment schedule instance +type RoleAssignmentScheduleInstance struct { + // Role assignment schedule instance properties. + Properties *RoleAssignmentScheduleInstanceProperties + + // READ-ONLY; The role assignment schedule instance ID. + ID *string + + // READ-ONLY; The role assignment schedule instance name. + Name *string + + // READ-ONLY; The role assignment schedule instance type. + Type *string +} + +// RoleAssignmentScheduleInstanceFilter - Role assignment schedule instance filter +type RoleAssignmentScheduleInstanceFilter struct { + // Returns role assignment schedule instances of the specific principal. + PrincipalID *string + + // Returns role assignment schedule instances belonging to a specific role assignment schedule. + RoleAssignmentScheduleID *string + + // Returns role assignment schedule instances of the specific role definition. + RoleDefinitionID *string + + // Returns role assignment schedule instances of the specific status. + Status *string +} + +// RoleAssignmentScheduleInstanceListResult - Role assignment schedule instance list operation result. +type RoleAssignmentScheduleInstanceListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role assignment schedule instance list. + Value []*RoleAssignmentScheduleInstance +} + +// RoleAssignmentScheduleInstanceProperties - Role assignment schedule properties with scope. +type RoleAssignmentScheduleInstanceProperties struct { + // Assignment type of the role assignment schedule + AssignmentType *AssignmentType + + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently accepted value is '2.0' + ConditionVersion *string + + // DateTime when role assignment schedule was created + CreatedOn *time.Time + + // The endDateTime of the role assignment schedule instance + EndDateTime *time.Time + + // Additional properties of principal, scope and role definition + ExpandedProperties *ExpandedProperties + + // roleEligibilityScheduleId used to activate + LinkedRoleEligibilityScheduleID *string + + // roleEligibilityScheduleInstanceId linked to this roleAssignmentScheduleInstance + LinkedRoleEligibilityScheduleInstanceID *string + + // Membership type of the role assignment schedule + MemberType *MemberType + + // Role Assignment Id in external system + OriginRoleAssignmentID *string + + // The principal ID. + PrincipalID *string + + // The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // Id of the master role assignment schedule + RoleAssignmentScheduleID *string + + // The role definition ID. + RoleDefinitionID *string + + // The role assignment schedule scope. + Scope *string + + // The startDateTime of the role assignment schedule instance + StartDateTime *time.Time + + // The status of the role assignment schedule instance. + Status *Status +} + +// RoleAssignmentScheduleListResult - Role assignment schedule list operation result. +type RoleAssignmentScheduleListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role assignment schedule list. + Value []*RoleAssignmentSchedule +} + +// RoleAssignmentScheduleProperties - Role assignment schedule properties with scope. +type RoleAssignmentScheduleProperties struct { + // Assignment type of the role assignment schedule + AssignmentType *AssignmentType + + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently accepted value is '2.0' + ConditionVersion *string + + // DateTime when role assignment schedule was created + CreatedOn *time.Time + + // End DateTime when role assignment schedule + EndDateTime *time.Time + + // Additional properties of principal, scope and role definition + ExpandedProperties *ExpandedProperties + + // The id of roleEligibilitySchedule used to activated this roleAssignmentSchedule + LinkedRoleEligibilityScheduleID *string + + // Membership type of the role assignment schedule + MemberType *MemberType + + // The principal ID. + PrincipalID *string + + // The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // The id of roleAssignmentScheduleRequest used to create this roleAssignmentSchedule + RoleAssignmentScheduleRequestID *string + + // The role definition ID. + RoleDefinitionID *string + + // The role assignment schedule scope. + Scope *string + + // Start DateTime when role assignment schedule + StartDateTime *time.Time + + // The status of the role assignment schedule. + Status *Status + + // DateTime when role assignment schedule was modified + UpdatedOn *time.Time +} + +// RoleAssignmentScheduleRequest - Role Assignment schedule request +type RoleAssignmentScheduleRequest struct { + // Role assignment schedule request properties. + Properties *RoleAssignmentScheduleRequestProperties + + // READ-ONLY; The role assignment schedule request ID. + ID *string + + // READ-ONLY; The role assignment schedule request name. + Name *string + + // READ-ONLY; The role assignment schedule request type. + Type *string +} + +// RoleAssignmentScheduleRequestFilter - Role assignment schedule request filter +type RoleAssignmentScheduleRequestFilter struct { + // Returns role assignment requests of the specific principal. + PrincipalID *string + + // Returns role assignment requests created by specific principal. + RequestorID *string + + // Returns role assignment requests of the specific role definition. + RoleDefinitionID *string + + // Returns role assignment requests of specific status. + Status *string +} + +// RoleAssignmentScheduleRequestListResult - Role assignment schedule request list operation result. +type RoleAssignmentScheduleRequestListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role assignment schedule request list. + Value []*RoleAssignmentScheduleRequest +} + +// RoleAssignmentScheduleRequestProperties - Role assignment schedule request properties with scope. +type RoleAssignmentScheduleRequestProperties struct { + // REQUIRED; The principal ID. + PrincipalID *string + + // REQUIRED; The type of the role assignment schedule request. Eg: SelfActivate, AdminAssign etc + RequestType *RequestType + + // REQUIRED; The role definition ID. + RoleDefinitionID *string + + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently accepted value is '2.0' + ConditionVersion *string + + // Justification for the role assignment + Justification *string + + // The linked role eligibility schedule id - to activate an eligibility. + LinkedRoleEligibilityScheduleID *string + + // Schedule info of the role assignment schedule + ScheduleInfo *RoleAssignmentScheduleRequestPropertiesScheduleInfo + + // The resultant role assignment schedule id or the role assignment schedule id being updated + TargetRoleAssignmentScheduleID *string + + // The role assignment schedule instance id being updated + TargetRoleAssignmentScheduleInstanceID *string + + // Ticket Info of the role assignment + TicketInfo *RoleAssignmentScheduleRequestPropertiesTicketInfo + + // READ-ONLY; The approvalId of the role assignment schedule request. + ApprovalID *string + + // READ-ONLY; DateTime when role assignment schedule request was created + CreatedOn *time.Time + + // READ-ONLY; Additional properties of principal, scope and role definition + ExpandedProperties *ExpandedProperties + + // READ-ONLY; The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // READ-ONLY; Id of the user who created this request + RequestorID *string + + // READ-ONLY; The role assignment schedule request scope. + Scope *string + + // READ-ONLY; The status of the role assignment schedule request. + Status *Status +} + +// RoleAssignmentScheduleRequestPropertiesScheduleInfo - Schedule info of the role assignment schedule +type RoleAssignmentScheduleRequestPropertiesScheduleInfo struct { + // Expiration of the role assignment schedule + Expiration *RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration + + // Start DateTime of the role assignment schedule. + StartDateTime *time.Time +} + +// RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration - Expiration of the role assignment schedule +type RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration struct { + // Duration of the role assignment schedule in TimeSpan. + Duration *string + + // End DateTime of the role assignment schedule. + EndDateTime *time.Time + + // Type of the role assignment schedule expiration + Type *Type +} + +// RoleAssignmentScheduleRequestPropertiesTicketInfo - Ticket Info of the role assignment +type RoleAssignmentScheduleRequestPropertiesTicketInfo struct { + // Ticket number for the role assignment + TicketNumber *string + + // Ticket system name for the role assignment + TicketSystem *string +} + +// RoleDefinition - Role definition. +type RoleDefinition struct { + // Role definition properties. + Properties *RoleDefinitionProperties + + // READ-ONLY; The role definition ID. + ID *string + + // READ-ONLY; The role definition name. + Name *string + + // READ-ONLY; The role definition type. + Type *string +} + +// RoleDefinitionFilter - Role Definitions filter +type RoleDefinitionFilter struct { + // Returns role definition with the specific name. + RoleName *string + + // Returns role definition with the specific type. + Type *string +} + +// RoleDefinitionListResult - Role definition list operation result. +type RoleDefinitionListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role definition list. + Value []*RoleDefinition +} + +// RoleDefinitionProperties - Role definition properties. +type RoleDefinitionProperties struct { + // Role definition assignable scopes. + AssignableScopes []*string + + // The role definition description. + Description *string + + // Role definition permissions. + Permissions []*Permission + + // The role name. + RoleName *string + + // The role type. + RoleType *string +} + +// RoleEligibilitySchedule - Role eligibility schedule +type RoleEligibilitySchedule struct { + // role eligibility schedule properties. + Properties *RoleEligibilityScheduleProperties + + // READ-ONLY; The role eligibility schedule Id. + ID *string + + // READ-ONLY; The role eligibility schedule name. + Name *string + + // READ-ONLY; The role eligibility schedule type. + Type *string +} + +// RoleEligibilityScheduleFilter - Role eligibility schedule filter +type RoleEligibilityScheduleFilter struct { + // Returns role eligibility schedule of the specific principal. + PrincipalID *string + + // Returns role eligibility schedule of the specific role definition. + RoleDefinitionID *string + + // Returns role eligibility schedule of the specific status. + Status *string +} + +// RoleEligibilityScheduleInstance - Information about current or upcoming role eligibility schedule instance +type RoleEligibilityScheduleInstance struct { + // Role eligibility schedule instance properties. + Properties *RoleEligibilityScheduleInstanceProperties + + // READ-ONLY; The role eligibility schedule instance ID. + ID *string + + // READ-ONLY; The role eligibility schedule instance name. + Name *string + + // READ-ONLY; The role eligibility schedule instance type. + Type *string +} + +// RoleEligibilityScheduleInstanceFilter - Role eligibility schedule instance filter +type RoleEligibilityScheduleInstanceFilter struct { + // Returns role eligibility schedule instances of the specific principal. + PrincipalID *string + + // Returns role eligibility schedule instances of the specific role definition. + RoleDefinitionID *string + + // Returns role eligibility schedule instances belonging to a specific role eligibility schedule. + RoleEligibilityScheduleID *string + + // Returns role eligibility schedule instances of the specific status. + Status *string +} + +// RoleEligibilityScheduleInstanceListResult - Role eligibility schedule instance list operation result. +type RoleEligibilityScheduleInstanceListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role eligibility schedule instance list. + Value []*RoleEligibilityScheduleInstance +} + +// RoleEligibilityScheduleInstanceProperties - Role eligibility schedule properties with scope. +type RoleEligibilityScheduleInstanceProperties struct { + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently accepted value is '2.0' + ConditionVersion *string + + // DateTime when role eligibility schedule was created + CreatedOn *time.Time + + // The endDateTime of the role eligibility schedule instance + EndDateTime *time.Time + + // Additional properties of principal, scope and role definition + ExpandedProperties *ExpandedProperties + + // Membership type of the role eligibility schedule + MemberType *MemberType + + // The principal ID. + PrincipalID *string + + // The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // The role definition ID. + RoleDefinitionID *string + + // Id of the master role eligibility schedule + RoleEligibilityScheduleID *string + + // The role eligibility schedule scope. + Scope *string + + // The startDateTime of the role eligibility schedule instance + StartDateTime *time.Time + + // The status of the role eligibility schedule instance + Status *Status +} + +// RoleEligibilityScheduleListResult - role eligibility schedule list operation result. +type RoleEligibilityScheduleListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // role eligibility schedule list. + Value []*RoleEligibilitySchedule +} + +// RoleEligibilityScheduleProperties - Role eligibility schedule properties with scope. +type RoleEligibilityScheduleProperties struct { + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently accepted value is '2.0' + ConditionVersion *string + + // DateTime when role eligibility schedule was created + CreatedOn *time.Time + + // End DateTime when role eligibility schedule + EndDateTime *time.Time + + // Additional properties of principal, scope and role definition + ExpandedProperties *ExpandedProperties + + // Membership type of the role eligibility schedule + MemberType *MemberType + + // The principal ID. + PrincipalID *string + + // The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // The role definition ID. + RoleDefinitionID *string + + // The id of roleEligibilityScheduleRequest used to create this roleAssignmentSchedule + RoleEligibilityScheduleRequestID *string + + // The role eligibility schedule scope. + Scope *string + + // Start DateTime when role eligibility schedule + StartDateTime *time.Time + + // The status of the role eligibility schedule. + Status *Status + + // DateTime when role eligibility schedule was modified + UpdatedOn *time.Time +} + +// RoleEligibilityScheduleRequest - Role Eligibility schedule request +type RoleEligibilityScheduleRequest struct { + // Role eligibility schedule request properties. + Properties *RoleEligibilityScheduleRequestProperties + + // READ-ONLY; The role eligibility schedule request ID. + ID *string + + // READ-ONLY; The role eligibility schedule request name. + Name *string + + // READ-ONLY; The role eligibility schedule request type. + Type *string +} + +// RoleEligibilityScheduleRequestFilter - Role eligibility schedule request filter +type RoleEligibilityScheduleRequestFilter struct { + // Returns role eligibility requests of the specific principal. + PrincipalID *string + + // Returns role eligibility requests created by specific principal. + RequestorID *string + + // Returns role eligibility requests of the specific role definition. + RoleDefinitionID *string + + // Returns role eligibility requests of specific status. + Status *string +} + +// RoleEligibilityScheduleRequestListResult - Role eligibility schedule request list operation result. +type RoleEligibilityScheduleRequestListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role eligibility schedule request list. + Value []*RoleEligibilityScheduleRequest +} + +// RoleEligibilityScheduleRequestProperties - Role eligibility schedule request properties with scope. +type RoleEligibilityScheduleRequestProperties struct { + // REQUIRED; The principal ID. + PrincipalID *string + + // REQUIRED; The type of the role assignment schedule request. Eg: SelfActivate, AdminAssign etc + RequestType *RequestType + + // REQUIRED; The role definition ID. + RoleDefinitionID *string + + // The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] + // StringEqualsIgnoreCase + // 'foostoragecontainer' + Condition *string + + // Version of the condition. Currently accepted value is '2.0' + ConditionVersion *string + + // Justification for the role eligibility + Justification *string + + // Schedule info of the role eligibility schedule + ScheduleInfo *RoleEligibilityScheduleRequestPropertiesScheduleInfo + + // The resultant role eligibility schedule id or the role eligibility schedule id being updated + TargetRoleEligibilityScheduleID *string + + // The role eligibility schedule instance id being updated + TargetRoleEligibilityScheduleInstanceID *string + + // Ticket Info of the role eligibility + TicketInfo *RoleEligibilityScheduleRequestPropertiesTicketInfo + + // READ-ONLY; The approvalId of the role eligibility schedule request. + ApprovalID *string + + // READ-ONLY; DateTime when role eligibility schedule request was created + CreatedOn *time.Time + + // READ-ONLY; Additional properties of principal, scope and role definition + ExpandedProperties *ExpandedProperties + + // READ-ONLY; The principal type of the assigned principal ID. + PrincipalType *PrincipalType + + // READ-ONLY; Id of the user who created this request + RequestorID *string + + // READ-ONLY; The role eligibility schedule request scope. + Scope *string + + // READ-ONLY; The status of the role eligibility schedule request. + Status *Status +} + +// RoleEligibilityScheduleRequestPropertiesScheduleInfo - Schedule info of the role eligibility schedule +type RoleEligibilityScheduleRequestPropertiesScheduleInfo struct { + // Expiration of the role eligibility schedule + Expiration *RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration + + // Start DateTime of the role eligibility schedule. + StartDateTime *time.Time +} + +// RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration - Expiration of the role eligibility schedule +type RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration struct { + // Duration of the role eligibility schedule in TimeSpan. + Duration *string + + // End DateTime of the role eligibility schedule. + EndDateTime *time.Time + + // Type of the role eligibility schedule expiration + Type *Type +} + +// RoleEligibilityScheduleRequestPropertiesTicketInfo - Ticket Info of the role eligibility +type RoleEligibilityScheduleRequestPropertiesTicketInfo struct { + // Ticket number for the role eligibility + TicketNumber *string + + // Ticket system name for the role eligibility + TicketSystem *string +} + +// RoleManagementPolicy - Role management policy +type RoleManagementPolicy struct { + // Role management policy properties. + Properties *RoleManagementPolicyProperties + + // READ-ONLY; The role management policy Id. + ID *string + + // READ-ONLY; The role management policy name. + Name *string + + // READ-ONLY; The role management policy type. + Type *string +} + +// RoleManagementPolicyApprovalRule - The role management policy approval rule. +type RoleManagementPolicyApprovalRule struct { + // REQUIRED; The type of rule + RuleType *RoleManagementPolicyRuleType + + // The id of the rule. + ID *string + + // The approval setting + Setting *ApprovalSettings + + // The target of the current rule. + Target *RoleManagementPolicyRuleTarget +} + +// GetRoleManagementPolicyRule implements the RoleManagementPolicyRuleClassification interface for type RoleManagementPolicyApprovalRule. +func (r *RoleManagementPolicyApprovalRule) GetRoleManagementPolicyRule() *RoleManagementPolicyRule { + return &RoleManagementPolicyRule{ + ID: r.ID, + RuleType: r.RuleType, + Target: r.Target, + } +} + +// RoleManagementPolicyAssignment - Role management policy +type RoleManagementPolicyAssignment struct { + // Role management policy properties. + Properties *RoleManagementPolicyAssignmentProperties + + // READ-ONLY; The role management policy Id. + ID *string + + // READ-ONLY; The role management policy name. + Name *string + + // READ-ONLY; The role management policy type. + Type *string +} + +// RoleManagementPolicyAssignmentListResult - Role management policy assignment list operation result. +type RoleManagementPolicyAssignmentListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role management policy assignment list. + Value []*RoleManagementPolicyAssignment +} + +// RoleManagementPolicyAssignmentProperties - Role management policy assignment properties with scope. +type RoleManagementPolicyAssignmentProperties struct { + // The policy id role management policy assignment. + PolicyID *string + + // The role definition of management policy assignment. + RoleDefinitionID *string + + // The role management policy scope. + Scope *string + + // READ-ONLY; The readonly computed rule applied to the policy. + EffectiveRules []RoleManagementPolicyRuleClassification + + // READ-ONLY; Additional properties of scope, role definition and policy + PolicyAssignmentProperties *PolicyAssignmentProperties +} + +// RoleManagementPolicyAuthenticationContextRule - The role management policy authentication context rule. +type RoleManagementPolicyAuthenticationContextRule struct { + // REQUIRED; The type of rule + RuleType *RoleManagementPolicyRuleType + + // The claim value. + ClaimValue *string + + // The id of the rule. + ID *string + + // The value indicating if rule is enabled. + IsEnabled *bool + + // The target of the current rule. + Target *RoleManagementPolicyRuleTarget +} + +// GetRoleManagementPolicyRule implements the RoleManagementPolicyRuleClassification interface for type RoleManagementPolicyAuthenticationContextRule. +func (r *RoleManagementPolicyAuthenticationContextRule) GetRoleManagementPolicyRule() *RoleManagementPolicyRule { + return &RoleManagementPolicyRule{ + ID: r.ID, + RuleType: r.RuleType, + Target: r.Target, + } +} + +// RoleManagementPolicyEnablementRule - The role management policy enablement rule. +type RoleManagementPolicyEnablementRule struct { + // REQUIRED; The type of rule + RuleType *RoleManagementPolicyRuleType + + // The list of enabled rules. + EnabledRules []*EnablementRules + + // The id of the rule. + ID *string + + // The target of the current rule. + Target *RoleManagementPolicyRuleTarget +} + +// GetRoleManagementPolicyRule implements the RoleManagementPolicyRuleClassification interface for type RoleManagementPolicyEnablementRule. +func (r *RoleManagementPolicyEnablementRule) GetRoleManagementPolicyRule() *RoleManagementPolicyRule { + return &RoleManagementPolicyRule{ + ID: r.ID, + RuleType: r.RuleType, + Target: r.Target, + } +} + +// RoleManagementPolicyExpirationRule - The role management policy expiration rule. +type RoleManagementPolicyExpirationRule struct { + // REQUIRED; The type of rule + RuleType *RoleManagementPolicyRuleType + + // The id of the rule. + ID *string + + // The value indicating whether expiration is required. + IsExpirationRequired *bool + + // The maximum duration of expiration in timespan. + MaximumDuration *string + + // The target of the current rule. + Target *RoleManagementPolicyRuleTarget +} + +// GetRoleManagementPolicyRule implements the RoleManagementPolicyRuleClassification interface for type RoleManagementPolicyExpirationRule. +func (r *RoleManagementPolicyExpirationRule) GetRoleManagementPolicyRule() *RoleManagementPolicyRule { + return &RoleManagementPolicyRule{ + ID: r.ID, + RuleType: r.RuleType, + Target: r.Target, + } +} + +// RoleManagementPolicyListResult - Role management policy list operation result. +type RoleManagementPolicyListResult struct { + // The URL to use for getting the next set of results. + NextLink *string + + // Role management policy list. + Value []*RoleManagementPolicy +} + +// RoleManagementPolicyNotificationRule - The role management policy notification rule. +type RoleManagementPolicyNotificationRule struct { + // REQUIRED; The type of rule + RuleType *RoleManagementPolicyRuleType + + // The id of the rule. + ID *string + + // Determines if the notification will be sent to the recipient type specified in the policy rule. + IsDefaultRecipientsEnabled *bool + + // The notification level. + NotificationLevel *NotificationLevel + + // The list of notification recipients. + NotificationRecipients []*string + + // The type of notification. + NotificationType *NotificationDeliveryMechanism + + // The recipient type. + RecipientType *RecipientType + + // The target of the current rule. + Target *RoleManagementPolicyRuleTarget +} + +// GetRoleManagementPolicyRule implements the RoleManagementPolicyRuleClassification interface for type RoleManagementPolicyNotificationRule. +func (r *RoleManagementPolicyNotificationRule) GetRoleManagementPolicyRule() *RoleManagementPolicyRule { + return &RoleManagementPolicyRule{ + ID: r.ID, + RuleType: r.RuleType, + Target: r.Target, + } +} + +// RoleManagementPolicyProperties - Role management policy properties with scope. +type RoleManagementPolicyProperties struct { + // The role management policy description. + Description *string + + // The role management policy display name. + DisplayName *string + + // The role management policy is default policy. + IsOrganizationDefault *bool + + // The rule applied to the policy. + Rules []RoleManagementPolicyRuleClassification + + // The role management policy scope. + Scope *string + + // READ-ONLY; The readonly computed rule applied to the policy. + EffectiveRules []RoleManagementPolicyRuleClassification + + // READ-ONLY; The name of the entity last modified it + LastModifiedBy *Principal + + // READ-ONLY; The last modified date time. + LastModifiedDateTime *time.Time + + // READ-ONLY; Additional properties of scope + PolicyProperties *PolicyProperties +} + +// RoleManagementPolicyRule - The role management policy rule. +type RoleManagementPolicyRule struct { + // REQUIRED; The type of rule + RuleType *RoleManagementPolicyRuleType + + // The id of the rule. + ID *string + + // The target of the current rule. + Target *RoleManagementPolicyRuleTarget +} + +// GetRoleManagementPolicyRule implements the RoleManagementPolicyRuleClassification interface for type RoleManagementPolicyRule. +func (r *RoleManagementPolicyRule) GetRoleManagementPolicyRule() *RoleManagementPolicyRule { return r } + +// RoleManagementPolicyRuleTarget - The role management policy rule target. +type RoleManagementPolicyRuleTarget struct { + // The caller of the setting. + Caller *string + + // The list of enforced settings. + EnforcedSettings []*string + + // The list of inheritable settings. + InheritableSettings []*string + + // The assignment level to which rule is applied. + Level *string + + // The type of operation. + Operations []*string + + // The list of target objects. + TargetObjects []*string +} + +// UserSet - The detail of a user. +type UserSet struct { + // The description of the user. + Description *string + + // The object id of the user. + ID *string + + // The value indicating whether the user is a backup fallback approver + IsBackup *bool + + // The type of user. + UserType *UserType +} + +// ValidationResponse - Validation response +type ValidationResponse struct { + // Failed validation result details + ErrorInfo *ValidationResponseErrorInfo + + // READ-ONLY; Whether or not validation succeeded + IsValid *bool +} + +// ValidationResponseErrorInfo - Failed validation result details +type ValidationResponseErrorInfo struct { + // READ-ONLY; Error code indicating why validation failed + Code *string + + // READ-ONLY; Message indicating why validation failed + Message *string +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/models_serde.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/models_serde.go new file mode 100644 index 000000000..c34ca4bc5 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/models_serde.go @@ -0,0 +1,3567 @@ +//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 armauthorization + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" +) + +// MarshalJSON implements the json.Marshaller interface for type ApprovalSettings. +func (a ApprovalSettings) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "approvalMode", a.ApprovalMode) + populate(objectMap, "approvalStages", a.ApprovalStages) + populate(objectMap, "isApprovalRequired", a.IsApprovalRequired) + populate(objectMap, "isApprovalRequiredForExtension", a.IsApprovalRequiredForExtension) + populate(objectMap, "isRequestorJustificationRequired", a.IsRequestorJustificationRequired) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ApprovalSettings. +func (a *ApprovalSettings) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "approvalMode": + err = unpopulate(val, "ApprovalMode", &a.ApprovalMode) + delete(rawMsg, key) + case "approvalStages": + err = unpopulate(val, "ApprovalStages", &a.ApprovalStages) + delete(rawMsg, key) + case "isApprovalRequired": + err = unpopulate(val, "IsApprovalRequired", &a.IsApprovalRequired) + delete(rawMsg, key) + case "isApprovalRequiredForExtension": + err = unpopulate(val, "IsApprovalRequiredForExtension", &a.IsApprovalRequiredForExtension) + delete(rawMsg, key) + case "isRequestorJustificationRequired": + err = unpopulate(val, "IsRequestorJustificationRequired", &a.IsRequestorJustificationRequired) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ApprovalStage. +func (a ApprovalStage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "approvalStageTimeOutInDays", a.ApprovalStageTimeOutInDays) + populate(objectMap, "escalationApprovers", a.EscalationApprovers) + populate(objectMap, "escalationTimeInMinutes", a.EscalationTimeInMinutes) + populate(objectMap, "isApproverJustificationRequired", a.IsApproverJustificationRequired) + populate(objectMap, "isEscalationEnabled", a.IsEscalationEnabled) + populate(objectMap, "primaryApprovers", a.PrimaryApprovers) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ApprovalStage. +func (a *ApprovalStage) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "approvalStageTimeOutInDays": + err = unpopulate(val, "ApprovalStageTimeOutInDays", &a.ApprovalStageTimeOutInDays) + delete(rawMsg, key) + case "escalationApprovers": + err = unpopulate(val, "EscalationApprovers", &a.EscalationApprovers) + delete(rawMsg, key) + case "escalationTimeInMinutes": + err = unpopulate(val, "EscalationTimeInMinutes", &a.EscalationTimeInMinutes) + delete(rawMsg, key) + case "isApproverJustificationRequired": + err = unpopulate(val, "IsApproverJustificationRequired", &a.IsApproverJustificationRequired) + delete(rawMsg, key) + case "isEscalationEnabled": + err = unpopulate(val, "IsEscalationEnabled", &a.IsEscalationEnabled) + delete(rawMsg, key) + case "primaryApprovers": + err = unpopulate(val, "PrimaryApprovers", &a.PrimaryApprovers) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ClassicAdministrator. +func (c ClassicAdministrator) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", c.ID) + populate(objectMap, "name", c.Name) + populate(objectMap, "properties", c.Properties) + populate(objectMap, "type", c.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ClassicAdministrator. +func (c *ClassicAdministrator) 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", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &c.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &c.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &c.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &c.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ClassicAdministratorListResult. +func (c ClassicAdministratorListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", c.NextLink) + populate(objectMap, "value", c.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ClassicAdministratorListResult. +func (c *ClassicAdministratorListResult) 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", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &c.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &c.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ClassicAdministratorProperties. +func (c ClassicAdministratorProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "emailAddress", c.EmailAddress) + populate(objectMap, "role", c.Role) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ClassicAdministratorProperties. +func (c *ClassicAdministratorProperties) 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", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "emailAddress": + err = unpopulate(val, "EmailAddress", &c.EmailAddress) + delete(rawMsg, key) + case "role": + err = unpopulate(val, "Role", &c.Role) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type DenyAssignment. +func (d DenyAssignment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", d.ID) + populate(objectMap, "name", d.Name) + populate(objectMap, "properties", d.Properties) + populate(objectMap, "type", d.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DenyAssignment. +func (d *DenyAssignment) 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 "id": + err = unpopulate(val, "ID", &d.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &d.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &d.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &d.Type) + 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 DenyAssignmentFilter. +func (d DenyAssignmentFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "denyAssignmentName", d.DenyAssignmentName) + populate(objectMap, "gdprExportPrincipalId", d.GdprExportPrincipalID) + populate(objectMap, "principalId", d.PrincipalID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DenyAssignmentFilter. +func (d *DenyAssignmentFilter) 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 "denyAssignmentName": + err = unpopulate(val, "DenyAssignmentName", &d.DenyAssignmentName) + delete(rawMsg, key) + case "gdprExportPrincipalId": + err = unpopulate(val, "GdprExportPrincipalID", &d.GdprExportPrincipalID) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &d.PrincipalID) + 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 DenyAssignmentListResult. +func (d DenyAssignmentListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", d.NextLink) + populate(objectMap, "value", d.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DenyAssignmentListResult. +func (d *DenyAssignmentListResult) 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 "nextLink": + err = unpopulate(val, "NextLink", &d.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &d.Value) + 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 DenyAssignmentPermission. +func (d DenyAssignmentPermission) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "actions", d.Actions) + populate(objectMap, "condition", d.Condition) + populate(objectMap, "conditionVersion", d.ConditionVersion) + populate(objectMap, "dataActions", d.DataActions) + populate(objectMap, "notActions", d.NotActions) + populate(objectMap, "notDataActions", d.NotDataActions) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DenyAssignmentPermission. +func (d *DenyAssignmentPermission) 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 "actions": + err = unpopulate(val, "Actions", &d.Actions) + delete(rawMsg, key) + case "condition": + err = unpopulate(val, "Condition", &d.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &d.ConditionVersion) + delete(rawMsg, key) + case "dataActions": + err = unpopulate(val, "DataActions", &d.DataActions) + delete(rawMsg, key) + case "notActions": + err = unpopulate(val, "NotActions", &d.NotActions) + delete(rawMsg, key) + case "notDataActions": + err = unpopulate(val, "NotDataActions", &d.NotDataActions) + 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 DenyAssignmentProperties. +func (d DenyAssignmentProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "denyAssignmentName", d.DenyAssignmentName) + populate(objectMap, "description", d.Description) + populate(objectMap, "doNotApplyToChildScopes", d.DoNotApplyToChildScopes) + populate(objectMap, "excludePrincipals", d.ExcludePrincipals) + populate(objectMap, "isSystemProtected", d.IsSystemProtected) + populate(objectMap, "permissions", d.Permissions) + populate(objectMap, "principals", d.Principals) + populate(objectMap, "scope", d.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DenyAssignmentProperties. +func (d *DenyAssignmentProperties) 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 "denyAssignmentName": + err = unpopulate(val, "DenyAssignmentName", &d.DenyAssignmentName) + delete(rawMsg, key) + case "description": + err = unpopulate(val, "Description", &d.Description) + delete(rawMsg, key) + case "doNotApplyToChildScopes": + err = unpopulate(val, "DoNotApplyToChildScopes", &d.DoNotApplyToChildScopes) + delete(rawMsg, key) + case "excludePrincipals": + err = unpopulate(val, "ExcludePrincipals", &d.ExcludePrincipals) + delete(rawMsg, key) + case "isSystemProtected": + err = unpopulate(val, "IsSystemProtected", &d.IsSystemProtected) + delete(rawMsg, key) + case "permissions": + err = unpopulate(val, "Permissions", &d.Permissions) + delete(rawMsg, key) + case "principals": + err = unpopulate(val, "Principals", &d.Principals) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &d.Scope) + 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 EligibleChildResource. +func (e EligibleChildResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", e.ID) + populate(objectMap, "name", e.Name) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type EligibleChildResource. +func (e *EligibleChildResource) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &e.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &e.Name) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type EligibleChildResourcesListResult. +func (e EligibleChildResourcesListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", e.NextLink) + populate(objectMap, "value", e.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type EligibleChildResourcesListResult. +func (e *EligibleChildResourcesListResult) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &e.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &e.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ErrorAdditionalInfo. +func (e ErrorAdditionalInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "info", e.Info) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorAdditionalInfo. +func (e *ErrorAdditionalInfo) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "info": + err = unpopulate(val, "Info", &e.Info) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ErrorDetail. +func (e ErrorDetail) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "additionalInfo", e.AdditionalInfo) + populate(objectMap, "code", e.Code) + populate(objectMap, "details", e.Details) + populate(objectMap, "message", e.Message) + populate(objectMap, "target", e.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorDetail. +func (e *ErrorDetail) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "additionalInfo": + err = unpopulate(val, "AdditionalInfo", &e.AdditionalInfo) + delete(rawMsg, key) + case "code": + err = unpopulate(val, "Code", &e.Code) + delete(rawMsg, key) + case "details": + err = unpopulate(val, "Details", &e.Details) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &e.Message) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &e.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ErrorResponse. +func (e ErrorResponse) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", e.Error) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponse. +func (e *ErrorResponse) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &e.Error) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExpandedProperties. +func (e ExpandedProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principal", e.Principal) + populate(objectMap, "roleDefinition", e.RoleDefinition) + populate(objectMap, "scope", e.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExpandedProperties. +func (e *ExpandedProperties) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principal": + err = unpopulate(val, "Principal", &e.Principal) + delete(rawMsg, key) + case "roleDefinition": + err = unpopulate(val, "RoleDefinition", &e.RoleDefinition) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &e.Scope) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExpandedPropertiesPrincipal. +func (e ExpandedPropertiesPrincipal) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", e.DisplayName) + populate(objectMap, "email", e.Email) + populate(objectMap, "id", e.ID) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExpandedPropertiesPrincipal. +func (e *ExpandedPropertiesPrincipal) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &e.DisplayName) + delete(rawMsg, key) + case "email": + err = unpopulate(val, "Email", &e.Email) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &e.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExpandedPropertiesRoleDefinition. +func (e ExpandedPropertiesRoleDefinition) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", e.DisplayName) + populate(objectMap, "id", e.ID) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExpandedPropertiesRoleDefinition. +func (e *ExpandedPropertiesRoleDefinition) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &e.DisplayName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &e.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExpandedPropertiesScope. +func (e ExpandedPropertiesScope) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", e.DisplayName) + populate(objectMap, "id", e.ID) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExpandedPropertiesScope. +func (e *ExpandedPropertiesScope) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &e.DisplayName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &e.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Permission. +func (p Permission) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "actions", p.Actions) + populate(objectMap, "dataActions", p.DataActions) + populate(objectMap, "notActions", p.NotActions) + populate(objectMap, "notDataActions", p.NotDataActions) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Permission. +func (p *Permission) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "actions": + err = unpopulate(val, "Actions", &p.Actions) + delete(rawMsg, key) + case "dataActions": + err = unpopulate(val, "DataActions", &p.DataActions) + delete(rawMsg, key) + case "notActions": + err = unpopulate(val, "NotActions", &p.NotActions) + delete(rawMsg, key) + case "notDataActions": + err = unpopulate(val, "NotDataActions", &p.NotDataActions) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PermissionGetResult. +func (p PermissionGetResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", p.NextLink) + populate(objectMap, "value", p.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PermissionGetResult. +func (p *PermissionGetResult) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &p.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &p.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PolicyAssignmentProperties. +func (p PolicyAssignmentProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "policy", p.Policy) + populate(objectMap, "roleDefinition", p.RoleDefinition) + populate(objectMap, "scope", p.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PolicyAssignmentProperties. +func (p *PolicyAssignmentProperties) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "policy": + err = unpopulate(val, "Policy", &p.Policy) + delete(rawMsg, key) + case "roleDefinition": + err = unpopulate(val, "RoleDefinition", &p.RoleDefinition) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &p.Scope) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PolicyAssignmentPropertiesPolicy. +func (p PolicyAssignmentPropertiesPolicy) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", p.ID) + populate(objectMap, "lastModifiedBy", p.LastModifiedBy) + populateDateTimeRFC3339(objectMap, "lastModifiedDateTime", p.LastModifiedDateTime) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PolicyAssignmentPropertiesPolicy. +func (p *PolicyAssignmentPropertiesPolicy) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "lastModifiedBy": + err = unpopulate(val, "LastModifiedBy", &p.LastModifiedBy) + delete(rawMsg, key) + case "lastModifiedDateTime": + err = unpopulateDateTimeRFC3339(val, "LastModifiedDateTime", &p.LastModifiedDateTime) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PolicyAssignmentPropertiesRoleDefinition. +func (p PolicyAssignmentPropertiesRoleDefinition) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", p.DisplayName) + populate(objectMap, "id", p.ID) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PolicyAssignmentPropertiesRoleDefinition. +func (p *PolicyAssignmentPropertiesRoleDefinition) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &p.DisplayName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PolicyAssignmentPropertiesScope. +func (p PolicyAssignmentPropertiesScope) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", p.DisplayName) + populate(objectMap, "id", p.ID) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PolicyAssignmentPropertiesScope. +func (p *PolicyAssignmentPropertiesScope) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &p.DisplayName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PolicyProperties. +func (p PolicyProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "scope", p.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PolicyProperties. +func (p *PolicyProperties) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "scope": + err = unpopulate(val, "Scope", &p.Scope) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type PolicyPropertiesScope. +func (p PolicyPropertiesScope) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", p.DisplayName) + populate(objectMap, "id", p.ID) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type PolicyPropertiesScope. +func (p *PolicyPropertiesScope) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &p.DisplayName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Principal. +func (p Principal) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", p.DisplayName) + populate(objectMap, "email", p.Email) + populate(objectMap, "id", p.ID) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Principal. +func (p *Principal) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &p.DisplayName) + delete(rawMsg, key) + case "email": + err = unpopulate(val, "Email", &p.Email) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderOperation. +func (p ProviderOperation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", p.Description) + populate(objectMap, "displayName", p.DisplayName) + populate(objectMap, "isDataAction", p.IsDataAction) + populate(objectMap, "name", p.Name) + populate(objectMap, "origin", p.Origin) + populateAny(objectMap, "properties", p.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderOperation. +func (p *ProviderOperation) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &p.Description) + delete(rawMsg, key) + case "displayName": + err = unpopulate(val, "DisplayName", &p.DisplayName) + delete(rawMsg, key) + case "isDataAction": + err = unpopulate(val, "IsDataAction", &p.IsDataAction) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &p.Name) + delete(rawMsg, key) + case "origin": + err = unpopulate(val, "Origin", &p.Origin) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &p.Properties) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderOperationsMetadata. +func (p ProviderOperationsMetadata) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", p.DisplayName) + populate(objectMap, "id", p.ID) + populate(objectMap, "name", p.Name) + populate(objectMap, "operations", p.Operations) + populate(objectMap, "resourceTypes", p.ResourceTypes) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderOperationsMetadata. +func (p *ProviderOperationsMetadata) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &p.DisplayName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &p.Name) + delete(rawMsg, key) + case "operations": + err = unpopulate(val, "Operations", &p.Operations) + delete(rawMsg, key) + case "resourceTypes": + err = unpopulate(val, "ResourceTypes", &p.ResourceTypes) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderOperationsMetadataListResult. +func (p ProviderOperationsMetadataListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", p.NextLink) + populate(objectMap, "value", p.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderOperationsMetadataListResult. +func (p *ProviderOperationsMetadataListResult) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &p.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &p.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceType. +func (r ResourceType) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "displayName", r.DisplayName) + populate(objectMap, "name", r.Name) + populate(objectMap, "operations", r.Operations) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceType. +func (r *ResourceType) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "displayName": + err = unpopulate(val, "DisplayName", &r.DisplayName) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "operations": + err = unpopulate(val, "Operations", &r.Operations) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignment. +func (r RoleAssignment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignment. +func (r *RoleAssignment) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentCreateParameters. +func (r RoleAssignmentCreateParameters) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "properties", r.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentCreateParameters. +func (r *RoleAssignmentCreateParameters) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentFilter. +func (r RoleAssignmentFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentFilter. +func (r *RoleAssignmentFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentListResult. +func (r RoleAssignmentListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentListResult. +func (r *RoleAssignmentListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentProperties. +func (r RoleAssignmentProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populate(objectMap, "createdBy", r.CreatedBy) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populate(objectMap, "delegatedManagedIdentityResourceId", r.DelegatedManagedIdentityResourceID) + populate(objectMap, "description", r.Description) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "scope", r.Scope) + populate(objectMap, "updatedBy", r.UpdatedBy) + populateDateTimeRFC3339(objectMap, "updatedOn", r.UpdatedOn) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentProperties. +func (r *RoleAssignmentProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdBy": + err = unpopulate(val, "CreatedBy", &r.CreatedBy) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "delegatedManagedIdentityResourceId": + err = unpopulate(val, "DelegatedManagedIdentityResourceID", &r.DelegatedManagedIdentityResourceID) + delete(rawMsg, key) + case "description": + err = unpopulate(val, "Description", &r.Description) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "updatedBy": + err = unpopulate(val, "UpdatedBy", &r.UpdatedBy) + delete(rawMsg, key) + case "updatedOn": + err = unpopulateDateTimeRFC3339(val, "UpdatedOn", &r.UpdatedOn) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentSchedule. +func (r RoleAssignmentSchedule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentSchedule. +func (r *RoleAssignmentSchedule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleFilter. +func (r RoleAssignmentScheduleFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleFilter. +func (r *RoleAssignmentScheduleFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleInstance. +func (r RoleAssignmentScheduleInstance) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleInstance. +func (r *RoleAssignmentScheduleInstance) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleInstanceFilter. +func (r RoleAssignmentScheduleInstanceFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "roleAssignmentScheduleId", r.RoleAssignmentScheduleID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleInstanceFilter. +func (r *RoleAssignmentScheduleInstanceFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "roleAssignmentScheduleId": + err = unpopulate(val, "RoleAssignmentScheduleID", &r.RoleAssignmentScheduleID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleInstanceListResult. +func (r RoleAssignmentScheduleInstanceListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleInstanceListResult. +func (r *RoleAssignmentScheduleInstanceListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleInstanceProperties. +func (r RoleAssignmentScheduleInstanceProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "assignmentType", r.AssignmentType) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populateDateTimeRFC3339(objectMap, "endDateTime", r.EndDateTime) + populate(objectMap, "expandedProperties", r.ExpandedProperties) + populate(objectMap, "linkedRoleEligibilityScheduleId", r.LinkedRoleEligibilityScheduleID) + populate(objectMap, "linkedRoleEligibilityScheduleInstanceId", r.LinkedRoleEligibilityScheduleInstanceID) + populate(objectMap, "memberType", r.MemberType) + populate(objectMap, "originRoleAssignmentId", r.OriginRoleAssignmentID) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "roleAssignmentScheduleId", r.RoleAssignmentScheduleID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "scope", r.Scope) + populateDateTimeRFC3339(objectMap, "startDateTime", r.StartDateTime) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleInstanceProperties. +func (r *RoleAssignmentScheduleInstanceProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "assignmentType": + err = unpopulate(val, "AssignmentType", &r.AssignmentType) + delete(rawMsg, key) + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "endDateTime": + err = unpopulateDateTimeRFC3339(val, "EndDateTime", &r.EndDateTime) + delete(rawMsg, key) + case "expandedProperties": + err = unpopulate(val, "ExpandedProperties", &r.ExpandedProperties) + delete(rawMsg, key) + case "linkedRoleEligibilityScheduleId": + err = unpopulate(val, "LinkedRoleEligibilityScheduleID", &r.LinkedRoleEligibilityScheduleID) + delete(rawMsg, key) + case "linkedRoleEligibilityScheduleInstanceId": + err = unpopulate(val, "LinkedRoleEligibilityScheduleInstanceID", &r.LinkedRoleEligibilityScheduleInstanceID) + delete(rawMsg, key) + case "memberType": + err = unpopulate(val, "MemberType", &r.MemberType) + delete(rawMsg, key) + case "originRoleAssignmentId": + err = unpopulate(val, "OriginRoleAssignmentID", &r.OriginRoleAssignmentID) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "roleAssignmentScheduleId": + err = unpopulate(val, "RoleAssignmentScheduleID", &r.RoleAssignmentScheduleID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "startDateTime": + err = unpopulateDateTimeRFC3339(val, "StartDateTime", &r.StartDateTime) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleListResult. +func (r RoleAssignmentScheduleListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleListResult. +func (r *RoleAssignmentScheduleListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleProperties. +func (r RoleAssignmentScheduleProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "assignmentType", r.AssignmentType) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populateDateTimeRFC3339(objectMap, "endDateTime", r.EndDateTime) + populate(objectMap, "expandedProperties", r.ExpandedProperties) + populate(objectMap, "linkedRoleEligibilityScheduleId", r.LinkedRoleEligibilityScheduleID) + populate(objectMap, "memberType", r.MemberType) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "roleAssignmentScheduleRequestId", r.RoleAssignmentScheduleRequestID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "scope", r.Scope) + populateDateTimeRFC3339(objectMap, "startDateTime", r.StartDateTime) + populate(objectMap, "status", r.Status) + populateDateTimeRFC3339(objectMap, "updatedOn", r.UpdatedOn) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleProperties. +func (r *RoleAssignmentScheduleProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "assignmentType": + err = unpopulate(val, "AssignmentType", &r.AssignmentType) + delete(rawMsg, key) + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "endDateTime": + err = unpopulateDateTimeRFC3339(val, "EndDateTime", &r.EndDateTime) + delete(rawMsg, key) + case "expandedProperties": + err = unpopulate(val, "ExpandedProperties", &r.ExpandedProperties) + delete(rawMsg, key) + case "linkedRoleEligibilityScheduleId": + err = unpopulate(val, "LinkedRoleEligibilityScheduleID", &r.LinkedRoleEligibilityScheduleID) + delete(rawMsg, key) + case "memberType": + err = unpopulate(val, "MemberType", &r.MemberType) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "roleAssignmentScheduleRequestId": + err = unpopulate(val, "RoleAssignmentScheduleRequestID", &r.RoleAssignmentScheduleRequestID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "startDateTime": + err = unpopulateDateTimeRFC3339(val, "StartDateTime", &r.StartDateTime) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + case "updatedOn": + err = unpopulateDateTimeRFC3339(val, "UpdatedOn", &r.UpdatedOn) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequest. +func (r RoleAssignmentScheduleRequest) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequest. +func (r *RoleAssignmentScheduleRequest) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequestFilter. +func (r RoleAssignmentScheduleRequestFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "requestorId", r.RequestorID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequestFilter. +func (r *RoleAssignmentScheduleRequestFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "requestorId": + err = unpopulate(val, "RequestorID", &r.RequestorID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequestListResult. +func (r RoleAssignmentScheduleRequestListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequestListResult. +func (r *RoleAssignmentScheduleRequestListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequestProperties. +func (r RoleAssignmentScheduleRequestProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "approvalId", r.ApprovalID) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populate(objectMap, "expandedProperties", r.ExpandedProperties) + populate(objectMap, "justification", r.Justification) + populate(objectMap, "linkedRoleEligibilityScheduleId", r.LinkedRoleEligibilityScheduleID) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "requestType", r.RequestType) + populate(objectMap, "requestorId", r.RequestorID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "scheduleInfo", r.ScheduleInfo) + populate(objectMap, "scope", r.Scope) + populate(objectMap, "status", r.Status) + populate(objectMap, "targetRoleAssignmentScheduleId", r.TargetRoleAssignmentScheduleID) + populate(objectMap, "targetRoleAssignmentScheduleInstanceId", r.TargetRoleAssignmentScheduleInstanceID) + populate(objectMap, "ticketInfo", r.TicketInfo) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequestProperties. +func (r *RoleAssignmentScheduleRequestProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "approvalId": + err = unpopulate(val, "ApprovalID", &r.ApprovalID) + delete(rawMsg, key) + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "expandedProperties": + err = unpopulate(val, "ExpandedProperties", &r.ExpandedProperties) + delete(rawMsg, key) + case "justification": + err = unpopulate(val, "Justification", &r.Justification) + delete(rawMsg, key) + case "linkedRoleEligibilityScheduleId": + err = unpopulate(val, "LinkedRoleEligibilityScheduleID", &r.LinkedRoleEligibilityScheduleID) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "requestType": + err = unpopulate(val, "RequestType", &r.RequestType) + delete(rawMsg, key) + case "requestorId": + err = unpopulate(val, "RequestorID", &r.RequestorID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "scheduleInfo": + err = unpopulate(val, "ScheduleInfo", &r.ScheduleInfo) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + case "targetRoleAssignmentScheduleId": + err = unpopulate(val, "TargetRoleAssignmentScheduleID", &r.TargetRoleAssignmentScheduleID) + delete(rawMsg, key) + case "targetRoleAssignmentScheduleInstanceId": + err = unpopulate(val, "TargetRoleAssignmentScheduleInstanceID", &r.TargetRoleAssignmentScheduleInstanceID) + delete(rawMsg, key) + case "ticketInfo": + err = unpopulate(val, "TicketInfo", &r.TicketInfo) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequestPropertiesScheduleInfo. +func (r RoleAssignmentScheduleRequestPropertiesScheduleInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "expiration", r.Expiration) + populateDateTimeRFC3339(objectMap, "startDateTime", r.StartDateTime) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequestPropertiesScheduleInfo. +func (r *RoleAssignmentScheduleRequestPropertiesScheduleInfo) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "expiration": + err = unpopulate(val, "Expiration", &r.Expiration) + delete(rawMsg, key) + case "startDateTime": + err = unpopulateDateTimeRFC3339(val, "StartDateTime", &r.StartDateTime) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration. +func (r RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "duration", r.Duration) + populateDateTimeRFC3339(objectMap, "endDateTime", r.EndDateTime) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration. +func (r *RoleAssignmentScheduleRequestPropertiesScheduleInfoExpiration) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "duration": + err = unpopulate(val, "Duration", &r.Duration) + delete(rawMsg, key) + case "endDateTime": + err = unpopulateDateTimeRFC3339(val, "EndDateTime", &r.EndDateTime) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleAssignmentScheduleRequestPropertiesTicketInfo. +func (r RoleAssignmentScheduleRequestPropertiesTicketInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "ticketNumber", r.TicketNumber) + populate(objectMap, "ticketSystem", r.TicketSystem) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleAssignmentScheduleRequestPropertiesTicketInfo. +func (r *RoleAssignmentScheduleRequestPropertiesTicketInfo) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "ticketNumber": + err = unpopulate(val, "TicketNumber", &r.TicketNumber) + delete(rawMsg, key) + case "ticketSystem": + err = unpopulate(val, "TicketSystem", &r.TicketSystem) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleDefinition. +func (r RoleDefinition) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleDefinition. +func (r *RoleDefinition) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleDefinitionFilter. +func (r RoleDefinitionFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "roleName", r.RoleName) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleDefinitionFilter. +func (r *RoleDefinitionFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "roleName": + err = unpopulate(val, "RoleName", &r.RoleName) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleDefinitionListResult. +func (r RoleDefinitionListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleDefinitionListResult. +func (r *RoleDefinitionListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleDefinitionProperties. +func (r RoleDefinitionProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "assignableScopes", r.AssignableScopes) + populate(objectMap, "description", r.Description) + populate(objectMap, "permissions", r.Permissions) + populate(objectMap, "roleName", r.RoleName) + populate(objectMap, "type", r.RoleType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleDefinitionProperties. +func (r *RoleDefinitionProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "assignableScopes": + err = unpopulate(val, "AssignableScopes", &r.AssignableScopes) + delete(rawMsg, key) + case "description": + err = unpopulate(val, "Description", &r.Description) + delete(rawMsg, key) + case "permissions": + err = unpopulate(val, "Permissions", &r.Permissions) + delete(rawMsg, key) + case "roleName": + err = unpopulate(val, "RoleName", &r.RoleName) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "RoleType", &r.RoleType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilitySchedule. +func (r RoleEligibilitySchedule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilitySchedule. +func (r *RoleEligibilitySchedule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleFilter. +func (r RoleEligibilityScheduleFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleFilter. +func (r *RoleEligibilityScheduleFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleInstance. +func (r RoleEligibilityScheduleInstance) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleInstance. +func (r *RoleEligibilityScheduleInstance) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleInstanceFilter. +func (r RoleEligibilityScheduleInstanceFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "roleEligibilityScheduleId", r.RoleEligibilityScheduleID) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleInstanceFilter. +func (r *RoleEligibilityScheduleInstanceFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "roleEligibilityScheduleId": + err = unpopulate(val, "RoleEligibilityScheduleID", &r.RoleEligibilityScheduleID) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleInstanceListResult. +func (r RoleEligibilityScheduleInstanceListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleInstanceListResult. +func (r *RoleEligibilityScheduleInstanceListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleInstanceProperties. +func (r RoleEligibilityScheduleInstanceProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populateDateTimeRFC3339(objectMap, "endDateTime", r.EndDateTime) + populate(objectMap, "expandedProperties", r.ExpandedProperties) + populate(objectMap, "memberType", r.MemberType) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "roleEligibilityScheduleId", r.RoleEligibilityScheduleID) + populate(objectMap, "scope", r.Scope) + populateDateTimeRFC3339(objectMap, "startDateTime", r.StartDateTime) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleInstanceProperties. +func (r *RoleEligibilityScheduleInstanceProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "endDateTime": + err = unpopulateDateTimeRFC3339(val, "EndDateTime", &r.EndDateTime) + delete(rawMsg, key) + case "expandedProperties": + err = unpopulate(val, "ExpandedProperties", &r.ExpandedProperties) + delete(rawMsg, key) + case "memberType": + err = unpopulate(val, "MemberType", &r.MemberType) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "roleEligibilityScheduleId": + err = unpopulate(val, "RoleEligibilityScheduleID", &r.RoleEligibilityScheduleID) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "startDateTime": + err = unpopulateDateTimeRFC3339(val, "StartDateTime", &r.StartDateTime) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleListResult. +func (r RoleEligibilityScheduleListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleListResult. +func (r *RoleEligibilityScheduleListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleProperties. +func (r RoleEligibilityScheduleProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populateDateTimeRFC3339(objectMap, "endDateTime", r.EndDateTime) + populate(objectMap, "expandedProperties", r.ExpandedProperties) + populate(objectMap, "memberType", r.MemberType) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "roleEligibilityScheduleRequestId", r.RoleEligibilityScheduleRequestID) + populate(objectMap, "scope", r.Scope) + populateDateTimeRFC3339(objectMap, "startDateTime", r.StartDateTime) + populate(objectMap, "status", r.Status) + populateDateTimeRFC3339(objectMap, "updatedOn", r.UpdatedOn) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleProperties. +func (r *RoleEligibilityScheduleProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "endDateTime": + err = unpopulateDateTimeRFC3339(val, "EndDateTime", &r.EndDateTime) + delete(rawMsg, key) + case "expandedProperties": + err = unpopulate(val, "ExpandedProperties", &r.ExpandedProperties) + delete(rawMsg, key) + case "memberType": + err = unpopulate(val, "MemberType", &r.MemberType) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "roleEligibilityScheduleRequestId": + err = unpopulate(val, "RoleEligibilityScheduleRequestID", &r.RoleEligibilityScheduleRequestID) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "startDateTime": + err = unpopulateDateTimeRFC3339(val, "StartDateTime", &r.StartDateTime) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + case "updatedOn": + err = unpopulateDateTimeRFC3339(val, "UpdatedOn", &r.UpdatedOn) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequest. +func (r RoleEligibilityScheduleRequest) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequest. +func (r *RoleEligibilityScheduleRequest) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequestFilter. +func (r RoleEligibilityScheduleRequestFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "requestorId", r.RequestorID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "status", r.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequestFilter. +func (r *RoleEligibilityScheduleRequestFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "requestorId": + err = unpopulate(val, "RequestorID", &r.RequestorID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequestListResult. +func (r RoleEligibilityScheduleRequestListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequestListResult. +func (r *RoleEligibilityScheduleRequestListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequestProperties. +func (r RoleEligibilityScheduleRequestProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "approvalId", r.ApprovalID) + populate(objectMap, "condition", r.Condition) + populate(objectMap, "conditionVersion", r.ConditionVersion) + populateDateTimeRFC3339(objectMap, "createdOn", r.CreatedOn) + populate(objectMap, "expandedProperties", r.ExpandedProperties) + populate(objectMap, "justification", r.Justification) + populate(objectMap, "principalId", r.PrincipalID) + populate(objectMap, "principalType", r.PrincipalType) + populate(objectMap, "requestType", r.RequestType) + populate(objectMap, "requestorId", r.RequestorID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "scheduleInfo", r.ScheduleInfo) + populate(objectMap, "scope", r.Scope) + populate(objectMap, "status", r.Status) + populate(objectMap, "targetRoleEligibilityScheduleId", r.TargetRoleEligibilityScheduleID) + populate(objectMap, "targetRoleEligibilityScheduleInstanceId", r.TargetRoleEligibilityScheduleInstanceID) + populate(objectMap, "ticketInfo", r.TicketInfo) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequestProperties. +func (r *RoleEligibilityScheduleRequestProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "approvalId": + err = unpopulate(val, "ApprovalID", &r.ApprovalID) + delete(rawMsg, key) + case "condition": + err = unpopulate(val, "Condition", &r.Condition) + delete(rawMsg, key) + case "conditionVersion": + err = unpopulate(val, "ConditionVersion", &r.ConditionVersion) + delete(rawMsg, key) + case "createdOn": + err = unpopulateDateTimeRFC3339(val, "CreatedOn", &r.CreatedOn) + delete(rawMsg, key) + case "expandedProperties": + err = unpopulate(val, "ExpandedProperties", &r.ExpandedProperties) + delete(rawMsg, key) + case "justification": + err = unpopulate(val, "Justification", &r.Justification) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &r.PrincipalID) + delete(rawMsg, key) + case "principalType": + err = unpopulate(val, "PrincipalType", &r.PrincipalType) + delete(rawMsg, key) + case "requestType": + err = unpopulate(val, "RequestType", &r.RequestType) + delete(rawMsg, key) + case "requestorId": + err = unpopulate(val, "RequestorID", &r.RequestorID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "scheduleInfo": + err = unpopulate(val, "ScheduleInfo", &r.ScheduleInfo) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &r.Status) + delete(rawMsg, key) + case "targetRoleEligibilityScheduleId": + err = unpopulate(val, "TargetRoleEligibilityScheduleID", &r.TargetRoleEligibilityScheduleID) + delete(rawMsg, key) + case "targetRoleEligibilityScheduleInstanceId": + err = unpopulate(val, "TargetRoleEligibilityScheduleInstanceID", &r.TargetRoleEligibilityScheduleInstanceID) + delete(rawMsg, key) + case "ticketInfo": + err = unpopulate(val, "TicketInfo", &r.TicketInfo) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequestPropertiesScheduleInfo. +func (r RoleEligibilityScheduleRequestPropertiesScheduleInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "expiration", r.Expiration) + populateDateTimeRFC3339(objectMap, "startDateTime", r.StartDateTime) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequestPropertiesScheduleInfo. +func (r *RoleEligibilityScheduleRequestPropertiesScheduleInfo) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "expiration": + err = unpopulate(val, "Expiration", &r.Expiration) + delete(rawMsg, key) + case "startDateTime": + err = unpopulateDateTimeRFC3339(val, "StartDateTime", &r.StartDateTime) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration. +func (r RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "duration", r.Duration) + populateDateTimeRFC3339(objectMap, "endDateTime", r.EndDateTime) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration. +func (r *RoleEligibilityScheduleRequestPropertiesScheduleInfoExpiration) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "duration": + err = unpopulate(val, "Duration", &r.Duration) + delete(rawMsg, key) + case "endDateTime": + err = unpopulateDateTimeRFC3339(val, "EndDateTime", &r.EndDateTime) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleEligibilityScheduleRequestPropertiesTicketInfo. +func (r RoleEligibilityScheduleRequestPropertiesTicketInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "ticketNumber", r.TicketNumber) + populate(objectMap, "ticketSystem", r.TicketSystem) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleEligibilityScheduleRequestPropertiesTicketInfo. +func (r *RoleEligibilityScheduleRequestPropertiesTicketInfo) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "ticketNumber": + err = unpopulate(val, "TicketNumber", &r.TicketNumber) + delete(rawMsg, key) + case "ticketSystem": + err = unpopulate(val, "TicketSystem", &r.TicketSystem) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicy. +func (r RoleManagementPolicy) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicy. +func (r *RoleManagementPolicy) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyApprovalRule. +func (r RoleManagementPolicyApprovalRule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + objectMap["ruleType"] = RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule + populate(objectMap, "setting", r.Setting) + populate(objectMap, "target", r.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyApprovalRule. +func (r *RoleManagementPolicyApprovalRule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "ruleType": + err = unpopulate(val, "RuleType", &r.RuleType) + delete(rawMsg, key) + case "setting": + err = unpopulate(val, "Setting", &r.Setting) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &r.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyAssignment. +func (r RoleManagementPolicyAssignment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "type", r.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyAssignment. +func (r *RoleManagementPolicyAssignment) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyAssignmentListResult. +func (r RoleManagementPolicyAssignmentListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyAssignmentListResult. +func (r *RoleManagementPolicyAssignmentListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyAssignmentProperties. +func (r RoleManagementPolicyAssignmentProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "effectiveRules", r.EffectiveRules) + populate(objectMap, "policyAssignmentProperties", r.PolicyAssignmentProperties) + populate(objectMap, "policyId", r.PolicyID) + populate(objectMap, "roleDefinitionId", r.RoleDefinitionID) + populate(objectMap, "scope", r.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyAssignmentProperties. +func (r *RoleManagementPolicyAssignmentProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "effectiveRules": + r.EffectiveRules, err = unmarshalRoleManagementPolicyRuleClassificationArray(val) + delete(rawMsg, key) + case "policyAssignmentProperties": + err = unpopulate(val, "PolicyAssignmentProperties", &r.PolicyAssignmentProperties) + delete(rawMsg, key) + case "policyId": + err = unpopulate(val, "PolicyID", &r.PolicyID) + delete(rawMsg, key) + case "roleDefinitionId": + err = unpopulate(val, "RoleDefinitionID", &r.RoleDefinitionID) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyAuthenticationContextRule. +func (r RoleManagementPolicyAuthenticationContextRule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "claimValue", r.ClaimValue) + populate(objectMap, "id", r.ID) + populate(objectMap, "isEnabled", r.IsEnabled) + objectMap["ruleType"] = RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule + populate(objectMap, "target", r.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyAuthenticationContextRule. +func (r *RoleManagementPolicyAuthenticationContextRule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "claimValue": + err = unpopulate(val, "ClaimValue", &r.ClaimValue) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "isEnabled": + err = unpopulate(val, "IsEnabled", &r.IsEnabled) + delete(rawMsg, key) + case "ruleType": + err = unpopulate(val, "RuleType", &r.RuleType) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &r.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyEnablementRule. +func (r RoleManagementPolicyEnablementRule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "enabledRules", r.EnabledRules) + populate(objectMap, "id", r.ID) + objectMap["ruleType"] = RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule + populate(objectMap, "target", r.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyEnablementRule. +func (r *RoleManagementPolicyEnablementRule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "enabledRules": + err = unpopulate(val, "EnabledRules", &r.EnabledRules) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "ruleType": + err = unpopulate(val, "RuleType", &r.RuleType) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &r.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyExpirationRule. +func (r RoleManagementPolicyExpirationRule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "isExpirationRequired", r.IsExpirationRequired) + populate(objectMap, "maximumDuration", r.MaximumDuration) + objectMap["ruleType"] = RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule + populate(objectMap, "target", r.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyExpirationRule. +func (r *RoleManagementPolicyExpirationRule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "isExpirationRequired": + err = unpopulate(val, "IsExpirationRequired", &r.IsExpirationRequired) + delete(rawMsg, key) + case "maximumDuration": + err = unpopulate(val, "MaximumDuration", &r.MaximumDuration) + delete(rawMsg, key) + case "ruleType": + err = unpopulate(val, "RuleType", &r.RuleType) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &r.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyListResult. +func (r RoleManagementPolicyListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyListResult. +func (r *RoleManagementPolicyListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyNotificationRule. +func (r RoleManagementPolicyNotificationRule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "isDefaultRecipientsEnabled", r.IsDefaultRecipientsEnabled) + populate(objectMap, "notificationLevel", r.NotificationLevel) + populate(objectMap, "notificationRecipients", r.NotificationRecipients) + populate(objectMap, "notificationType", r.NotificationType) + populate(objectMap, "recipientType", r.RecipientType) + objectMap["ruleType"] = RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule + populate(objectMap, "target", r.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyNotificationRule. +func (r *RoleManagementPolicyNotificationRule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "isDefaultRecipientsEnabled": + err = unpopulate(val, "IsDefaultRecipientsEnabled", &r.IsDefaultRecipientsEnabled) + delete(rawMsg, key) + case "notificationLevel": + err = unpopulate(val, "NotificationLevel", &r.NotificationLevel) + delete(rawMsg, key) + case "notificationRecipients": + err = unpopulate(val, "NotificationRecipients", &r.NotificationRecipients) + delete(rawMsg, key) + case "notificationType": + err = unpopulate(val, "NotificationType", &r.NotificationType) + delete(rawMsg, key) + case "recipientType": + err = unpopulate(val, "RecipientType", &r.RecipientType) + delete(rawMsg, key) + case "ruleType": + err = unpopulate(val, "RuleType", &r.RuleType) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &r.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyProperties. +func (r RoleManagementPolicyProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", r.Description) + populate(objectMap, "displayName", r.DisplayName) + populate(objectMap, "effectiveRules", r.EffectiveRules) + populate(objectMap, "isOrganizationDefault", r.IsOrganizationDefault) + populate(objectMap, "lastModifiedBy", r.LastModifiedBy) + populateDateTimeRFC3339(objectMap, "lastModifiedDateTime", r.LastModifiedDateTime) + populate(objectMap, "policyProperties", r.PolicyProperties) + populate(objectMap, "rules", r.Rules) + populate(objectMap, "scope", r.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyProperties. +func (r *RoleManagementPolicyProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &r.Description) + delete(rawMsg, key) + case "displayName": + err = unpopulate(val, "DisplayName", &r.DisplayName) + delete(rawMsg, key) + case "effectiveRules": + r.EffectiveRules, err = unmarshalRoleManagementPolicyRuleClassificationArray(val) + delete(rawMsg, key) + case "isOrganizationDefault": + err = unpopulate(val, "IsOrganizationDefault", &r.IsOrganizationDefault) + delete(rawMsg, key) + case "lastModifiedBy": + err = unpopulate(val, "LastModifiedBy", &r.LastModifiedBy) + delete(rawMsg, key) + case "lastModifiedDateTime": + err = unpopulateDateTimeRFC3339(val, "LastModifiedDateTime", &r.LastModifiedDateTime) + delete(rawMsg, key) + case "policyProperties": + err = unpopulate(val, "PolicyProperties", &r.PolicyProperties) + delete(rawMsg, key) + case "rules": + r.Rules, err = unmarshalRoleManagementPolicyRuleClassificationArray(val) + delete(rawMsg, key) + case "scope": + err = unpopulate(val, "Scope", &r.Scope) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyRule. +func (r RoleManagementPolicyRule) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + objectMap["ruleType"] = r.RuleType + populate(objectMap, "target", r.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyRule. +func (r *RoleManagementPolicyRule) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "ruleType": + err = unpopulate(val, "RuleType", &r.RuleType) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &r.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleManagementPolicyRuleTarget. +func (r RoleManagementPolicyRuleTarget) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "caller", r.Caller) + populate(objectMap, "enforcedSettings", r.EnforcedSettings) + populate(objectMap, "inheritableSettings", r.InheritableSettings) + populate(objectMap, "level", r.Level) + populate(objectMap, "operations", r.Operations) + populate(objectMap, "targetObjects", r.TargetObjects) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleManagementPolicyRuleTarget. +func (r *RoleManagementPolicyRuleTarget) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "caller": + err = unpopulate(val, "Caller", &r.Caller) + delete(rawMsg, key) + case "enforcedSettings": + err = unpopulate(val, "EnforcedSettings", &r.EnforcedSettings) + delete(rawMsg, key) + case "inheritableSettings": + err = unpopulate(val, "InheritableSettings", &r.InheritableSettings) + delete(rawMsg, key) + case "level": + err = unpopulate(val, "Level", &r.Level) + delete(rawMsg, key) + case "operations": + err = unpopulate(val, "Operations", &r.Operations) + delete(rawMsg, key) + case "targetObjects": + err = unpopulate(val, "TargetObjects", &r.TargetObjects) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type UserSet. +func (u UserSet) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", u.Description) + populate(objectMap, "id", u.ID) + populate(objectMap, "isBackup", u.IsBackup) + populate(objectMap, "userType", u.UserType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type UserSet. +func (u *UserSet) 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", u, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &u.Description) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &u.ID) + delete(rawMsg, key) + case "isBackup": + err = unpopulate(val, "IsBackup", &u.IsBackup) + delete(rawMsg, key) + case "userType": + err = unpopulate(val, "UserType", &u.UserType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", u, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ValidationResponse. +func (v ValidationResponse) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "errorInfo", v.ErrorInfo) + populate(objectMap, "isValid", v.IsValid) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ValidationResponse. +func (v *ValidationResponse) 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", v, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "errorInfo": + err = unpopulate(val, "ErrorInfo", &v.ErrorInfo) + delete(rawMsg, key) + case "isValid": + err = unpopulate(val, "IsValid", &v.IsValid) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", v, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ValidationResponseErrorInfo. +func (v ValidationResponseErrorInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", v.Code) + populate(objectMap, "message", v.Message) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ValidationResponseErrorInfo. +func (v *ValidationResponseErrorInfo) 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", v, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &v.Code) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &v.Message) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", v, err) + } + } + return nil +} + +func populate(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else if !reflect.ValueOf(v).IsNil() { + m[k] = v + } +} + +func populateAny(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else { + m[k] = v + } +} + +func unpopulate(data json.RawMessage, fn string, v any) 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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/options.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/options.go new file mode 100644 index 000000000..05e23b54d --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/options.go @@ -0,0 +1,426 @@ +//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 armauthorization + +// ClassicAdministratorsClientListOptions contains the optional parameters for the ClassicAdministratorsClient.NewListPager +// method. +type ClassicAdministratorsClientListOptions struct { + // placeholder for future optional parameters +} + +// DenyAssignmentsClientGetByIDOptions contains the optional parameters for the DenyAssignmentsClient.GetByID method. +type DenyAssignmentsClientGetByIDOptions struct { + // placeholder for future optional parameters +} + +// DenyAssignmentsClientGetOptions contains the optional parameters for the DenyAssignmentsClient.Get method. +type DenyAssignmentsClientGetOptions struct { + // placeholder for future optional parameters +} + +// DenyAssignmentsClientListForResourceGroupOptions contains the optional parameters for the DenyAssignmentsClient.NewListForResourceGroupPager +// method. +type DenyAssignmentsClientListForResourceGroupOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all deny assignments at or above the scope. Use $filter=denyAssignmentName + // eq '{name}' to search deny assignments by name at + // specified scope. Use $filter=principalId eq '{id}' to return all deny assignments at, above and below the scope for the + // specified principal. Use $filter=gdprExportPrincipalId eq '{id}' to return all + // deny assignments at, above and below the scope for the specified principal. This filter is different from the principalId + // filter as it returns not only those deny assignments that contain the + // specified principal is the Principals list but also those deny assignments that contain the specified principal is the + // ExcludePrincipals list. Additionally, when gdprExportPrincipalId filter is used, + // only the deny assignment name and description properties are returned. + Filter *string +} + +// DenyAssignmentsClientListForResourceOptions contains the optional parameters for the DenyAssignmentsClient.NewListForResourcePager +// method. +type DenyAssignmentsClientListForResourceOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all deny assignments at or above the scope. Use $filter=denyAssignmentName + // eq '{name}' to search deny assignments by name at + // specified scope. Use $filter=principalId eq '{id}' to return all deny assignments at, above and below the scope for the + // specified principal. Use $filter=gdprExportPrincipalId eq '{id}' to return all + // deny assignments at, above and below the scope for the specified principal. This filter is different from the principalId + // filter as it returns not only those deny assignments that contain the + // specified principal is the Principals list but also those deny assignments that contain the specified principal is the + // ExcludePrincipals list. Additionally, when gdprExportPrincipalId filter is used, + // only the deny assignment name and description properties are returned. + Filter *string +} + +// DenyAssignmentsClientListForScopeOptions contains the optional parameters for the DenyAssignmentsClient.NewListForScopePager +// method. +type DenyAssignmentsClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all deny assignments at or above the scope. Use $filter=denyAssignmentName + // eq '{name}' to search deny assignments by name at + // specified scope. Use $filter=principalId eq '{id}' to return all deny assignments at, above and below the scope for the + // specified principal. Use $filter=gdprExportPrincipalId eq '{id}' to return all + // deny assignments at, above and below the scope for the specified principal. This filter is different from the principalId + // filter as it returns not only those deny assignments that contain the + // specified principal is the Principals list but also those deny assignments that contain the specified principal is the + // ExcludePrincipals list. Additionally, when gdprExportPrincipalId filter is used, + // only the deny assignment name and description properties are returned. + Filter *string +} + +// DenyAssignmentsClientListOptions contains the optional parameters for the DenyAssignmentsClient.NewListPager method. +type DenyAssignmentsClientListOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all deny assignments at or above the scope. Use $filter=denyAssignmentName + // eq '{name}' to search deny assignments by name at + // specified scope. Use $filter=principalId eq '{id}' to return all deny assignments at, above and below the scope for the + // specified principal. Use $filter=gdprExportPrincipalId eq '{id}' to return all + // deny assignments at, above and below the scope for the specified principal. This filter is different from the principalId + // filter as it returns not only those deny assignments that contain the + // specified principal is the Principals list but also those deny assignments that contain the specified principal is the + // ExcludePrincipals list. Additionally, when gdprExportPrincipalId filter is used, + // only the deny assignment name and description properties are returned. + Filter *string +} + +// EligibleChildResourcesClientGetOptions contains the optional parameters for the EligibleChildResourcesClient.NewGetPager +// method. +type EligibleChildResourcesClientGetOptions struct { + // The filter to apply on the operation. Use $filter=resourceType+eq+'Subscription' to filter on only resource of type = 'Subscription'. + // Use + // $filter=resourceType+eq+'subscription'+or+resourceType+eq+'resourcegroup' to filter on resource of type = 'Subscription' + // or 'ResourceGroup' + Filter *string +} + +// GlobalAdministratorClientElevateAccessOptions contains the optional parameters for the GlobalAdministratorClient.ElevateAccess +// method. +type GlobalAdministratorClientElevateAccessOptions struct { + // placeholder for future optional parameters +} + +// PermissionsClientListForResourceGroupOptions contains the optional parameters for the PermissionsClient.NewListForResourceGroupPager +// method. +type PermissionsClientListForResourceGroupOptions struct { + // placeholder for future optional parameters +} + +// PermissionsClientListForResourceOptions contains the optional parameters for the PermissionsClient.NewListForResourcePager +// method. +type PermissionsClientListForResourceOptions struct { + // placeholder for future optional parameters +} + +// ProviderOperationsMetadataClientGetOptions contains the optional parameters for the ProviderOperationsMetadataClient.Get +// method. +type ProviderOperationsMetadataClientGetOptions struct { + // Specifies whether to expand the values. + Expand *string +} + +// ProviderOperationsMetadataClientListOptions contains the optional parameters for the ProviderOperationsMetadataClient.NewListPager +// method. +type ProviderOperationsMetadataClientListOptions struct { + // Specifies whether to expand the values. + Expand *string +} + +// RoleAssignmentScheduleInstancesClientGetOptions contains the optional parameters for the RoleAssignmentScheduleInstancesClient.Get +// method. +type RoleAssignmentScheduleInstancesClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentScheduleInstancesClientListForScopeOptions contains the optional parameters for the RoleAssignmentScheduleInstancesClient.NewListForScopePager +// method. +type RoleAssignmentScheduleInstancesClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignment schedules at or above the scope. + // Use $filter=principalId eq {id} to return all role assignment schedules at, + // above or below the scope for the specified principal. Use $filter=assignedTo('{userId}') to return all role assignment + // schedule instances for the user. Use $filter=asTarget() to return all role + // assignment schedule instances created for the current user. + Filter *string +} + +// RoleAssignmentScheduleRequestsClientCancelOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Cancel +// method. +type RoleAssignmentScheduleRequestsClientCancelOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentScheduleRequestsClientCreateOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Create +// method. +type RoleAssignmentScheduleRequestsClientCreateOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentScheduleRequestsClientGetOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Get +// method. +type RoleAssignmentScheduleRequestsClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentScheduleRequestsClientListForScopeOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.NewListForScopePager +// method. +type RoleAssignmentScheduleRequestsClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignment schedule requests at or above + // the scope. Use $filter=principalId eq {id} to return all role assignment + // schedule requests at, above or below the scope for the specified principal. Use $filter=asRequestor() to return all role + // assignment schedule requests requested by the current user. Use + // $filter=asTarget() to return all role assignment schedule requests created for the current user. Use $filter=asApprover() + // to return all role assignment schedule requests where the current user is an + // approver. + Filter *string +} + +// RoleAssignmentScheduleRequestsClientValidateOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Validate +// method. +type RoleAssignmentScheduleRequestsClientValidateOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentSchedulesClientGetOptions contains the optional parameters for the RoleAssignmentSchedulesClient.Get method. +type RoleAssignmentSchedulesClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentSchedulesClientListForScopeOptions contains the optional parameters for the RoleAssignmentSchedulesClient.NewListForScopePager +// method. +type RoleAssignmentSchedulesClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignment schedules at or above the scope. + // Use $filter=principalId eq {id} to return all role assignment schedules at, + // above or below the scope for the specified principal. Use $filter=assignedTo('{userId}') to return all role assignment + // schedules for the current user. Use $filter=asTarget() to return all role + // assignment schedules created for the current user. + Filter *string +} + +// RoleAssignmentsClientCreateByIDOptions contains the optional parameters for the RoleAssignmentsClient.CreateByID method. +type RoleAssignmentsClientCreateByIDOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentsClientCreateOptions contains the optional parameters for the RoleAssignmentsClient.Create method. +type RoleAssignmentsClientCreateOptions struct { + // placeholder for future optional parameters +} + +// RoleAssignmentsClientDeleteByIDOptions contains the optional parameters for the RoleAssignmentsClient.DeleteByID method. +type RoleAssignmentsClientDeleteByIDOptions struct { + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientDeleteOptions contains the optional parameters for the RoleAssignmentsClient.Delete method. +type RoleAssignmentsClientDeleteOptions struct { + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientGetByIDOptions contains the optional parameters for the RoleAssignmentsClient.GetByID method. +type RoleAssignmentsClientGetByIDOptions struct { + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientGetOptions contains the optional parameters for the RoleAssignmentsClient.Get method. +type RoleAssignmentsClientGetOptions struct { + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientListForResourceGroupOptions contains the optional parameters for the RoleAssignmentsClient.NewListForResourceGroupPager +// method. +type RoleAssignmentsClientListForResourceGroupOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignments at or above the scope. Use $filter=principalId + // eq {id} to return all role assignments at, above or below the + // scope for the specified principal. + Filter *string + + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientListForResourceOptions contains the optional parameters for the RoleAssignmentsClient.NewListForResourcePager +// method. +type RoleAssignmentsClientListForResourceOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignments at or above the scope. Use $filter=principalId + // eq {id} to return all role assignments at, above or below the + // scope for the specified principal. + Filter *string + + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientListForScopeOptions contains the optional parameters for the RoleAssignmentsClient.NewListForScopePager +// method. +type RoleAssignmentsClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignments at or above the scope. Use $filter=principalId + // eq {id} to return all role assignments at, above or below the + // scope for the specified principal. + Filter *string + + // The skipToken to apply on the operation. Use $skipToken={skiptoken} to return paged role assignments following the skipToken + // passed. Only supported on provider level calls. + SkipToken *string + + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleAssignmentsClientListForSubscriptionOptions contains the optional parameters for the RoleAssignmentsClient.NewListForSubscriptionPager +// method. +type RoleAssignmentsClientListForSubscriptionOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignments at or above the scope. Use $filter=principalId + // eq {id} to return all role assignments at, above or below the + // scope for the specified principal. + Filter *string + + // Tenant ID for cross-tenant request + TenantID *string +} + +// RoleDefinitionsClientCreateOrUpdateOptions contains the optional parameters for the RoleDefinitionsClient.CreateOrUpdate +// method. +type RoleDefinitionsClientCreateOrUpdateOptions struct { + // placeholder for future optional parameters +} + +// RoleDefinitionsClientDeleteOptions contains the optional parameters for the RoleDefinitionsClient.Delete method. +type RoleDefinitionsClientDeleteOptions struct { + // placeholder for future optional parameters +} + +// RoleDefinitionsClientGetByIDOptions contains the optional parameters for the RoleDefinitionsClient.GetByID method. +type RoleDefinitionsClientGetByIDOptions struct { + // placeholder for future optional parameters +} + +// RoleDefinitionsClientGetOptions contains the optional parameters for the RoleDefinitionsClient.Get method. +type RoleDefinitionsClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleDefinitionsClientListOptions contains the optional parameters for the RoleDefinitionsClient.NewListPager method. +type RoleDefinitionsClientListOptions struct { + // The filter to apply on the operation. Use atScopeAndBelow filter to search below the given scope as well. + Filter *string +} + +// RoleEligibilityScheduleInstancesClientGetOptions contains the optional parameters for the RoleEligibilityScheduleInstancesClient.Get +// method. +type RoleEligibilityScheduleInstancesClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleEligibilityScheduleInstancesClientListForScopeOptions contains the optional parameters for the RoleEligibilityScheduleInstancesClient.NewListForScopePager +// method. +type RoleEligibilityScheduleInstancesClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role assignment schedules at or above the scope. + // Use $filter=principalId eq {id} to return all role assignment schedules at, + // above or below the scope for the specified principal. Use $filter=assignedTo('{userId}') to return all role eligibility + // schedules for the user. Use $filter=asTarget() to return all role eligibility + // schedules created for the current user. + Filter *string +} + +// RoleEligibilityScheduleRequestsClientCancelOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Cancel +// method. +type RoleEligibilityScheduleRequestsClientCancelOptions struct { + // placeholder for future optional parameters +} + +// RoleEligibilityScheduleRequestsClientCreateOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Create +// method. +type RoleEligibilityScheduleRequestsClientCreateOptions struct { + // placeholder for future optional parameters +} + +// RoleEligibilityScheduleRequestsClientGetOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Get +// method. +type RoleEligibilityScheduleRequestsClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleEligibilityScheduleRequestsClientListForScopeOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.NewListForScopePager +// method. +type RoleEligibilityScheduleRequestsClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role eligibility schedule requests at or above + // the scope. Use $filter=principalId eq {id} to return all role eligibility + // schedule requests at, above or below the scope for the specified principal. Use $filter=asRequestor() to return all role + // eligibility schedule requests requested by the current user. Use + // $filter=asTarget() to return all role eligibility schedule requests created for the current user. Use $filter=asApprover() + // to return all role eligibility schedule requests where the current user is an + // approver. + Filter *string +} + +// RoleEligibilityScheduleRequestsClientValidateOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Validate +// method. +type RoleEligibilityScheduleRequestsClientValidateOptions struct { + // placeholder for future optional parameters +} + +// RoleEligibilitySchedulesClientGetOptions contains the optional parameters for the RoleEligibilitySchedulesClient.Get method. +type RoleEligibilitySchedulesClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleEligibilitySchedulesClientListForScopeOptions contains the optional parameters for the RoleEligibilitySchedulesClient.NewListForScopePager +// method. +type RoleEligibilitySchedulesClientListForScopeOptions struct { + // The filter to apply on the operation. Use $filter=atScope() to return all role eligibility schedules at or above the scope. + // Use $filter=principalId eq {id} to return all role eligibility schedules at, + // above or below the scope for the specified principal. Use $filter=assignedTo('{userId}') to return all role eligibility + // schedules for the user. Use $filter=asTarget() to return all role eligibility + // schedules created for the current user. + Filter *string +} + +// RoleManagementPoliciesClientDeleteOptions contains the optional parameters for the RoleManagementPoliciesClient.Delete +// method. +type RoleManagementPoliciesClientDeleteOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPoliciesClientGetOptions contains the optional parameters for the RoleManagementPoliciesClient.Get method. +type RoleManagementPoliciesClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPoliciesClientListForScopeOptions contains the optional parameters for the RoleManagementPoliciesClient.NewListForScopePager +// method. +type RoleManagementPoliciesClientListForScopeOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPoliciesClientUpdateOptions contains the optional parameters for the RoleManagementPoliciesClient.Update +// method. +type RoleManagementPoliciesClientUpdateOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPolicyAssignmentsClientCreateOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.Create +// method. +type RoleManagementPolicyAssignmentsClientCreateOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPolicyAssignmentsClientDeleteOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.Delete +// method. +type RoleManagementPolicyAssignmentsClientDeleteOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPolicyAssignmentsClientGetOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.Get +// method. +type RoleManagementPolicyAssignmentsClientGetOptions struct { + // placeholder for future optional parameters +} + +// RoleManagementPolicyAssignmentsClientListForScopeOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.NewListForScopePager +// method. +type RoleManagementPolicyAssignmentsClientListForScopeOptions struct { + // placeholder for future optional parameters +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/permissions_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/permissions_client.go new file mode 100644 index 000000000..aeed18e26 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/permissions_client.go @@ -0,0 +1,175 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// PermissionsClient contains the methods for the Permissions group. +// Don't use this type directly, use NewPermissionsClient() instead. +type PermissionsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewPermissionsClient creates a new instance of PermissionsClient with the specified values. +// - subscriptionID - The ID of the target subscription. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewPermissionsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*PermissionsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &PermissionsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// NewListForResourcePager - Gets all permissions the caller has for a resource. +// +// Generated from API version 2022-04-01 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type of the resource. +// - resourceName - The name of the resource to get the permissions for. +// - options - PermissionsClientListForResourceOptions contains the optional parameters for the PermissionsClient.NewListForResourcePager +// method. +func (client *PermissionsClient) NewListForResourcePager(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, options *PermissionsClientListForResourceOptions) *runtime.Pager[PermissionsClientListForResourceResponse] { + return runtime.NewPager(runtime.PagingHandler[PermissionsClientListForResourceResponse]{ + More: func(page PermissionsClientListForResourceResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *PermissionsClientListForResourceResponse) (PermissionsClientListForResourceResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "PermissionsClient.NewListForResourcePager") + 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.listForResourceCreateRequest(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, options) + }, nil) + if err != nil { + return PermissionsClientListForResourceResponse{}, err + } + return client.listForResourceHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForResourceCreateRequest creates the ListForResource request. +func (client *PermissionsClient) listForResourceCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, options *PermissionsClientListForResourceOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}/providers/Microsoft.Authorization/permissions" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", resourceProviderNamespace) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForResourceHandleResponse handles the ListForResource response. +func (client *PermissionsClient) listForResourceHandleResponse(resp *http.Response) (PermissionsClientListForResourceResponse, error) { + result := PermissionsClientListForResourceResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.PermissionGetResult); err != nil { + return PermissionsClientListForResourceResponse{}, err + } + return result, nil +} + +// NewListForResourceGroupPager - Gets all permissions the caller has for a resource group. +// +// Generated from API version 2022-04-01 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - options - PermissionsClientListForResourceGroupOptions contains the optional parameters for the PermissionsClient.NewListForResourceGroupPager +// method. +func (client *PermissionsClient) NewListForResourceGroupPager(resourceGroupName string, options *PermissionsClientListForResourceGroupOptions) *runtime.Pager[PermissionsClientListForResourceGroupResponse] { + return runtime.NewPager(runtime.PagingHandler[PermissionsClientListForResourceGroupResponse]{ + More: func(page PermissionsClientListForResourceGroupResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *PermissionsClientListForResourceGroupResponse) (PermissionsClientListForResourceGroupResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "PermissionsClient.NewListForResourceGroupPager") + 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.listForResourceGroupCreateRequest(ctx, resourceGroupName, options) + }, nil) + if err != nil { + return PermissionsClientListForResourceGroupResponse{}, err + } + return client.listForResourceGroupHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForResourceGroupCreateRequest creates the ListForResourceGroup request. +func (client *PermissionsClient) listForResourceGroupCreateRequest(ctx context.Context, resourceGroupName string, options *PermissionsClientListForResourceGroupOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Authorization/permissions" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForResourceGroupHandleResponse handles the ListForResourceGroup response. +func (client *PermissionsClient) listForResourceGroupHandleResponse(resp *http.Response) (PermissionsClientListForResourceGroupResponse, error) { + result := PermissionsClientListForResourceGroupResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.PermissionGetResult); err != nil { + return PermissionsClientListForResourceGroupResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/polymorphic_helpers.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/polymorphic_helpers.go new file mode 100644 index 000000000..6f1166cc0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/polymorphic_helpers.go @@ -0,0 +1,59 @@ +//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 armauthorization + +import "encoding/json" + +func unmarshalRoleManagementPolicyRuleClassification(rawMsg json.RawMessage) (RoleManagementPolicyRuleClassification, error) { + if rawMsg == nil { + return nil, nil + } + var m map[string]any + if err := json.Unmarshal(rawMsg, &m); err != nil { + return nil, err + } + var b RoleManagementPolicyRuleClassification + switch m["ruleType"] { + case string(RoleManagementPolicyRuleTypeRoleManagementPolicyApprovalRule): + b = &RoleManagementPolicyApprovalRule{} + case string(RoleManagementPolicyRuleTypeRoleManagementPolicyAuthenticationContextRule): + b = &RoleManagementPolicyAuthenticationContextRule{} + case string(RoleManagementPolicyRuleTypeRoleManagementPolicyEnablementRule): + b = &RoleManagementPolicyEnablementRule{} + case string(RoleManagementPolicyRuleTypeRoleManagementPolicyExpirationRule): + b = &RoleManagementPolicyExpirationRule{} + case string(RoleManagementPolicyRuleTypeRoleManagementPolicyNotificationRule): + b = &RoleManagementPolicyNotificationRule{} + default: + b = &RoleManagementPolicyRule{} + } + if err := json.Unmarshal(rawMsg, b); err != nil { + return nil, err + } + return b, nil +} + +func unmarshalRoleManagementPolicyRuleClassificationArray(rawMsg json.RawMessage) ([]RoleManagementPolicyRuleClassification, error) { + if rawMsg == nil { + return nil, nil + } + var rawMessages []json.RawMessage + if err := json.Unmarshal(rawMsg, &rawMessages); err != nil { + return nil, err + } + fArray := make([]RoleManagementPolicyRuleClassification, len(rawMessages)) + for index, rawMessage := range rawMessages { + f, err := unmarshalRoleManagementPolicyRuleClassification(rawMessage) + if err != nil { + return nil, err + } + fArray[index] = f + } + return fArray, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/provideroperationsmetadata_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/provideroperationsmetadata_client.go new file mode 100644 index 000000000..dccd8687a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/provideroperationsmetadata_client.go @@ -0,0 +1,149 @@ +//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 armauthorization + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "strings" +) + +// ProviderOperationsMetadataClient contains the methods for the ProviderOperationsMetadata group. +// Don't use this type directly, use NewProviderOperationsMetadataClient() instead. +type ProviderOperationsMetadataClient struct { + internal *arm.Client +} + +// NewProviderOperationsMetadataClient creates a new instance of ProviderOperationsMetadataClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewProviderOperationsMetadataClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*ProviderOperationsMetadataClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &ProviderOperationsMetadataClient{ + internal: cl, + } + return client, nil +} + +// Get - Gets provider operations metadata for the specified resource provider. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - resourceProviderNamespace - The namespace of the resource provider. +// - options - ProviderOperationsMetadataClientGetOptions contains the optional parameters for the ProviderOperationsMetadataClient.Get +// method. +func (client *ProviderOperationsMetadataClient) Get(ctx context.Context, resourceProviderNamespace string, options *ProviderOperationsMetadataClientGetOptions) (ProviderOperationsMetadataClientGetResponse, error) { + var err error + const operationName = "ProviderOperationsMetadataClient.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 ProviderOperationsMetadataClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProviderOperationsMetadataClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProviderOperationsMetadataClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *ProviderOperationsMetadataClient) getCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProviderOperationsMetadataClientGetOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Authorization/providerOperations/{resourceProviderNamespace}" + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", resourceProviderNamespace) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *ProviderOperationsMetadataClient) getHandleResponse(resp *http.Response) (ProviderOperationsMetadataClientGetResponse, error) { + result := ProviderOperationsMetadataClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ProviderOperationsMetadata); err != nil { + return ProviderOperationsMetadataClientGetResponse{}, err + } + return result, nil +} + +// NewListPager - Gets provider operations metadata for all resource providers. +// +// Generated from API version 2022-04-01 +// - options - ProviderOperationsMetadataClientListOptions contains the optional parameters for the ProviderOperationsMetadataClient.NewListPager +// method. +func (client *ProviderOperationsMetadataClient) NewListPager(options *ProviderOperationsMetadataClientListOptions) *runtime.Pager[ProviderOperationsMetadataClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[ProviderOperationsMetadataClientListResponse]{ + More: func(page ProviderOperationsMetadataClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *ProviderOperationsMetadataClientListResponse) (ProviderOperationsMetadataClientListResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "ProviderOperationsMetadataClient.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 ProviderOperationsMetadataClientListResponse{}, err + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *ProviderOperationsMetadataClient) listCreateRequest(ctx context.Context, options *ProviderOperationsMetadataClientListOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Authorization/providerOperations" + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *ProviderOperationsMetadataClient) listHandleResponse(resp *http.Response) (ProviderOperationsMetadataClientListResponse, error) { + result := ProviderOperationsMetadataClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ProviderOperationsMetadataListResult); err != nil { + return ProviderOperationsMetadataClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/response_types.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/response_types.go new file mode 100644 index 000000000..a1df622bc --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/response_types.go @@ -0,0 +1,328 @@ +//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 armauthorization + +// ClassicAdministratorsClientListResponse contains the response from method ClassicAdministratorsClient.NewListPager. +type ClassicAdministratorsClientListResponse struct { + // ClassicAdministrator list result information. + ClassicAdministratorListResult +} + +// DenyAssignmentsClientGetByIDResponse contains the response from method DenyAssignmentsClient.GetByID. +type DenyAssignmentsClientGetByIDResponse struct { + // Deny Assignment + DenyAssignment +} + +// DenyAssignmentsClientGetResponse contains the response from method DenyAssignmentsClient.Get. +type DenyAssignmentsClientGetResponse struct { + // Deny Assignment + DenyAssignment +} + +// DenyAssignmentsClientListForResourceGroupResponse contains the response from method DenyAssignmentsClient.NewListForResourceGroupPager. +type DenyAssignmentsClientListForResourceGroupResponse struct { + // Deny assignment list operation result. + DenyAssignmentListResult +} + +// DenyAssignmentsClientListForResourceResponse contains the response from method DenyAssignmentsClient.NewListForResourcePager. +type DenyAssignmentsClientListForResourceResponse struct { + // Deny assignment list operation result. + DenyAssignmentListResult +} + +// DenyAssignmentsClientListForScopeResponse contains the response from method DenyAssignmentsClient.NewListForScopePager. +type DenyAssignmentsClientListForScopeResponse struct { + // Deny assignment list operation result. + DenyAssignmentListResult +} + +// DenyAssignmentsClientListResponse contains the response from method DenyAssignmentsClient.NewListPager. +type DenyAssignmentsClientListResponse struct { + // Deny assignment list operation result. + DenyAssignmentListResult +} + +// EligibleChildResourcesClientGetResponse contains the response from method EligibleChildResourcesClient.NewGetPager. +type EligibleChildResourcesClientGetResponse struct { + // Eligible child resources list operation result. + EligibleChildResourcesListResult +} + +// GlobalAdministratorClientElevateAccessResponse contains the response from method GlobalAdministratorClient.ElevateAccess. +type GlobalAdministratorClientElevateAccessResponse struct { + // placeholder for future response values +} + +// PermissionsClientListForResourceGroupResponse contains the response from method PermissionsClient.NewListForResourceGroupPager. +type PermissionsClientListForResourceGroupResponse struct { + // Permissions information. + PermissionGetResult +} + +// PermissionsClientListForResourceResponse contains the response from method PermissionsClient.NewListForResourcePager. +type PermissionsClientListForResourceResponse struct { + // Permissions information. + PermissionGetResult +} + +// ProviderOperationsMetadataClientGetResponse contains the response from method ProviderOperationsMetadataClient.Get. +type ProviderOperationsMetadataClientGetResponse struct { + // Provider Operations metadata + ProviderOperationsMetadata +} + +// ProviderOperationsMetadataClientListResponse contains the response from method ProviderOperationsMetadataClient.NewListPager. +type ProviderOperationsMetadataClientListResponse struct { + // Provider operations metadata list + ProviderOperationsMetadataListResult +} + +// RoleAssignmentScheduleInstancesClientGetResponse contains the response from method RoleAssignmentScheduleInstancesClient.Get. +type RoleAssignmentScheduleInstancesClientGetResponse struct { + // Information about current or upcoming role assignment schedule instance + RoleAssignmentScheduleInstance +} + +// RoleAssignmentScheduleInstancesClientListForScopeResponse contains the response from method RoleAssignmentScheduleInstancesClient.NewListForScopePager. +type RoleAssignmentScheduleInstancesClientListForScopeResponse struct { + // Role assignment schedule instance list operation result. + RoleAssignmentScheduleInstanceListResult +} + +// RoleAssignmentScheduleRequestsClientCancelResponse contains the response from method RoleAssignmentScheduleRequestsClient.Cancel. +type RoleAssignmentScheduleRequestsClientCancelResponse struct { + // placeholder for future response values +} + +// RoleAssignmentScheduleRequestsClientCreateResponse contains the response from method RoleAssignmentScheduleRequestsClient.Create. +type RoleAssignmentScheduleRequestsClientCreateResponse struct { + // Role Assignment schedule request + RoleAssignmentScheduleRequest +} + +// RoleAssignmentScheduleRequestsClientGetResponse contains the response from method RoleAssignmentScheduleRequestsClient.Get. +type RoleAssignmentScheduleRequestsClientGetResponse struct { + // Role Assignment schedule request + RoleAssignmentScheduleRequest +} + +// RoleAssignmentScheduleRequestsClientListForScopeResponse contains the response from method RoleAssignmentScheduleRequestsClient.NewListForScopePager. +type RoleAssignmentScheduleRequestsClientListForScopeResponse struct { + // Role assignment schedule request list operation result. + RoleAssignmentScheduleRequestListResult +} + +// RoleAssignmentScheduleRequestsClientValidateResponse contains the response from method RoleAssignmentScheduleRequestsClient.Validate. +type RoleAssignmentScheduleRequestsClientValidateResponse struct { + // Role Assignment schedule request + RoleAssignmentScheduleRequest +} + +// RoleAssignmentSchedulesClientGetResponse contains the response from method RoleAssignmentSchedulesClient.Get. +type RoleAssignmentSchedulesClientGetResponse struct { + // Role Assignment schedule + RoleAssignmentSchedule +} + +// RoleAssignmentSchedulesClientListForScopeResponse contains the response from method RoleAssignmentSchedulesClient.NewListForScopePager. +type RoleAssignmentSchedulesClientListForScopeResponse struct { + // Role assignment schedule list operation result. + RoleAssignmentScheduleListResult +} + +// RoleAssignmentsClientCreateByIDResponse contains the response from method RoleAssignmentsClient.CreateByID. +type RoleAssignmentsClientCreateByIDResponse struct { + // Role Assignments + RoleAssignment +} + +// RoleAssignmentsClientCreateResponse contains the response from method RoleAssignmentsClient.Create. +type RoleAssignmentsClientCreateResponse struct { + // Role Assignments + RoleAssignment +} + +// RoleAssignmentsClientDeleteByIDResponse contains the response from method RoleAssignmentsClient.DeleteByID. +type RoleAssignmentsClientDeleteByIDResponse struct { + // Role Assignments + RoleAssignment +} + +// RoleAssignmentsClientDeleteResponse contains the response from method RoleAssignmentsClient.Delete. +type RoleAssignmentsClientDeleteResponse struct { + // Role Assignments + RoleAssignment +} + +// RoleAssignmentsClientGetByIDResponse contains the response from method RoleAssignmentsClient.GetByID. +type RoleAssignmentsClientGetByIDResponse struct { + // Role Assignments + RoleAssignment +} + +// RoleAssignmentsClientGetResponse contains the response from method RoleAssignmentsClient.Get. +type RoleAssignmentsClientGetResponse struct { + // Role Assignments + RoleAssignment +} + +// RoleAssignmentsClientListForResourceGroupResponse contains the response from method RoleAssignmentsClient.NewListForResourceGroupPager. +type RoleAssignmentsClientListForResourceGroupResponse struct { + // Role assignment list operation result. + RoleAssignmentListResult +} + +// RoleAssignmentsClientListForResourceResponse contains the response from method RoleAssignmentsClient.NewListForResourcePager. +type RoleAssignmentsClientListForResourceResponse struct { + // Role assignment list operation result. + RoleAssignmentListResult +} + +// RoleAssignmentsClientListForScopeResponse contains the response from method RoleAssignmentsClient.NewListForScopePager. +type RoleAssignmentsClientListForScopeResponse struct { + // Role assignment list operation result. + RoleAssignmentListResult +} + +// RoleAssignmentsClientListForSubscriptionResponse contains the response from method RoleAssignmentsClient.NewListForSubscriptionPager. +type RoleAssignmentsClientListForSubscriptionResponse struct { + // Role assignment list operation result. + RoleAssignmentListResult +} + +// RoleDefinitionsClientCreateOrUpdateResponse contains the response from method RoleDefinitionsClient.CreateOrUpdate. +type RoleDefinitionsClientCreateOrUpdateResponse struct { + // Role definition. + RoleDefinition +} + +// RoleDefinitionsClientDeleteResponse contains the response from method RoleDefinitionsClient.Delete. +type RoleDefinitionsClientDeleteResponse struct { + // Role definition. + RoleDefinition +} + +// RoleDefinitionsClientGetByIDResponse contains the response from method RoleDefinitionsClient.GetByID. +type RoleDefinitionsClientGetByIDResponse struct { + // Role definition. + RoleDefinition +} + +// RoleDefinitionsClientGetResponse contains the response from method RoleDefinitionsClient.Get. +type RoleDefinitionsClientGetResponse struct { + // Role definition. + RoleDefinition +} + +// RoleDefinitionsClientListResponse contains the response from method RoleDefinitionsClient.NewListPager. +type RoleDefinitionsClientListResponse struct { + // Role definition list operation result. + RoleDefinitionListResult +} + +// RoleEligibilityScheduleInstancesClientGetResponse contains the response from method RoleEligibilityScheduleInstancesClient.Get. +type RoleEligibilityScheduleInstancesClientGetResponse struct { + // Information about current or upcoming role eligibility schedule instance + RoleEligibilityScheduleInstance +} + +// RoleEligibilityScheduleInstancesClientListForScopeResponse contains the response from method RoleEligibilityScheduleInstancesClient.NewListForScopePager. +type RoleEligibilityScheduleInstancesClientListForScopeResponse struct { + // Role eligibility schedule instance list operation result. + RoleEligibilityScheduleInstanceListResult +} + +// RoleEligibilityScheduleRequestsClientCancelResponse contains the response from method RoleEligibilityScheduleRequestsClient.Cancel. +type RoleEligibilityScheduleRequestsClientCancelResponse struct { + // placeholder for future response values +} + +// RoleEligibilityScheduleRequestsClientCreateResponse contains the response from method RoleEligibilityScheduleRequestsClient.Create. +type RoleEligibilityScheduleRequestsClientCreateResponse struct { + // Role Eligibility schedule request + RoleEligibilityScheduleRequest +} + +// RoleEligibilityScheduleRequestsClientGetResponse contains the response from method RoleEligibilityScheduleRequestsClient.Get. +type RoleEligibilityScheduleRequestsClientGetResponse struct { + // Role Eligibility schedule request + RoleEligibilityScheduleRequest +} + +// RoleEligibilityScheduleRequestsClientListForScopeResponse contains the response from method RoleEligibilityScheduleRequestsClient.NewListForScopePager. +type RoleEligibilityScheduleRequestsClientListForScopeResponse struct { + // Role eligibility schedule request list operation result. + RoleEligibilityScheduleRequestListResult +} + +// RoleEligibilityScheduleRequestsClientValidateResponse contains the response from method RoleEligibilityScheduleRequestsClient.Validate. +type RoleEligibilityScheduleRequestsClientValidateResponse struct { + // Role Eligibility schedule request + RoleEligibilityScheduleRequest +} + +// RoleEligibilitySchedulesClientGetResponse contains the response from method RoleEligibilitySchedulesClient.Get. +type RoleEligibilitySchedulesClientGetResponse struct { + // Role eligibility schedule + RoleEligibilitySchedule +} + +// RoleEligibilitySchedulesClientListForScopeResponse contains the response from method RoleEligibilitySchedulesClient.NewListForScopePager. +type RoleEligibilitySchedulesClientListForScopeResponse struct { + // role eligibility schedule list operation result. + RoleEligibilityScheduleListResult +} + +// RoleManagementPoliciesClientDeleteResponse contains the response from method RoleManagementPoliciesClient.Delete. +type RoleManagementPoliciesClientDeleteResponse struct { + // placeholder for future response values +} + +// RoleManagementPoliciesClientGetResponse contains the response from method RoleManagementPoliciesClient.Get. +type RoleManagementPoliciesClientGetResponse struct { + // Role management policy + RoleManagementPolicy +} + +// RoleManagementPoliciesClientListForScopeResponse contains the response from method RoleManagementPoliciesClient.NewListForScopePager. +type RoleManagementPoliciesClientListForScopeResponse struct { + // Role management policy list operation result. + RoleManagementPolicyListResult +} + +// RoleManagementPoliciesClientUpdateResponse contains the response from method RoleManagementPoliciesClient.Update. +type RoleManagementPoliciesClientUpdateResponse struct { + // Role management policy + RoleManagementPolicy +} + +// RoleManagementPolicyAssignmentsClientCreateResponse contains the response from method RoleManagementPolicyAssignmentsClient.Create. +type RoleManagementPolicyAssignmentsClientCreateResponse struct { + // Role management policy + RoleManagementPolicyAssignment +} + +// RoleManagementPolicyAssignmentsClientDeleteResponse contains the response from method RoleManagementPolicyAssignmentsClient.Delete. +type RoleManagementPolicyAssignmentsClientDeleteResponse struct { + // placeholder for future response values +} + +// RoleManagementPolicyAssignmentsClientGetResponse contains the response from method RoleManagementPolicyAssignmentsClient.Get. +type RoleManagementPolicyAssignmentsClientGetResponse struct { + // Role management policy + RoleManagementPolicyAssignment +} + +// RoleManagementPolicyAssignmentsClientListForScopeResponse contains the response from method RoleManagementPolicyAssignmentsClient.NewListForScopePager. +type RoleManagementPolicyAssignmentsClientListForScopeResponse struct { + // Role management policy assignment list operation result. + RoleManagementPolicyAssignmentListResult +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignments_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignments_client.go new file mode 100644 index 000000000..808b83f0a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignments_client.go @@ -0,0 +1,671 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleAssignmentsClient contains the methods for the RoleAssignments group. +// Don't use this type directly, use NewRoleAssignmentsClient() instead. +type RoleAssignmentsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewRoleAssignmentsClient creates a new instance of RoleAssignmentsClient with the specified values. +// - subscriptionID - The ID of the target subscription. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleAssignmentsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleAssignmentsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// Create - Create or update a role assignment by scope and name. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the operation or resource. Valid scopes are: subscription (format: '/subscriptions/{subscriptionId}'), +// resource group (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}' +// - roleAssignmentName - The name of the role assignment. It can be any valid GUID. +// - parameters - Parameters for the role assignment. +// - options - RoleAssignmentsClientCreateOptions contains the optional parameters for the RoleAssignmentsClient.Create method. +func (client *RoleAssignmentsClient) Create(ctx context.Context, scope string, roleAssignmentName string, parameters RoleAssignmentCreateParameters, options *RoleAssignmentsClientCreateOptions) (RoleAssignmentsClientCreateResponse, error) { + var err error + const operationName = "RoleAssignmentsClient.Create" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createCreateRequest(ctx, scope, roleAssignmentName, parameters, options) + if err != nil { + return RoleAssignmentsClientCreateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentsClientCreateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentsClientCreateResponse{}, err + } + resp, err := client.createHandleResponse(httpResp) + return resp, err +} + +// createCreateRequest creates the Create request. +func (client *RoleAssignmentsClient) createCreateRequest(ctx context.Context, scope string, roleAssignmentName string, parameters RoleAssignmentCreateParameters, options *RoleAssignmentsClientCreateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentName}", roleAssignmentName) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createHandleResponse handles the Create response. +func (client *RoleAssignmentsClient) createHandleResponse(resp *http.Response) (RoleAssignmentsClientCreateResponse, error) { + result := RoleAssignmentsClientCreateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignment); err != nil { + return RoleAssignmentsClientCreateResponse{}, err + } + return result, nil +} + +// CreateByID - Create or update a role assignment by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - roleAssignmentID - The fully qualified ID of the role assignment including scope, resource name, and resource type. Format: +// /{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}. Example: +// /subscriptions//resourcegroups//providers/Microsoft.Authorization/roleAssignments/ +// - parameters - Parameters for the role assignment. +// - options - RoleAssignmentsClientCreateByIDOptions contains the optional parameters for the RoleAssignmentsClient.CreateByID +// method. +func (client *RoleAssignmentsClient) CreateByID(ctx context.Context, roleAssignmentID string, parameters RoleAssignmentCreateParameters, options *RoleAssignmentsClientCreateByIDOptions) (RoleAssignmentsClientCreateByIDResponse, error) { + var err error + const operationName = "RoleAssignmentsClient.CreateByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createByIDCreateRequest(ctx, roleAssignmentID, parameters, options) + if err != nil { + return RoleAssignmentsClientCreateByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentsClientCreateByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentsClientCreateByIDResponse{}, err + } + resp, err := client.createByIDHandleResponse(httpResp) + return resp, err +} + +// createByIDCreateRequest creates the CreateByID request. +func (client *RoleAssignmentsClient) createByIDCreateRequest(ctx context.Context, roleAssignmentID string, parameters RoleAssignmentCreateParameters, options *RoleAssignmentsClientCreateByIDOptions) (*policy.Request, error) { + urlPath := "/{roleAssignmentId}" + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentId}", roleAssignmentID) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createByIDHandleResponse handles the CreateByID response. +func (client *RoleAssignmentsClient) createByIDHandleResponse(resp *http.Response) (RoleAssignmentsClientCreateByIDResponse, error) { + result := RoleAssignmentsClientCreateByIDResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignment); err != nil { + return RoleAssignmentsClientCreateByIDResponse{}, err + } + return result, nil +} + +// Delete - Delete a role assignment by scope and name. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the operation or resource. Valid scopes are: subscription (format: '/subscriptions/{subscriptionId}'), +// resource group (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}' +// - roleAssignmentName - The name of the role assignment. It can be any valid GUID. +// - options - RoleAssignmentsClientDeleteOptions contains the optional parameters for the RoleAssignmentsClient.Delete method. +func (client *RoleAssignmentsClient) Delete(ctx context.Context, scope string, roleAssignmentName string, options *RoleAssignmentsClientDeleteOptions) (RoleAssignmentsClientDeleteResponse, error) { + var err error + const operationName = "RoleAssignmentsClient.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, scope, roleAssignmentName, options) + if err != nil { + return RoleAssignmentsClientDeleteResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentsClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentsClientDeleteResponse{}, err + } + resp, err := client.deleteHandleResponse(httpResp) + return resp, err +} + +// deleteCreateRequest creates the Delete request. +func (client *RoleAssignmentsClient) deleteCreateRequest(ctx context.Context, scope string, roleAssignmentName string, options *RoleAssignmentsClientDeleteOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentName}", roleAssignmentName) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// deleteHandleResponse handles the Delete response. +func (client *RoleAssignmentsClient) deleteHandleResponse(resp *http.Response) (RoleAssignmentsClientDeleteResponse, error) { + result := RoleAssignmentsClientDeleteResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignment); err != nil { + return RoleAssignmentsClientDeleteResponse{}, err + } + return result, nil +} + +// DeleteByID - Delete a role assignment by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - roleAssignmentID - The fully qualified ID of the role assignment including scope, resource name, and resource type. Format: +// /{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}. Example: +// /subscriptions//resourcegroups//providers/Microsoft.Authorization/roleAssignments/ +// - options - RoleAssignmentsClientDeleteByIDOptions contains the optional parameters for the RoleAssignmentsClient.DeleteByID +// method. +func (client *RoleAssignmentsClient) DeleteByID(ctx context.Context, roleAssignmentID string, options *RoleAssignmentsClientDeleteByIDOptions) (RoleAssignmentsClientDeleteByIDResponse, error) { + var err error + const operationName = "RoleAssignmentsClient.DeleteByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteByIDCreateRequest(ctx, roleAssignmentID, options) + if err != nil { + return RoleAssignmentsClientDeleteByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentsClientDeleteByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentsClientDeleteByIDResponse{}, err + } + resp, err := client.deleteByIDHandleResponse(httpResp) + return resp, err +} + +// deleteByIDCreateRequest creates the DeleteByID request. +func (client *RoleAssignmentsClient) deleteByIDCreateRequest(ctx context.Context, roleAssignmentID string, options *RoleAssignmentsClientDeleteByIDOptions) (*policy.Request, error) { + urlPath := "/{roleAssignmentId}" + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentId}", roleAssignmentID) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// deleteByIDHandleResponse handles the DeleteByID response. +func (client *RoleAssignmentsClient) deleteByIDHandleResponse(resp *http.Response) (RoleAssignmentsClientDeleteByIDResponse, error) { + result := RoleAssignmentsClientDeleteByIDResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignment); err != nil { + return RoleAssignmentsClientDeleteByIDResponse{}, err + } + return result, nil +} + +// Get - Get a role assignment by scope and name. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the operation or resource. Valid scopes are: subscription (format: '/subscriptions/{subscriptionId}'), +// resource group (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}' +// - roleAssignmentName - The name of the role assignment. It can be any valid GUID. +// - options - RoleAssignmentsClientGetOptions contains the optional parameters for the RoleAssignmentsClient.Get method. +func (client *RoleAssignmentsClient) Get(ctx context.Context, scope string, roleAssignmentName string, options *RoleAssignmentsClientGetOptions) (RoleAssignmentsClientGetResponse, error) { + var err error + const operationName = "RoleAssignmentsClient.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, scope, roleAssignmentName, options) + if err != nil { + return RoleAssignmentsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleAssignmentsClient) getCreateRequest(ctx context.Context, scope string, roleAssignmentName string, options *RoleAssignmentsClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentName}", roleAssignmentName) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleAssignmentsClient) getHandleResponse(resp *http.Response) (RoleAssignmentsClientGetResponse, error) { + result := RoleAssignmentsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignment); err != nil { + return RoleAssignmentsClientGetResponse{}, err + } + return result, nil +} + +// GetByID - Get a role assignment by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - roleAssignmentID - The fully qualified ID of the role assignment including scope, resource name, and resource type. Format: +// /{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}. Example: +// /subscriptions//resourcegroups//providers/Microsoft.Authorization/roleAssignments/ +// - options - RoleAssignmentsClientGetByIDOptions contains the optional parameters for the RoleAssignmentsClient.GetByID method. +func (client *RoleAssignmentsClient) GetByID(ctx context.Context, roleAssignmentID string, options *RoleAssignmentsClientGetByIDOptions) (RoleAssignmentsClientGetByIDResponse, error) { + var err error + const operationName = "RoleAssignmentsClient.GetByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getByIDCreateRequest(ctx, roleAssignmentID, options) + if err != nil { + return RoleAssignmentsClientGetByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentsClientGetByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentsClientGetByIDResponse{}, err + } + resp, err := client.getByIDHandleResponse(httpResp) + return resp, err +} + +// getByIDCreateRequest creates the GetByID request. +func (client *RoleAssignmentsClient) getByIDCreateRequest(ctx context.Context, roleAssignmentID string, options *RoleAssignmentsClientGetByIDOptions) (*policy.Request, error) { + urlPath := "/{roleAssignmentId}" + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentId}", roleAssignmentID) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getByIDHandleResponse handles the GetByID response. +func (client *RoleAssignmentsClient) getByIDHandleResponse(resp *http.Response) (RoleAssignmentsClientGetByIDResponse, error) { + result := RoleAssignmentsClientGetByIDResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignment); err != nil { + return RoleAssignmentsClientGetByIDResponse{}, err + } + return result, nil +} + +// NewListForResourcePager - List all role assignments that apply to a resource. +// +// Generated from API version 2022-04-01 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - resourceType - The resource type name. For example the type name of a web app is 'sites' (from Microsoft.Web/sites). +// - resourceName - The resource name. +// - options - RoleAssignmentsClientListForResourceOptions contains the optional parameters for the RoleAssignmentsClient.NewListForResourcePager +// method. +func (client *RoleAssignmentsClient) NewListForResourcePager(resourceGroupName string, resourceProviderNamespace string, resourceType string, resourceName string, options *RoleAssignmentsClientListForResourceOptions) *runtime.Pager[RoleAssignmentsClientListForResourceResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentsClientListForResourceResponse]{ + More: func(page RoleAssignmentsClientListForResourceResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentsClientListForResourceResponse) (RoleAssignmentsClientListForResourceResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentsClient.NewListForResourcePager") + 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.listForResourceCreateRequest(ctx, resourceGroupName, resourceProviderNamespace, resourceType, resourceName, options) + }, nil) + if err != nil { + return RoleAssignmentsClientListForResourceResponse{}, err + } + return client.listForResourceHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForResourceCreateRequest creates the ListForResource request. +func (client *RoleAssignmentsClient) listForResourceCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, resourceType string, resourceName string, options *RoleAssignmentsClientListForResourceOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}/providers/Microsoft.Authorization/roleAssignments" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", resourceProviderNamespace) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", resourceName) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + unencodedParams := []string{req.Raw().URL.RawQuery} + if options != nil && options.Filter != nil { + unencodedParams = append(unencodedParams, "$filter="+*options.Filter) + } + req.Raw().URL.RawQuery = strings.Join(unencodedParams, "&") + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForResourceHandleResponse handles the ListForResource response. +func (client *RoleAssignmentsClient) listForResourceHandleResponse(resp *http.Response) (RoleAssignmentsClientListForResourceResponse, error) { + result := RoleAssignmentsClientListForResourceResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentListResult); err != nil { + return RoleAssignmentsClientListForResourceResponse{}, err + } + return result, nil +} + +// NewListForResourceGroupPager - List all role assignments that apply to a resource group. +// +// Generated from API version 2022-04-01 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - options - RoleAssignmentsClientListForResourceGroupOptions contains the optional parameters for the RoleAssignmentsClient.NewListForResourceGroupPager +// method. +func (client *RoleAssignmentsClient) NewListForResourceGroupPager(resourceGroupName string, options *RoleAssignmentsClientListForResourceGroupOptions) *runtime.Pager[RoleAssignmentsClientListForResourceGroupResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentsClientListForResourceGroupResponse]{ + More: func(page RoleAssignmentsClientListForResourceGroupResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentsClientListForResourceGroupResponse) (RoleAssignmentsClientListForResourceGroupResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentsClient.NewListForResourceGroupPager") + 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.listForResourceGroupCreateRequest(ctx, resourceGroupName, options) + }, nil) + if err != nil { + return RoleAssignmentsClientListForResourceGroupResponse{}, err + } + return client.listForResourceGroupHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForResourceGroupCreateRequest creates the ListForResourceGroup request. +func (client *RoleAssignmentsClient) listForResourceGroupCreateRequest(ctx context.Context, resourceGroupName string, options *RoleAssignmentsClientListForResourceGroupOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Authorization/roleAssignments" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + unencodedParams := []string{req.Raw().URL.RawQuery} + if options != nil && options.Filter != nil { + unencodedParams = append(unencodedParams, "$filter="+*options.Filter) + } + req.Raw().URL.RawQuery = strings.Join(unencodedParams, "&") + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForResourceGroupHandleResponse handles the ListForResourceGroup response. +func (client *RoleAssignmentsClient) listForResourceGroupHandleResponse(resp *http.Response) (RoleAssignmentsClientListForResourceGroupResponse, error) { + result := RoleAssignmentsClientListForResourceGroupResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentListResult); err != nil { + return RoleAssignmentsClientListForResourceGroupResponse{}, err + } + return result, nil +} + +// NewListForScopePager - List all role assignments that apply to a scope. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the operation or resource. Valid scopes are: subscription (format: '/subscriptions/{subscriptionId}'), +// resource group (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format: +// '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}' +// - options - RoleAssignmentsClientListForScopeOptions contains the optional parameters for the RoleAssignmentsClient.NewListForScopePager +// method. +func (client *RoleAssignmentsClient) NewListForScopePager(scope string, options *RoleAssignmentsClientListForScopeOptions) *runtime.Pager[RoleAssignmentsClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentsClientListForScopeResponse]{ + More: func(page RoleAssignmentsClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentsClientListForScopeResponse) (RoleAssignmentsClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentsClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleAssignmentsClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleAssignmentsClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleAssignmentsClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignments" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + unencodedParams := []string{req.Raw().URL.RawQuery} + if options != nil && options.Filter != nil { + unencodedParams = append(unencodedParams, "$filter="+*options.Filter) + } + if options != nil && options.SkipToken != nil { + unencodedParams = append(unencodedParams, "$skipToken="+*options.SkipToken) + } + req.Raw().URL.RawQuery = strings.Join(unencodedParams, "&") + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleAssignmentsClient) listForScopeHandleResponse(resp *http.Response) (RoleAssignmentsClientListForScopeResponse, error) { + result := RoleAssignmentsClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentListResult); err != nil { + return RoleAssignmentsClientListForScopeResponse{}, err + } + return result, nil +} + +// NewListForSubscriptionPager - List all role assignments that apply to a subscription. +// +// Generated from API version 2022-04-01 +// - options - RoleAssignmentsClientListForSubscriptionOptions contains the optional parameters for the RoleAssignmentsClient.NewListForSubscriptionPager +// method. +func (client *RoleAssignmentsClient) NewListForSubscriptionPager(options *RoleAssignmentsClientListForSubscriptionOptions) *runtime.Pager[RoleAssignmentsClientListForSubscriptionResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentsClientListForSubscriptionResponse]{ + More: func(page RoleAssignmentsClientListForSubscriptionResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentsClientListForSubscriptionResponse) (RoleAssignmentsClientListForSubscriptionResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentsClient.NewListForSubscriptionPager") + 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.listForSubscriptionCreateRequest(ctx, options) + }, nil) + if err != nil { + return RoleAssignmentsClientListForSubscriptionResponse{}, err + } + return client.listForSubscriptionHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForSubscriptionCreateRequest creates the ListForSubscription request. +func (client *RoleAssignmentsClient) listForSubscriptionCreateRequest(ctx context.Context, options *RoleAssignmentsClientListForSubscriptionOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleAssignments" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + if options != nil && options.TenantID != nil { + reqQP.Set("tenantId", *options.TenantID) + } + req.Raw().URL.RawQuery = reqQP.Encode() + unencodedParams := []string{req.Raw().URL.RawQuery} + if options != nil && options.Filter != nil { + unencodedParams = append(unencodedParams, "$filter="+*options.Filter) + } + req.Raw().URL.RawQuery = strings.Join(unencodedParams, "&") + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForSubscriptionHandleResponse handles the ListForSubscription response. +func (client *RoleAssignmentsClient) listForSubscriptionHandleResponse(resp *http.Response) (RoleAssignmentsClientListForSubscriptionResponse, error) { + result := RoleAssignmentsClientListForSubscriptionResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentListResult); err != nil { + return RoleAssignmentsClientListForSubscriptionResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentscheduleinstances_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentscheduleinstances_client.go new file mode 100644 index 000000000..3134e6723 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentscheduleinstances_client.go @@ -0,0 +1,155 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleAssignmentScheduleInstancesClient contains the methods for the RoleAssignmentScheduleInstances group. +// Don't use this type directly, use NewRoleAssignmentScheduleInstancesClient() instead. +type RoleAssignmentScheduleInstancesClient struct { + internal *arm.Client +} + +// NewRoleAssignmentScheduleInstancesClient creates a new instance of RoleAssignmentScheduleInstancesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleAssignmentScheduleInstancesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentScheduleInstancesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleAssignmentScheduleInstancesClient{ + internal: cl, + } + return client, nil +} + +// Get - Gets the specified role assignment schedule instance. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignments schedules. +// - roleAssignmentScheduleInstanceName - The name (hash of schedule name + time) of the role assignment schedule to get. +// - options - RoleAssignmentScheduleInstancesClientGetOptions contains the optional parameters for the RoleAssignmentScheduleInstancesClient.Get +// method. +func (client *RoleAssignmentScheduleInstancesClient) Get(ctx context.Context, scope string, roleAssignmentScheduleInstanceName string, options *RoleAssignmentScheduleInstancesClientGetOptions) (RoleAssignmentScheduleInstancesClientGetResponse, error) { + var err error + const operationName = "RoleAssignmentScheduleInstancesClient.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, scope, roleAssignmentScheduleInstanceName, options) + if err != nil { + return RoleAssignmentScheduleInstancesClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentScheduleInstancesClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentScheduleInstancesClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleAssignmentScheduleInstancesClient) getCreateRequest(ctx context.Context, scope string, roleAssignmentScheduleInstanceName string, options *RoleAssignmentScheduleInstancesClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleInstances/{roleAssignmentScheduleInstanceName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleAssignmentScheduleInstanceName == "" { + return nil, errors.New("parameter roleAssignmentScheduleInstanceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentScheduleInstanceName}", url.PathEscape(roleAssignmentScheduleInstanceName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleAssignmentScheduleInstancesClient) getHandleResponse(resp *http.Response) (RoleAssignmentScheduleInstancesClientGetResponse, error) { + result := RoleAssignmentScheduleInstancesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleInstance); err != nil { + return RoleAssignmentScheduleInstancesClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role assignment schedule instances of a role assignment schedule. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignment schedule. +// - options - RoleAssignmentScheduleInstancesClientListForScopeOptions contains the optional parameters for the RoleAssignmentScheduleInstancesClient.NewListForScopePager +// method. +func (client *RoleAssignmentScheduleInstancesClient) NewListForScopePager(scope string, options *RoleAssignmentScheduleInstancesClientListForScopeOptions) *runtime.Pager[RoleAssignmentScheduleInstancesClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentScheduleInstancesClientListForScopeResponse]{ + More: func(page RoleAssignmentScheduleInstancesClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentScheduleInstancesClientListForScopeResponse) (RoleAssignmentScheduleInstancesClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentScheduleInstancesClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleAssignmentScheduleInstancesClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleAssignmentScheduleInstancesClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleAssignmentScheduleInstancesClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleInstances" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleAssignmentScheduleInstancesClient) listForScopeHandleResponse(resp *http.Response) (RoleAssignmentScheduleInstancesClientListForScopeResponse, error) { + result := RoleAssignmentScheduleInstancesClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleInstanceListResult); err != nil { + return RoleAssignmentScheduleInstancesClientListForScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentschedulerequests_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentschedulerequests_client.go new file mode 100644 index 000000000..660672016 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentschedulerequests_client.go @@ -0,0 +1,332 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleAssignmentScheduleRequestsClient contains the methods for the RoleAssignmentScheduleRequests group. +// Don't use this type directly, use NewRoleAssignmentScheduleRequestsClient() instead. +type RoleAssignmentScheduleRequestsClient struct { + internal *arm.Client +} + +// NewRoleAssignmentScheduleRequestsClient creates a new instance of RoleAssignmentScheduleRequestsClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleAssignmentScheduleRequestsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentScheduleRequestsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleAssignmentScheduleRequestsClient{ + internal: cl, + } + return client, nil +} + +// Cancel - Cancels a pending role assignment schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignment request to cancel. +// - roleAssignmentScheduleRequestName - The name of the role assignment request to cancel. +// - options - RoleAssignmentScheduleRequestsClientCancelOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Cancel +// method. +func (client *RoleAssignmentScheduleRequestsClient) Cancel(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, options *RoleAssignmentScheduleRequestsClientCancelOptions) (RoleAssignmentScheduleRequestsClientCancelResponse, error) { + var err error + const operationName = "RoleAssignmentScheduleRequestsClient.Cancel" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelCreateRequest(ctx, scope, roleAssignmentScheduleRequestName, options) + if err != nil { + return RoleAssignmentScheduleRequestsClientCancelResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentScheduleRequestsClientCancelResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentScheduleRequestsClientCancelResponse{}, err + } + return RoleAssignmentScheduleRequestsClientCancelResponse{}, nil +} + +// cancelCreateRequest creates the Cancel request. +func (client *RoleAssignmentScheduleRequestsClient) cancelCreateRequest(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, options *RoleAssignmentScheduleRequestsClientCancelOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/{roleAssignmentScheduleRequestName}/cancel" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleAssignmentScheduleRequestName == "" { + return nil, errors.New("parameter roleAssignmentScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentScheduleRequestName}", url.PathEscape(roleAssignmentScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Create - Creates a role assignment schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignment schedule request to create. The scope can be any REST resource instance. For example, +// use '/subscriptions/{subscription-id}/' for a subscription, +// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}' for a resource group, and +// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}' +// for a resource. +// - roleAssignmentScheduleRequestName - A GUID for the role assignment to create. The name must be unique and different for +// each role assignment. +// - parameters - Parameters for the role assignment schedule request. +// - options - RoleAssignmentScheduleRequestsClientCreateOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Create +// method. +func (client *RoleAssignmentScheduleRequestsClient) Create(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, parameters RoleAssignmentScheduleRequest, options *RoleAssignmentScheduleRequestsClientCreateOptions) (RoleAssignmentScheduleRequestsClientCreateResponse, error) { + var err error + const operationName = "RoleAssignmentScheduleRequestsClient.Create" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createCreateRequest(ctx, scope, roleAssignmentScheduleRequestName, parameters, options) + if err != nil { + return RoleAssignmentScheduleRequestsClientCreateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentScheduleRequestsClientCreateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentScheduleRequestsClientCreateResponse{}, err + } + resp, err := client.createHandleResponse(httpResp) + return resp, err +} + +// createCreateRequest creates the Create request. +func (client *RoleAssignmentScheduleRequestsClient) createCreateRequest(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, parameters RoleAssignmentScheduleRequest, options *RoleAssignmentScheduleRequestsClientCreateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/{roleAssignmentScheduleRequestName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleAssignmentScheduleRequestName == "" { + return nil, errors.New("parameter roleAssignmentScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentScheduleRequestName}", url.PathEscape(roleAssignmentScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createHandleResponse handles the Create response. +func (client *RoleAssignmentScheduleRequestsClient) createHandleResponse(resp *http.Response) (RoleAssignmentScheduleRequestsClientCreateResponse, error) { + result := RoleAssignmentScheduleRequestsClientCreateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleRequest); err != nil { + return RoleAssignmentScheduleRequestsClientCreateResponse{}, err + } + return result, nil +} + +// Get - Get the specified role assignment schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignment schedule request. +// - roleAssignmentScheduleRequestName - The name (guid) of the role assignment schedule request to get. +// - options - RoleAssignmentScheduleRequestsClientGetOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Get +// method. +func (client *RoleAssignmentScheduleRequestsClient) Get(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, options *RoleAssignmentScheduleRequestsClientGetOptions) (RoleAssignmentScheduleRequestsClientGetResponse, error) { + var err error + const operationName = "RoleAssignmentScheduleRequestsClient.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, scope, roleAssignmentScheduleRequestName, options) + if err != nil { + return RoleAssignmentScheduleRequestsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentScheduleRequestsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentScheduleRequestsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleAssignmentScheduleRequestsClient) getCreateRequest(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, options *RoleAssignmentScheduleRequestsClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/{roleAssignmentScheduleRequestName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleAssignmentScheduleRequestName == "" { + return nil, errors.New("parameter roleAssignmentScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentScheduleRequestName}", url.PathEscape(roleAssignmentScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleAssignmentScheduleRequestsClient) getHandleResponse(resp *http.Response) (RoleAssignmentScheduleRequestsClientGetResponse, error) { + result := RoleAssignmentScheduleRequestsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleRequest); err != nil { + return RoleAssignmentScheduleRequestsClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role assignment schedule requests for a scope. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignments schedule requests. +// - options - RoleAssignmentScheduleRequestsClientListForScopeOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.NewListForScopePager +// method. +func (client *RoleAssignmentScheduleRequestsClient) NewListForScopePager(scope string, options *RoleAssignmentScheduleRequestsClientListForScopeOptions) *runtime.Pager[RoleAssignmentScheduleRequestsClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentScheduleRequestsClientListForScopeResponse]{ + More: func(page RoleAssignmentScheduleRequestsClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentScheduleRequestsClientListForScopeResponse) (RoleAssignmentScheduleRequestsClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentScheduleRequestsClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleAssignmentScheduleRequestsClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleAssignmentScheduleRequestsClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleAssignmentScheduleRequestsClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleRequests" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleAssignmentScheduleRequestsClient) listForScopeHandleResponse(resp *http.Response) (RoleAssignmentScheduleRequestsClientListForScopeResponse, error) { + result := RoleAssignmentScheduleRequestsClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleRequestListResult); err != nil { + return RoleAssignmentScheduleRequestsClientListForScopeResponse{}, err + } + return result, nil +} + +// Validate - Validates a new role assignment schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignment request to validate. +// - roleAssignmentScheduleRequestName - The name of the role assignment request to validate. +// - parameters - Parameters for the role assignment schedule request. +// - options - RoleAssignmentScheduleRequestsClientValidateOptions contains the optional parameters for the RoleAssignmentScheduleRequestsClient.Validate +// method. +func (client *RoleAssignmentScheduleRequestsClient) Validate(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, parameters RoleAssignmentScheduleRequest, options *RoleAssignmentScheduleRequestsClientValidateOptions) (RoleAssignmentScheduleRequestsClientValidateResponse, error) { + var err error + const operationName = "RoleAssignmentScheduleRequestsClient.Validate" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateCreateRequest(ctx, scope, roleAssignmentScheduleRequestName, parameters, options) + if err != nil { + return RoleAssignmentScheduleRequestsClientValidateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentScheduleRequestsClientValidateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentScheduleRequestsClientValidateResponse{}, err + } + resp, err := client.validateHandleResponse(httpResp) + return resp, err +} + +// validateCreateRequest creates the Validate request. +func (client *RoleAssignmentScheduleRequestsClient) validateCreateRequest(ctx context.Context, scope string, roleAssignmentScheduleRequestName string, parameters RoleAssignmentScheduleRequest, options *RoleAssignmentScheduleRequestsClientValidateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentScheduleRequests/{roleAssignmentScheduleRequestName}/validate" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleAssignmentScheduleRequestName == "" { + return nil, errors.New("parameter roleAssignmentScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentScheduleRequestName}", url.PathEscape(roleAssignmentScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// validateHandleResponse handles the Validate response. +func (client *RoleAssignmentScheduleRequestsClient) validateHandleResponse(resp *http.Response) (RoleAssignmentScheduleRequestsClientValidateResponse, error) { + result := RoleAssignmentScheduleRequestsClientValidateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleRequest); err != nil { + return RoleAssignmentScheduleRequestsClientValidateResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentschedules_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentschedules_client.go new file mode 100644 index 000000000..3788a52a6 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleassignmentschedules_client.go @@ -0,0 +1,155 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleAssignmentSchedulesClient contains the methods for the RoleAssignmentSchedules group. +// Don't use this type directly, use NewRoleAssignmentSchedulesClient() instead. +type RoleAssignmentSchedulesClient struct { + internal *arm.Client +} + +// NewRoleAssignmentSchedulesClient creates a new instance of RoleAssignmentSchedulesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleAssignmentSchedulesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentSchedulesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleAssignmentSchedulesClient{ + internal: cl, + } + return client, nil +} + +// Get - Get the specified role assignment schedule for a resource scope +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignment schedule. +// - roleAssignmentScheduleName - The name (guid) of the role assignment schedule to get. +// - options - RoleAssignmentSchedulesClientGetOptions contains the optional parameters for the RoleAssignmentSchedulesClient.Get +// method. +func (client *RoleAssignmentSchedulesClient) Get(ctx context.Context, scope string, roleAssignmentScheduleName string, options *RoleAssignmentSchedulesClientGetOptions) (RoleAssignmentSchedulesClientGetResponse, error) { + var err error + const operationName = "RoleAssignmentSchedulesClient.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, scope, roleAssignmentScheduleName, options) + if err != nil { + return RoleAssignmentSchedulesClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleAssignmentSchedulesClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleAssignmentSchedulesClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleAssignmentSchedulesClient) getCreateRequest(ctx context.Context, scope string, roleAssignmentScheduleName string, options *RoleAssignmentSchedulesClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentSchedules/{roleAssignmentScheduleName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleAssignmentScheduleName == "" { + return nil, errors.New("parameter roleAssignmentScheduleName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleAssignmentScheduleName}", url.PathEscape(roleAssignmentScheduleName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleAssignmentSchedulesClient) getHandleResponse(resp *http.Response) (RoleAssignmentSchedulesClientGetResponse, error) { + result := RoleAssignmentSchedulesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentSchedule); err != nil { + return RoleAssignmentSchedulesClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role assignment schedules for a resource scope. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role assignments schedules. +// - options - RoleAssignmentSchedulesClientListForScopeOptions contains the optional parameters for the RoleAssignmentSchedulesClient.NewListForScopePager +// method. +func (client *RoleAssignmentSchedulesClient) NewListForScopePager(scope string, options *RoleAssignmentSchedulesClientListForScopeOptions) *runtime.Pager[RoleAssignmentSchedulesClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleAssignmentSchedulesClientListForScopeResponse]{ + More: func(page RoleAssignmentSchedulesClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleAssignmentSchedulesClientListForScopeResponse) (RoleAssignmentSchedulesClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleAssignmentSchedulesClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleAssignmentSchedulesClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleAssignmentSchedulesClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleAssignmentSchedulesClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleAssignmentSchedules" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleAssignmentSchedulesClient) listForScopeHandleResponse(resp *http.Response) (RoleAssignmentSchedulesClientListForScopeResponse, error) { + result := RoleAssignmentSchedulesClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleAssignmentScheduleListResult); err != nil { + return RoleAssignmentSchedulesClientListForScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roledefinitions_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roledefinitions_client.go new file mode 100644 index 000000000..97b9c0655 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roledefinitions_client.go @@ -0,0 +1,327 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleDefinitionsClient contains the methods for the RoleDefinitions group. +// Don't use this type directly, use NewRoleDefinitionsClient() instead. +type RoleDefinitionsClient struct { + internal *arm.Client +} + +// NewRoleDefinitionsClient creates a new instance of RoleDefinitionsClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleDefinitionsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleDefinitionsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleDefinitionsClient{ + internal: cl, + } + return client, nil +} + +// CreateOrUpdate - Creates or updates a role definition. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the role definition. +// - roleDefinitionID - The ID of the role definition. +// - roleDefinition - The values for the role definition. +// - options - RoleDefinitionsClientCreateOrUpdateOptions contains the optional parameters for the RoleDefinitionsClient.CreateOrUpdate +// method. +func (client *RoleDefinitionsClient) CreateOrUpdate(ctx context.Context, scope string, roleDefinitionID string, roleDefinition RoleDefinition, options *RoleDefinitionsClientCreateOrUpdateOptions) (RoleDefinitionsClientCreateOrUpdateResponse, error) { + var err error + const operationName = "RoleDefinitionsClient.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, scope, roleDefinitionID, roleDefinition, options) + if err != nil { + return RoleDefinitionsClientCreateOrUpdateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleDefinitionsClientCreateOrUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return RoleDefinitionsClientCreateOrUpdateResponse{}, err + } + resp, err := client.createOrUpdateHandleResponse(httpResp) + return resp, err +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *RoleDefinitionsClient) createOrUpdateCreateRequest(ctx context.Context, scope string, roleDefinitionID string, roleDefinition RoleDefinition, options *RoleDefinitionsClientCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleDefinitionID == "" { + return nil, errors.New("parameter roleDefinitionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleDefinitionId}", url.PathEscape(roleDefinitionID)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, roleDefinition); err != nil { + return nil, err + } + return req, nil +} + +// createOrUpdateHandleResponse handles the CreateOrUpdate response. +func (client *RoleDefinitionsClient) createOrUpdateHandleResponse(resp *http.Response) (RoleDefinitionsClientCreateOrUpdateResponse, error) { + result := RoleDefinitionsClientCreateOrUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleDefinition); err != nil { + return RoleDefinitionsClientCreateOrUpdateResponse{}, err + } + return result, nil +} + +// Delete - Deletes a role definition. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the role definition. +// - roleDefinitionID - The ID of the role definition to delete. +// - options - RoleDefinitionsClientDeleteOptions contains the optional parameters for the RoleDefinitionsClient.Delete method. +func (client *RoleDefinitionsClient) Delete(ctx context.Context, scope string, roleDefinitionID string, options *RoleDefinitionsClientDeleteOptions) (RoleDefinitionsClientDeleteResponse, error) { + var err error + const operationName = "RoleDefinitionsClient.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, scope, roleDefinitionID, options) + if err != nil { + return RoleDefinitionsClientDeleteResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleDefinitionsClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return RoleDefinitionsClientDeleteResponse{}, err + } + resp, err := client.deleteHandleResponse(httpResp) + return resp, err +} + +// deleteCreateRequest creates the Delete request. +func (client *RoleDefinitionsClient) deleteCreateRequest(ctx context.Context, scope string, roleDefinitionID string, options *RoleDefinitionsClientDeleteOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleDefinitionID == "" { + return nil, errors.New("parameter roleDefinitionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleDefinitionId}", url.PathEscape(roleDefinitionID)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// deleteHandleResponse handles the Delete response. +func (client *RoleDefinitionsClient) deleteHandleResponse(resp *http.Response) (RoleDefinitionsClientDeleteResponse, error) { + result := RoleDefinitionsClientDeleteResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleDefinition); err != nil { + return RoleDefinitionsClientDeleteResponse{}, err + } + return result, nil +} + +// Get - Get role definition by name (GUID). +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the role definition. +// - roleDefinitionID - The ID of the role definition. +// - options - RoleDefinitionsClientGetOptions contains the optional parameters for the RoleDefinitionsClient.Get method. +func (client *RoleDefinitionsClient) Get(ctx context.Context, scope string, roleDefinitionID string, options *RoleDefinitionsClientGetOptions) (RoleDefinitionsClientGetResponse, error) { + var err error + const operationName = "RoleDefinitionsClient.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, scope, roleDefinitionID, options) + if err != nil { + return RoleDefinitionsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleDefinitionsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleDefinitionsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleDefinitionsClient) getCreateRequest(ctx context.Context, scope string, roleDefinitionID string, options *RoleDefinitionsClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleDefinitionID == "" { + return nil, errors.New("parameter roleDefinitionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleDefinitionId}", url.PathEscape(roleDefinitionID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleDefinitionsClient) getHandleResponse(resp *http.Response) (RoleDefinitionsClientGetResponse, error) { + result := RoleDefinitionsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleDefinition); err != nil { + return RoleDefinitionsClientGetResponse{}, err + } + return result, nil +} + +// GetByID - Gets a role definition by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2022-04-01 +// - roleID - The fully qualified role definition ID. Use the format, /subscriptions/{guid}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId} +// for subscription level role definitions, or +// /providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionId} for tenant level role definitions. +// - options - RoleDefinitionsClientGetByIDOptions contains the optional parameters for the RoleDefinitionsClient.GetByID method. +func (client *RoleDefinitionsClient) GetByID(ctx context.Context, roleID string, options *RoleDefinitionsClientGetByIDOptions) (RoleDefinitionsClientGetByIDResponse, error) { + var err error + const operationName = "RoleDefinitionsClient.GetByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getByIDCreateRequest(ctx, roleID, options) + if err != nil { + return RoleDefinitionsClientGetByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleDefinitionsClientGetByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleDefinitionsClientGetByIDResponse{}, err + } + resp, err := client.getByIDHandleResponse(httpResp) + return resp, err +} + +// getByIDCreateRequest creates the GetByID request. +func (client *RoleDefinitionsClient) getByIDCreateRequest(ctx context.Context, roleID string, options *RoleDefinitionsClientGetByIDOptions) (*policy.Request, error) { + urlPath := "/{roleId}" + urlPath = strings.ReplaceAll(urlPath, "{roleId}", roleID) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getByIDHandleResponse handles the GetByID response. +func (client *RoleDefinitionsClient) getByIDHandleResponse(resp *http.Response) (RoleDefinitionsClientGetByIDResponse, error) { + result := RoleDefinitionsClientGetByIDResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleDefinition); err != nil { + return RoleDefinitionsClientGetByIDResponse{}, err + } + return result, nil +} + +// NewListPager - Get all role definitions that are applicable at scope and above. +// +// Generated from API version 2022-04-01 +// - scope - The scope of the role definition. +// - options - RoleDefinitionsClientListOptions contains the optional parameters for the RoleDefinitionsClient.NewListPager +// method. +func (client *RoleDefinitionsClient) NewListPager(scope string, options *RoleDefinitionsClientListOptions) *runtime.Pager[RoleDefinitionsClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleDefinitionsClientListResponse]{ + More: func(page RoleDefinitionsClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleDefinitionsClientListResponse) (RoleDefinitionsClientListResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleDefinitionsClient.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, scope, options) + }, nil) + if err != nil { + return RoleDefinitionsClientListResponse{}, err + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *RoleDefinitionsClient) listCreateRequest(ctx context.Context, scope string, options *RoleDefinitionsClientListOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleDefinitions" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2022-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *RoleDefinitionsClient) listHandleResponse(resp *http.Response) (RoleDefinitionsClientListResponse, error) { + result := RoleDefinitionsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleDefinitionListResult); err != nil { + return RoleDefinitionsClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityscheduleinstances_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityscheduleinstances_client.go new file mode 100644 index 000000000..e9fb778e1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityscheduleinstances_client.go @@ -0,0 +1,155 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleEligibilityScheduleInstancesClient contains the methods for the RoleEligibilityScheduleInstances group. +// Don't use this type directly, use NewRoleEligibilityScheduleInstancesClient() instead. +type RoleEligibilityScheduleInstancesClient struct { + internal *arm.Client +} + +// NewRoleEligibilityScheduleInstancesClient creates a new instance of RoleEligibilityScheduleInstancesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleEligibilityScheduleInstancesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleEligibilityScheduleInstancesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleEligibilityScheduleInstancesClient{ + internal: cl, + } + return client, nil +} + +// Get - Gets the specified role eligibility schedule instance. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedules. +// - roleEligibilityScheduleInstanceName - The name (hash of schedule name + time) of the role eligibility schedule to get. +// - options - RoleEligibilityScheduleInstancesClientGetOptions contains the optional parameters for the RoleEligibilityScheduleInstancesClient.Get +// method. +func (client *RoleEligibilityScheduleInstancesClient) Get(ctx context.Context, scope string, roleEligibilityScheduleInstanceName string, options *RoleEligibilityScheduleInstancesClientGetOptions) (RoleEligibilityScheduleInstancesClientGetResponse, error) { + var err error + const operationName = "RoleEligibilityScheduleInstancesClient.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, scope, roleEligibilityScheduleInstanceName, options) + if err != nil { + return RoleEligibilityScheduleInstancesClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleEligibilityScheduleInstancesClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleEligibilityScheduleInstancesClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleEligibilityScheduleInstancesClient) getCreateRequest(ctx context.Context, scope string, roleEligibilityScheduleInstanceName string, options *RoleEligibilityScheduleInstancesClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleInstances/{roleEligibilityScheduleInstanceName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleEligibilityScheduleInstanceName == "" { + return nil, errors.New("parameter roleEligibilityScheduleInstanceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleEligibilityScheduleInstanceName}", url.PathEscape(roleEligibilityScheduleInstanceName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleEligibilityScheduleInstancesClient) getHandleResponse(resp *http.Response) (RoleEligibilityScheduleInstancesClientGetResponse, error) { + result := RoleEligibilityScheduleInstancesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleInstance); err != nil { + return RoleEligibilityScheduleInstancesClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role eligibility schedule instances of a role eligibility schedule. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedule. +// - options - RoleEligibilityScheduleInstancesClientListForScopeOptions contains the optional parameters for the RoleEligibilityScheduleInstancesClient.NewListForScopePager +// method. +func (client *RoleEligibilityScheduleInstancesClient) NewListForScopePager(scope string, options *RoleEligibilityScheduleInstancesClientListForScopeOptions) *runtime.Pager[RoleEligibilityScheduleInstancesClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleEligibilityScheduleInstancesClientListForScopeResponse]{ + More: func(page RoleEligibilityScheduleInstancesClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleEligibilityScheduleInstancesClientListForScopeResponse) (RoleEligibilityScheduleInstancesClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleEligibilityScheduleInstancesClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleEligibilityScheduleInstancesClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleEligibilityScheduleInstancesClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleEligibilityScheduleInstancesClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleInstances" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleEligibilityScheduleInstancesClient) listForScopeHandleResponse(resp *http.Response) (RoleEligibilityScheduleInstancesClientListForScopeResponse, error) { + result := RoleEligibilityScheduleInstancesClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleInstanceListResult); err != nil { + return RoleEligibilityScheduleInstancesClientListForScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityschedulerequests_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityschedulerequests_client.go new file mode 100644 index 000000000..fca5ee49c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityschedulerequests_client.go @@ -0,0 +1,331 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleEligibilityScheduleRequestsClient contains the methods for the RoleEligibilityScheduleRequests group. +// Don't use this type directly, use NewRoleEligibilityScheduleRequestsClient() instead. +type RoleEligibilityScheduleRequestsClient struct { + internal *arm.Client +} + +// NewRoleEligibilityScheduleRequestsClient creates a new instance of RoleEligibilityScheduleRequestsClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleEligibilityScheduleRequestsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleEligibilityScheduleRequestsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleEligibilityScheduleRequestsClient{ + internal: cl, + } + return client, nil +} + +// Cancel - Cancels a pending role eligibility schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility request to cancel. +// - roleEligibilityScheduleRequestName - The name of the role eligibility request to cancel. +// - options - RoleEligibilityScheduleRequestsClientCancelOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Cancel +// method. +func (client *RoleEligibilityScheduleRequestsClient) Cancel(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, options *RoleEligibilityScheduleRequestsClientCancelOptions) (RoleEligibilityScheduleRequestsClientCancelResponse, error) { + var err error + const operationName = "RoleEligibilityScheduleRequestsClient.Cancel" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelCreateRequest(ctx, scope, roleEligibilityScheduleRequestName, options) + if err != nil { + return RoleEligibilityScheduleRequestsClientCancelResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleEligibilityScheduleRequestsClientCancelResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleEligibilityScheduleRequestsClientCancelResponse{}, err + } + return RoleEligibilityScheduleRequestsClientCancelResponse{}, nil +} + +// cancelCreateRequest creates the Cancel request. +func (client *RoleEligibilityScheduleRequestsClient) cancelCreateRequest(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, options *RoleEligibilityScheduleRequestsClientCancelOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleRequests/{roleEligibilityScheduleRequestName}/cancel" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleEligibilityScheduleRequestName == "" { + return nil, errors.New("parameter roleEligibilityScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleEligibilityScheduleRequestName}", url.PathEscape(roleEligibilityScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Create - Creates a role eligibility schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedule request to create. The scope can be any REST resource instance. For +// example, use '/subscriptions/{subscription-id}/' for a subscription, +// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}' for a resource group, and +// '/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/{resource-provider}/{resource-type}/{resource-name}' +// for a resource. +// - roleEligibilityScheduleRequestName - The name of the role eligibility to create. It can be any valid GUID. +// - parameters - Parameters for the role eligibility schedule request. +// - options - RoleEligibilityScheduleRequestsClientCreateOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Create +// method. +func (client *RoleEligibilityScheduleRequestsClient) Create(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, parameters RoleEligibilityScheduleRequest, options *RoleEligibilityScheduleRequestsClientCreateOptions) (RoleEligibilityScheduleRequestsClientCreateResponse, error) { + var err error + const operationName = "RoleEligibilityScheduleRequestsClient.Create" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createCreateRequest(ctx, scope, roleEligibilityScheduleRequestName, parameters, options) + if err != nil { + return RoleEligibilityScheduleRequestsClientCreateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleEligibilityScheduleRequestsClientCreateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return RoleEligibilityScheduleRequestsClientCreateResponse{}, err + } + resp, err := client.createHandleResponse(httpResp) + return resp, err +} + +// createCreateRequest creates the Create request. +func (client *RoleEligibilityScheduleRequestsClient) createCreateRequest(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, parameters RoleEligibilityScheduleRequest, options *RoleEligibilityScheduleRequestsClientCreateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleRequests/{roleEligibilityScheduleRequestName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleEligibilityScheduleRequestName == "" { + return nil, errors.New("parameter roleEligibilityScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleEligibilityScheduleRequestName}", url.PathEscape(roleEligibilityScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createHandleResponse handles the Create response. +func (client *RoleEligibilityScheduleRequestsClient) createHandleResponse(resp *http.Response) (RoleEligibilityScheduleRequestsClientCreateResponse, error) { + result := RoleEligibilityScheduleRequestsClientCreateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleRequest); err != nil { + return RoleEligibilityScheduleRequestsClientCreateResponse{}, err + } + return result, nil +} + +// Get - Get the specified role eligibility schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedule request. +// - roleEligibilityScheduleRequestName - The name (guid) of the role eligibility schedule request to get. +// - options - RoleEligibilityScheduleRequestsClientGetOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Get +// method. +func (client *RoleEligibilityScheduleRequestsClient) Get(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, options *RoleEligibilityScheduleRequestsClientGetOptions) (RoleEligibilityScheduleRequestsClientGetResponse, error) { + var err error + const operationName = "RoleEligibilityScheduleRequestsClient.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, scope, roleEligibilityScheduleRequestName, options) + if err != nil { + return RoleEligibilityScheduleRequestsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleEligibilityScheduleRequestsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleEligibilityScheduleRequestsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleEligibilityScheduleRequestsClient) getCreateRequest(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, options *RoleEligibilityScheduleRequestsClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleRequests/{roleEligibilityScheduleRequestName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleEligibilityScheduleRequestName == "" { + return nil, errors.New("parameter roleEligibilityScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleEligibilityScheduleRequestName}", url.PathEscape(roleEligibilityScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleEligibilityScheduleRequestsClient) getHandleResponse(resp *http.Response) (RoleEligibilityScheduleRequestsClientGetResponse, error) { + result := RoleEligibilityScheduleRequestsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleRequest); err != nil { + return RoleEligibilityScheduleRequestsClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role eligibility schedule requests for a scope. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedule requests. +// - options - RoleEligibilityScheduleRequestsClientListForScopeOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.NewListForScopePager +// method. +func (client *RoleEligibilityScheduleRequestsClient) NewListForScopePager(scope string, options *RoleEligibilityScheduleRequestsClientListForScopeOptions) *runtime.Pager[RoleEligibilityScheduleRequestsClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleEligibilityScheduleRequestsClientListForScopeResponse]{ + More: func(page RoleEligibilityScheduleRequestsClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleEligibilityScheduleRequestsClientListForScopeResponse) (RoleEligibilityScheduleRequestsClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleEligibilityScheduleRequestsClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleEligibilityScheduleRequestsClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleEligibilityScheduleRequestsClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleEligibilityScheduleRequestsClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleRequests" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleEligibilityScheduleRequestsClient) listForScopeHandleResponse(resp *http.Response) (RoleEligibilityScheduleRequestsClientListForScopeResponse, error) { + result := RoleEligibilityScheduleRequestsClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleRequestListResult); err != nil { + return RoleEligibilityScheduleRequestsClientListForScopeResponse{}, err + } + return result, nil +} + +// Validate - Validates a new role eligibility schedule request. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility request to validate. +// - roleEligibilityScheduleRequestName - The name of the role eligibility request to validate. +// - parameters - Parameters for the role eligibility schedule request. +// - options - RoleEligibilityScheduleRequestsClientValidateOptions contains the optional parameters for the RoleEligibilityScheduleRequestsClient.Validate +// method. +func (client *RoleEligibilityScheduleRequestsClient) Validate(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, parameters RoleEligibilityScheduleRequest, options *RoleEligibilityScheduleRequestsClientValidateOptions) (RoleEligibilityScheduleRequestsClientValidateResponse, error) { + var err error + const operationName = "RoleEligibilityScheduleRequestsClient.Validate" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateCreateRequest(ctx, scope, roleEligibilityScheduleRequestName, parameters, options) + if err != nil { + return RoleEligibilityScheduleRequestsClientValidateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleEligibilityScheduleRequestsClientValidateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleEligibilityScheduleRequestsClientValidateResponse{}, err + } + resp, err := client.validateHandleResponse(httpResp) + return resp, err +} + +// validateCreateRequest creates the Validate request. +func (client *RoleEligibilityScheduleRequestsClient) validateCreateRequest(ctx context.Context, scope string, roleEligibilityScheduleRequestName string, parameters RoleEligibilityScheduleRequest, options *RoleEligibilityScheduleRequestsClientValidateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilityScheduleRequests/{roleEligibilityScheduleRequestName}/validate" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleEligibilityScheduleRequestName == "" { + return nil, errors.New("parameter roleEligibilityScheduleRequestName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleEligibilityScheduleRequestName}", url.PathEscape(roleEligibilityScheduleRequestName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// validateHandleResponse handles the Validate response. +func (client *RoleEligibilityScheduleRequestsClient) validateHandleResponse(resp *http.Response) (RoleEligibilityScheduleRequestsClientValidateResponse, error) { + result := RoleEligibilityScheduleRequestsClientValidateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleRequest); err != nil { + return RoleEligibilityScheduleRequestsClientValidateResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityschedules_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityschedules_client.go new file mode 100644 index 000000000..8c6102618 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/roleeligibilityschedules_client.go @@ -0,0 +1,155 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleEligibilitySchedulesClient contains the methods for the RoleEligibilitySchedules group. +// Don't use this type directly, use NewRoleEligibilitySchedulesClient() instead. +type RoleEligibilitySchedulesClient struct { + internal *arm.Client +} + +// NewRoleEligibilitySchedulesClient creates a new instance of RoleEligibilitySchedulesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleEligibilitySchedulesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleEligibilitySchedulesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleEligibilitySchedulesClient{ + internal: cl, + } + return client, nil +} + +// Get - Get the specified role eligibility schedule for a resource scope +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedule. +// - roleEligibilityScheduleName - The name (guid) of the role eligibility schedule to get. +// - options - RoleEligibilitySchedulesClientGetOptions contains the optional parameters for the RoleEligibilitySchedulesClient.Get +// method. +func (client *RoleEligibilitySchedulesClient) Get(ctx context.Context, scope string, roleEligibilityScheduleName string, options *RoleEligibilitySchedulesClientGetOptions) (RoleEligibilitySchedulesClientGetResponse, error) { + var err error + const operationName = "RoleEligibilitySchedulesClient.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, scope, roleEligibilityScheduleName, options) + if err != nil { + return RoleEligibilitySchedulesClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleEligibilitySchedulesClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleEligibilitySchedulesClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleEligibilitySchedulesClient) getCreateRequest(ctx context.Context, scope string, roleEligibilityScheduleName string, options *RoleEligibilitySchedulesClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilitySchedules/{roleEligibilityScheduleName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleEligibilityScheduleName == "" { + return nil, errors.New("parameter roleEligibilityScheduleName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleEligibilityScheduleName}", url.PathEscape(roleEligibilityScheduleName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleEligibilitySchedulesClient) getHandleResponse(resp *http.Response) (RoleEligibilitySchedulesClientGetResponse, error) { + result := RoleEligibilitySchedulesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilitySchedule); err != nil { + return RoleEligibilitySchedulesClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role eligibility schedules for a resource scope. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role eligibility schedules. +// - options - RoleEligibilitySchedulesClientListForScopeOptions contains the optional parameters for the RoleEligibilitySchedulesClient.NewListForScopePager +// method. +func (client *RoleEligibilitySchedulesClient) NewListForScopePager(scope string, options *RoleEligibilitySchedulesClientListForScopeOptions) *runtime.Pager[RoleEligibilitySchedulesClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleEligibilitySchedulesClientListForScopeResponse]{ + More: func(page RoleEligibilitySchedulesClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleEligibilitySchedulesClientListForScopeResponse) (RoleEligibilitySchedulesClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleEligibilitySchedulesClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleEligibilitySchedulesClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleEligibilitySchedulesClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleEligibilitySchedulesClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleEligibilitySchedules" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleEligibilitySchedulesClient) listForScopeHandleResponse(resp *http.Response) (RoleEligibilitySchedulesClientListForScopeResponse, error) { + result := RoleEligibilitySchedulesClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleEligibilityScheduleListResult); err != nil { + return RoleEligibilitySchedulesClientListForScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/rolemanagementpolicies_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/rolemanagementpolicies_client.go new file mode 100644 index 000000000..34aa8cabb --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/rolemanagementpolicies_client.go @@ -0,0 +1,262 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleManagementPoliciesClient contains the methods for the RoleManagementPolicies group. +// Don't use this type directly, use NewRoleManagementPoliciesClient() instead. +type RoleManagementPoliciesClient struct { + internal *arm.Client +} + +// NewRoleManagementPoliciesClient creates a new instance of RoleManagementPoliciesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleManagementPoliciesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleManagementPoliciesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleManagementPoliciesClient{ + internal: cl, + } + return client, nil +} + +// Delete - Delete a role management policy +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy to upsert. +// - roleManagementPolicyName - The name (guid) of the role management policy to upsert. +// - options - RoleManagementPoliciesClientDeleteOptions contains the optional parameters for the RoleManagementPoliciesClient.Delete +// method. +func (client *RoleManagementPoliciesClient) Delete(ctx context.Context, scope string, roleManagementPolicyName string, options *RoleManagementPoliciesClientDeleteOptions) (RoleManagementPoliciesClientDeleteResponse, error) { + var err error + const operationName = "RoleManagementPoliciesClient.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, scope, roleManagementPolicyName, options) + if err != nil { + return RoleManagementPoliciesClientDeleteResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleManagementPoliciesClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return RoleManagementPoliciesClientDeleteResponse{}, err + } + return RoleManagementPoliciesClientDeleteResponse{}, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *RoleManagementPoliciesClient) deleteCreateRequest(ctx context.Context, scope string, roleManagementPolicyName string, options *RoleManagementPoliciesClientDeleteOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicies/{roleManagementPolicyName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleManagementPolicyName == "" { + return nil, errors.New("parameter roleManagementPolicyName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleManagementPolicyName}", url.PathEscape(roleManagementPolicyName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Get - Get the specified role management policy for a resource scope +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy. +// - roleManagementPolicyName - The name (guid) of the role management policy to get. +// - options - RoleManagementPoliciesClientGetOptions contains the optional parameters for the RoleManagementPoliciesClient.Get +// method. +func (client *RoleManagementPoliciesClient) Get(ctx context.Context, scope string, roleManagementPolicyName string, options *RoleManagementPoliciesClientGetOptions) (RoleManagementPoliciesClientGetResponse, error) { + var err error + const operationName = "RoleManagementPoliciesClient.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, scope, roleManagementPolicyName, options) + if err != nil { + return RoleManagementPoliciesClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleManagementPoliciesClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleManagementPoliciesClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleManagementPoliciesClient) getCreateRequest(ctx context.Context, scope string, roleManagementPolicyName string, options *RoleManagementPoliciesClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicies/{roleManagementPolicyName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleManagementPolicyName == "" { + return nil, errors.New("parameter roleManagementPolicyName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleManagementPolicyName}", url.PathEscape(roleManagementPolicyName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleManagementPoliciesClient) getHandleResponse(resp *http.Response) (RoleManagementPoliciesClientGetResponse, error) { + result := RoleManagementPoliciesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleManagementPolicy); err != nil { + return RoleManagementPoliciesClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role management policies for a resource scope. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy. +// - options - RoleManagementPoliciesClientListForScopeOptions contains the optional parameters for the RoleManagementPoliciesClient.NewListForScopePager +// method. +func (client *RoleManagementPoliciesClient) NewListForScopePager(scope string, options *RoleManagementPoliciesClientListForScopeOptions) *runtime.Pager[RoleManagementPoliciesClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleManagementPoliciesClientListForScopeResponse]{ + More: func(page RoleManagementPoliciesClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleManagementPoliciesClientListForScopeResponse) (RoleManagementPoliciesClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleManagementPoliciesClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleManagementPoliciesClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleManagementPoliciesClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleManagementPoliciesClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicies" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleManagementPoliciesClient) listForScopeHandleResponse(resp *http.Response) (RoleManagementPoliciesClientListForScopeResponse, error) { + result := RoleManagementPoliciesClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleManagementPolicyListResult); err != nil { + return RoleManagementPoliciesClientListForScopeResponse{}, err + } + return result, nil +} + +// Update - Update a role management policy +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy to upsert. +// - roleManagementPolicyName - The name (guid) of the role management policy to upsert. +// - parameters - Parameters for the role management policy. +// - options - RoleManagementPoliciesClientUpdateOptions contains the optional parameters for the RoleManagementPoliciesClient.Update +// method. +func (client *RoleManagementPoliciesClient) Update(ctx context.Context, scope string, roleManagementPolicyName string, parameters RoleManagementPolicy, options *RoleManagementPoliciesClientUpdateOptions) (RoleManagementPoliciesClientUpdateResponse, error) { + var err error + const operationName = "RoleManagementPoliciesClient.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, scope, roleManagementPolicyName, parameters, options) + if err != nil { + return RoleManagementPoliciesClientUpdateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleManagementPoliciesClientUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleManagementPoliciesClientUpdateResponse{}, err + } + resp, err := client.updateHandleResponse(httpResp) + return resp, err +} + +// updateCreateRequest creates the Update request. +func (client *RoleManagementPoliciesClient) updateCreateRequest(ctx context.Context, scope string, roleManagementPolicyName string, parameters RoleManagementPolicy, options *RoleManagementPoliciesClientUpdateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicies/{roleManagementPolicyName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleManagementPolicyName == "" { + return nil, errors.New("parameter roleManagementPolicyName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleManagementPolicyName}", url.PathEscape(roleManagementPolicyName)) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// updateHandleResponse handles the Update response. +func (client *RoleManagementPoliciesClient) updateHandleResponse(resp *http.Response) (RoleManagementPoliciesClientUpdateResponse, error) { + result := RoleManagementPoliciesClientUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleManagementPolicy); err != nil { + return RoleManagementPoliciesClientUpdateResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/rolemanagementpolicyassignments_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/rolemanagementpolicyassignments_client.go new file mode 100644 index 000000000..0f20dd1c9 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/rolemanagementpolicyassignments_client.go @@ -0,0 +1,262 @@ +//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 armauthorization + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// RoleManagementPolicyAssignmentsClient contains the methods for the RoleManagementPolicyAssignments group. +// Don't use this type directly, use NewRoleManagementPolicyAssignmentsClient() instead. +type RoleManagementPolicyAssignmentsClient struct { + internal *arm.Client +} + +// NewRoleManagementPolicyAssignmentsClient creates a new instance of RoleManagementPolicyAssignmentsClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewRoleManagementPolicyAssignmentsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*RoleManagementPolicyAssignmentsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &RoleManagementPolicyAssignmentsClient{ + internal: cl, + } + return client, nil +} + +// Create - Create a role management policy assignment +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy assignment to upsert. +// - roleManagementPolicyAssignmentName - The name of format {guid_guid} the role management policy assignment to upsert. +// - parameters - Parameters for the role management policy assignment. +// - options - RoleManagementPolicyAssignmentsClientCreateOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.Create +// method. +func (client *RoleManagementPolicyAssignmentsClient) Create(ctx context.Context, scope string, roleManagementPolicyAssignmentName string, parameters RoleManagementPolicyAssignment, options *RoleManagementPolicyAssignmentsClientCreateOptions) (RoleManagementPolicyAssignmentsClientCreateResponse, error) { + var err error + const operationName = "RoleManagementPolicyAssignmentsClient.Create" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createCreateRequest(ctx, scope, roleManagementPolicyAssignmentName, parameters, options) + if err != nil { + return RoleManagementPolicyAssignmentsClientCreateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleManagementPolicyAssignmentsClientCreateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return RoleManagementPolicyAssignmentsClientCreateResponse{}, err + } + resp, err := client.createHandleResponse(httpResp) + return resp, err +} + +// createCreateRequest creates the Create request. +func (client *RoleManagementPolicyAssignmentsClient) createCreateRequest(ctx context.Context, scope string, roleManagementPolicyAssignmentName string, parameters RoleManagementPolicyAssignment, options *RoleManagementPolicyAssignmentsClientCreateOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicyAssignments/{roleManagementPolicyAssignmentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleManagementPolicyAssignmentName == "" { + return nil, errors.New("parameter roleManagementPolicyAssignmentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleManagementPolicyAssignmentName}", url.PathEscape(roleManagementPolicyAssignmentName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createHandleResponse handles the Create response. +func (client *RoleManagementPolicyAssignmentsClient) createHandleResponse(resp *http.Response) (RoleManagementPolicyAssignmentsClientCreateResponse, error) { + result := RoleManagementPolicyAssignmentsClientCreateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleManagementPolicyAssignment); err != nil { + return RoleManagementPolicyAssignmentsClientCreateResponse{}, err + } + return result, nil +} + +// Delete - Delete a role management policy assignment +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy assignment to delete. +// - roleManagementPolicyAssignmentName - The name of format {guid_guid} the role management policy assignment to delete. +// - options - RoleManagementPolicyAssignmentsClientDeleteOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.Delete +// method. +func (client *RoleManagementPolicyAssignmentsClient) Delete(ctx context.Context, scope string, roleManagementPolicyAssignmentName string, options *RoleManagementPolicyAssignmentsClientDeleteOptions) (RoleManagementPolicyAssignmentsClientDeleteResponse, error) { + var err error + const operationName = "RoleManagementPolicyAssignmentsClient.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, scope, roleManagementPolicyAssignmentName, options) + if err != nil { + return RoleManagementPolicyAssignmentsClientDeleteResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleManagementPolicyAssignmentsClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return RoleManagementPolicyAssignmentsClientDeleteResponse{}, err + } + return RoleManagementPolicyAssignmentsClientDeleteResponse{}, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *RoleManagementPolicyAssignmentsClient) deleteCreateRequest(ctx context.Context, scope string, roleManagementPolicyAssignmentName string, options *RoleManagementPolicyAssignmentsClientDeleteOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicyAssignments/{roleManagementPolicyAssignmentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleManagementPolicyAssignmentName == "" { + return nil, errors.New("parameter roleManagementPolicyAssignmentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleManagementPolicyAssignmentName}", url.PathEscape(roleManagementPolicyAssignmentName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Get - Get the specified role management policy assignment for a resource scope +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy. +// - roleManagementPolicyAssignmentName - The name of format {guid_guid} the role management policy assignment to get. +// - options - RoleManagementPolicyAssignmentsClientGetOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.Get +// method. +func (client *RoleManagementPolicyAssignmentsClient) Get(ctx context.Context, scope string, roleManagementPolicyAssignmentName string, options *RoleManagementPolicyAssignmentsClientGetOptions) (RoleManagementPolicyAssignmentsClientGetResponse, error) { + var err error + const operationName = "RoleManagementPolicyAssignmentsClient.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, scope, roleManagementPolicyAssignmentName, options) + if err != nil { + return RoleManagementPolicyAssignmentsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return RoleManagementPolicyAssignmentsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return RoleManagementPolicyAssignmentsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *RoleManagementPolicyAssignmentsClient) getCreateRequest(ctx context.Context, scope string, roleManagementPolicyAssignmentName string, options *RoleManagementPolicyAssignmentsClientGetOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicyAssignments/{roleManagementPolicyAssignmentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if roleManagementPolicyAssignmentName == "" { + return nil, errors.New("parameter roleManagementPolicyAssignmentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{roleManagementPolicyAssignmentName}", url.PathEscape(roleManagementPolicyAssignmentName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *RoleManagementPolicyAssignmentsClient) getHandleResponse(resp *http.Response) (RoleManagementPolicyAssignmentsClientGetResponse, error) { + result := RoleManagementPolicyAssignmentsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleManagementPolicyAssignment); err != nil { + return RoleManagementPolicyAssignmentsClientGetResponse{}, err + } + return result, nil +} + +// NewListForScopePager - Gets role management assignment policies for a resource scope. +// +// Generated from API version 2020-10-01 +// - scope - The scope of the role management policy. +// - options - RoleManagementPolicyAssignmentsClientListForScopeOptions contains the optional parameters for the RoleManagementPolicyAssignmentsClient.NewListForScopePager +// method. +func (client *RoleManagementPolicyAssignmentsClient) NewListForScopePager(scope string, options *RoleManagementPolicyAssignmentsClientListForScopeOptions) *runtime.Pager[RoleManagementPolicyAssignmentsClientListForScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[RoleManagementPolicyAssignmentsClientListForScopeResponse]{ + More: func(page RoleManagementPolicyAssignmentsClientListForScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *RoleManagementPolicyAssignmentsClientListForScopeResponse) (RoleManagementPolicyAssignmentsClientListForScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "RoleManagementPolicyAssignmentsClient.NewListForScopePager") + 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.listForScopeCreateRequest(ctx, scope, options) + }, nil) + if err != nil { + return RoleManagementPolicyAssignmentsClientListForScopeResponse{}, err + } + return client.listForScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listForScopeCreateRequest creates the ListForScope request. +func (client *RoleManagementPolicyAssignmentsClient) listForScopeCreateRequest(ctx context.Context, scope string, options *RoleManagementPolicyAssignmentsClientListForScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Authorization/roleManagementPolicyAssignments" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2020-10-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listForScopeHandleResponse handles the ListForScope response. +func (client *RoleManagementPolicyAssignmentsClient) listForScopeHandleResponse(resp *http.Response) (RoleManagementPolicyAssignmentsClientListForScopeResponse, error) { + result := RoleManagementPolicyAssignmentsClientListForScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.RoleManagementPolicyAssignmentListResult); err != nil { + return RoleManagementPolicyAssignmentsClientListForScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/time_rfc3339.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/time_rfc3339.go new file mode 100644 index 000000000..57651544a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2/time_rfc3339.go @@ -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 armauthorization + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" + "regexp" + "strings" + "time" +) + +// 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+)*"*$`) + +const ( + utcDateTimeJSON = `"2006-01-02T15:04:05.999999999"` + utcDateTime = "2006-01-02T15:04:05.999999999" + dateTimeJSON = `"` + time.RFC3339Nano + `"` +) + +type dateTimeRFC3339 time.Time + +func (t dateTimeRFC3339) MarshalJSON() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalJSON() +} + +func (t dateTimeRFC3339) MarshalText() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalText() +} + +func (t *dateTimeRFC3339) UnmarshalJSON(data []byte) error { + layout := utcDateTimeJSON + if tzOffsetRegex.Match(data) { + layout = dateTimeJSON + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) UnmarshalText(data []byte) error { + layout := utcDateTime + if tzOffsetRegex.Match(data) { + layout = time.RFC3339Nano + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) Parse(layout, value string) error { + p, err := time.Parse(layout, strings.ToUpper(value)) + *t = dateTimeRFC3339(p) + return err +} + +func populateDateTimeRFC3339(m map[string]any, k string, t *time.Time) { + if t == nil { + return + } else if azcore.IsNullValue(t) { + m[k] = nil + return + } else if reflect.ValueOf(t).IsNil() { + return + } + m[k] = (*dateTimeRFC3339)(t) +} + +func unpopulateDateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error { + if data == nil || strings.EqualFold(string(data), "null") { + return nil + } + var aux dateTimeRFC3339 + if err := json.Unmarshal(data, &aux); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + *t = (*time.Time)(&aux) + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/CHANGELOG.md new file mode 100644 index 000000000..34085f095 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/CHANGELOG.md @@ -0,0 +1,68 @@ +# Release History + +## 1.3.0 (2025-07-25) +### Features Added + +- New enum type `IsolationScope` with values `IsolationScopeNone`, `IsolationScopeRegional` +- New field `IsolationScope` in struct `UserAssignedIdentityProperties` + + +## 1.2.0 (2023-11-24) +### Features Added + +- Support for test fakes and OpenTelemetry trace spans. + + +## 1.1.0 (2023-03-31) +### Features Added + +- New struct `ClientFactory` which is a client factory used to create any client in this module + + +## 1.0.0 (2023-02-24) +### Breaking Changes + +- Function `*UserAssignedIdentitiesClient.NewListAssociatedResourcesPager` has been removed + +### Features Added + +- New type alias `CreatedByType` with values `CreatedByTypeApplication`, `CreatedByTypeKey`, `CreatedByTypeManagedIdentity`, `CreatedByTypeUser` +- New function `timeRFC3339.MarshalText() ([]byte, error)` +- New function `*timeRFC3339.Parse(string) error` +- New function `*timeRFC3339.UnmarshalText([]byte) error` +- New struct `SystemData` +- New field `SystemData` in struct `FederatedIdentityCredential` +- New field `SystemData` in struct `Identity` +- New field `SystemData` in struct `IdentityUpdate` +- New field `SystemData` in struct `SystemAssignedIdentity` + + +## 0.7.0 (2022-06-27) +### Features Added + +- New function `*FederatedIdentityCredentialsClient.Delete(context.Context, string, string, string, *FederatedIdentityCredentialsClientDeleteOptions) (FederatedIdentityCredentialsClientDeleteResponse, error)` +- New function `*FederatedIdentityCredentialsClient.CreateOrUpdate(context.Context, string, string, string, FederatedIdentityCredential, *FederatedIdentityCredentialsClientCreateOrUpdateOptions) (FederatedIdentityCredentialsClientCreateOrUpdateResponse, error)` +- New function `*FederatedIdentityCredentialsClient.NewListPager(string, string, *FederatedIdentityCredentialsClientListOptions) *runtime.Pager[FederatedIdentityCredentialsClientListResponse]` +- New function `NewFederatedIdentityCredentialsClient(string, azcore.TokenCredential, *arm.ClientOptions) (*FederatedIdentityCredentialsClient, error)` +- New function `*FederatedIdentityCredentialsClient.Get(context.Context, string, string, string, *FederatedIdentityCredentialsClientGetOptions) (FederatedIdentityCredentialsClientGetResponse, error)` +- New struct `FederatedIdentityCredential` +- New struct `FederatedIdentityCredentialProperties` +- New struct `FederatedIdentityCredentialsClient` +- New struct `FederatedIdentityCredentialsClientCreateOrUpdateOptions` +- New struct `FederatedIdentityCredentialsClientCreateOrUpdateResponse` +- New struct `FederatedIdentityCredentialsClientDeleteOptions` +- New struct `FederatedIdentityCredentialsClientDeleteResponse` +- New struct `FederatedIdentityCredentialsClientGetOptions` +- New struct `FederatedIdentityCredentialsClientGetResponse` +- New struct `FederatedIdentityCredentialsClientListOptions` +- New struct `FederatedIdentityCredentialsClientListResponse` +- New struct `FederatedIdentityCredentialsListResult` + + +## 0.6.0 (2022-05-17) + +The package of `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi` is using our [next generation design principles](https://azure.github.io/azure-sdk/general_introduction.html) since version 0.6.0, which contains breaking changes. + +To migrate the existing applications to the latest version, please refer to [Migration Guide](https://aka.ms/azsdk/go/mgmt/migration). + +To learn more, please refer to our documentation [Quick Start](https://aka.ms/azsdk/go/mgmt). \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/LICENSE.txt new file mode 100644 index 000000000..dc0c2ffb3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/README.md new file mode 100644 index 000000000..8c86245d8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/README.md @@ -0,0 +1,90 @@ +# Azure Managed Service Identity Module for Go + +The `armmsi` module provides operations for working with Azure Managed Service Identity. + +[Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/resourcemanager/msi/armmsi) + +# Getting started + +## Prerequisites + +- an [Azure subscription](https://azure.microsoft.com/free/) +- [Supported](https://aka.ms/azsdk/go/supported-versions) version of Go (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 + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Install the Azure Managed Service Identity module: + +```sh +go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi +``` + +## Authorization + +When creating a client, you will need to provide a credential for authenticating with Azure Managed Service Identity. The `azidentity` module provides facilities for various ways of authenticating with Azure including client/secret, certificate, managed identity, and more. + +```go +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). + +## Client Factory + +Azure Managed Service Identity module consists of one or more clients. We provide a client factory which could be used to create any client in this module. + +```go +clientFactory, err := armmsi.NewClientFactory(, 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). + +```go +options := arm.ClientOptions { + ClientOptions: azcore.ClientOptions { + Cloud: cloud.AzureChina, + }, +} +clientFactory, err := armmsi.NewClientFactory(, 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.NewFederatedIdentityCredentialsClient() +``` + +## 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. + +## Provide Feedback + +If you encounter bugs or have suggestions, please +[open an issue](https://github.com/Azure/azure-sdk-for-go/issues) and assign the `Managed Service Identity` label. + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. +For details, visit [https://cla.microsoft.com](https://cla.microsoft.com). + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only +need to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information, see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/assets.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/assets.json new file mode 100644 index 000000000..84324b8b7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/assets.json @@ -0,0 +1,6 @@ +{ + "AssetsRepo": "Azure/azure-sdk-assets", + "AssetsRepoPrefixPath": "go", + "TagPrefix": "go/resourcemanager/msi/armmsi", + "Tag": "go/resourcemanager/msi/armmsi_dbfb7feb00" +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/autorest.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/autorest.md new file mode 100644 index 000000000..c735b46f0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/autorest.md @@ -0,0 +1,13 @@ +### AutoRest Configuration + +> see https://aka.ms/autorest + +``` yaml +azure-arm: true +require: +- https://github.com/Azure/azure-rest-api-specs/blob/44319b51c6f952fdc9543d3dc4fdd9959350d102/specification/msi/resource-manager/readme.md +- https://github.com/Azure/azure-rest-api-specs/blob/44319b51c6f952fdc9543d3dc4fdd9959350d102/specification/msi/resource-manager/readme.go.md +license-header: MICROSOFT_MIT_NO_VERSION +module-version: 1.3.0 +tag: package-2024-11-30 +``` \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/build.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/build.go new file mode 100644 index 000000000..1c3e780b1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/build.go @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// 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 ../../../../eng/scripts/build.ps1 -skipBuild -cleanGenerated -format -tidy -generate -alwaysSetBodyParamRequired -removeUnreferencedTypes resourcemanager/msi/armmsi + +package armmsi diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/ci.yml new file mode 100644 index 000000000..c897a929e --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/ci.yml @@ -0,0 +1,28 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/msi/armmsi/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/msi/armmsi/ + +extends: + template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + ServiceDirectory: 'resourcemanager/msi/armmsi' + UsePipelineProxy: false diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/client_factory.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/client_factory.go new file mode 100644 index 000000000..fd7d09d85 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/client_factory.go @@ -0,0 +1,64 @@ +// 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 armmsi + +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 + internal *arm.Client +} + +// 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 Id of the Subscription to which the identity belongs. +// - 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) { + internal, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + return &ClientFactory{ + subscriptionID: subscriptionID, + internal: internal, + }, nil +} + +// NewFederatedIdentityCredentialsClient creates a new instance of FederatedIdentityCredentialsClient. +func (c *ClientFactory) NewFederatedIdentityCredentialsClient() *FederatedIdentityCredentialsClient { + return &FederatedIdentityCredentialsClient{ + subscriptionID: c.subscriptionID, + internal: c.internal, + } +} + +// NewOperationsClient creates a new instance of OperationsClient. +func (c *ClientFactory) NewOperationsClient() *OperationsClient { + return &OperationsClient{ + internal: c.internal, + } +} + +// NewSystemAssignedIdentitiesClient creates a new instance of SystemAssignedIdentitiesClient. +func (c *ClientFactory) NewSystemAssignedIdentitiesClient() *SystemAssignedIdentitiesClient { + return &SystemAssignedIdentitiesClient{ + internal: c.internal, + } +} + +// NewUserAssignedIdentitiesClient creates a new instance of UserAssignedIdentitiesClient. +func (c *ClientFactory) NewUserAssignedIdentitiesClient() *UserAssignedIdentitiesClient { + return &UserAssignedIdentitiesClient{ + subscriptionID: c.subscriptionID, + internal: c.internal, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/constants.go new file mode 100644 index 000000000..d33c5e1e4 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/constants.go @@ -0,0 +1,47 @@ +// 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 armmsi + +const ( + moduleName = "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi" + moduleVersion = "v1.3.0" +) + +// CreatedByType - The type of identity that created the resource. +type CreatedByType string + +const ( + CreatedByTypeApplication CreatedByType = "Application" + CreatedByTypeKey CreatedByType = "Key" + CreatedByTypeManagedIdentity CreatedByType = "ManagedIdentity" + CreatedByTypeUser CreatedByType = "User" +) + +// PossibleCreatedByTypeValues returns the possible values for the CreatedByType const type. +func PossibleCreatedByTypeValues() []CreatedByType { + return []CreatedByType{ + CreatedByTypeApplication, + CreatedByTypeKey, + CreatedByTypeManagedIdentity, + CreatedByTypeUser, + } +} + +// IsolationScope - Enum to configure regional restrictions on identity assignment, as necessary. +type IsolationScope string + +const ( + IsolationScopeNone IsolationScope = "None" + IsolationScopeRegional IsolationScope = "Regional" +) + +// PossibleIsolationScopeValues returns the possible values for the IsolationScope const type. +func PossibleIsolationScopeValues() []IsolationScope { + return []IsolationScope{ + IsolationScopeNone, + IsolationScopeRegional, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/federatedidentitycredentials_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/federatedidentitycredentials_client.go new file mode 100644 index 000000000..05f06385c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/federatedidentitycredentials_client.go @@ -0,0 +1,317 @@ +// 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 armmsi + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strconv" + "strings" +) + +// FederatedIdentityCredentialsClient contains the methods for the FederatedIdentityCredentials group. +// Don't use this type directly, use NewFederatedIdentityCredentialsClient() instead. +type FederatedIdentityCredentialsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewFederatedIdentityCredentialsClient creates a new instance of FederatedIdentityCredentialsClient with the specified values. +// - subscriptionID - The Id of the Subscription to which the identity belongs. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewFederatedIdentityCredentialsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*FederatedIdentityCredentialsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &FederatedIdentityCredentialsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// CreateOrUpdate - Create or update a federated identity credential under the specified user assigned identity. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceName - The name of the identity resource. +// - federatedIdentityCredentialResourceName - The name of the federated identity credential resource. +// - parameters - Parameters to create or update the federated identity credential. +// - options - FederatedIdentityCredentialsClientCreateOrUpdateOptions contains the optional parameters for the FederatedIdentityCredentialsClient.CreateOrUpdate +// method. +func (client *FederatedIdentityCredentialsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string, federatedIdentityCredentialResourceName string, parameters FederatedIdentityCredential, options *FederatedIdentityCredentialsClientCreateOrUpdateOptions) (FederatedIdentityCredentialsClientCreateOrUpdateResponse, error) { + var err error + const operationName = "FederatedIdentityCredentialsClient.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, resourceName, federatedIdentityCredentialResourceName, parameters, options) + if err != nil { + return FederatedIdentityCredentialsClientCreateOrUpdateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return FederatedIdentityCredentialsClientCreateOrUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return FederatedIdentityCredentialsClientCreateOrUpdateResponse{}, err + } + resp, err := client.createOrUpdateHandleResponse(httpResp) + return resp, err +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *FederatedIdentityCredentialsClient) createOrUpdateCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, federatedIdentityCredentialResourceName string, parameters FederatedIdentityCredential, _ *FederatedIdentityCredentialsClientCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if federatedIdentityCredentialResourceName == "" { + return nil, errors.New("parameter federatedIdentityCredentialResourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{federatedIdentityCredentialResourceName}", url.PathEscape(federatedIdentityCredentialResourceName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createOrUpdateHandleResponse handles the CreateOrUpdate response. +func (client *FederatedIdentityCredentialsClient) createOrUpdateHandleResponse(resp *http.Response) (FederatedIdentityCredentialsClientCreateOrUpdateResponse, error) { + result := FederatedIdentityCredentialsClientCreateOrUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FederatedIdentityCredential); err != nil { + return FederatedIdentityCredentialsClientCreateOrUpdateResponse{}, err + } + return result, nil +} + +// Delete - Deletes the federated identity credential. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceName - The name of the identity resource. +// - federatedIdentityCredentialResourceName - The name of the federated identity credential resource. +// - options - FederatedIdentityCredentialsClientDeleteOptions contains the optional parameters for the FederatedIdentityCredentialsClient.Delete +// method. +func (client *FederatedIdentityCredentialsClient) Delete(ctx context.Context, resourceGroupName string, resourceName string, federatedIdentityCredentialResourceName string, options *FederatedIdentityCredentialsClientDeleteOptions) (FederatedIdentityCredentialsClientDeleteResponse, error) { + var err error + const operationName = "FederatedIdentityCredentialsClient.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, resourceGroupName, resourceName, federatedIdentityCredentialResourceName, options) + if err != nil { + return FederatedIdentityCredentialsClientDeleteResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return FederatedIdentityCredentialsClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return FederatedIdentityCredentialsClientDeleteResponse{}, err + } + return FederatedIdentityCredentialsClientDeleteResponse{}, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *FederatedIdentityCredentialsClient) deleteCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, federatedIdentityCredentialResourceName string, _ *FederatedIdentityCredentialsClientDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if federatedIdentityCredentialResourceName == "" { + return nil, errors.New("parameter federatedIdentityCredentialResourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{federatedIdentityCredentialResourceName}", url.PathEscape(federatedIdentityCredentialResourceName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Get - Gets the federated identity credential. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceName - The name of the identity resource. +// - federatedIdentityCredentialResourceName - The name of the federated identity credential resource. +// - options - FederatedIdentityCredentialsClientGetOptions contains the optional parameters for the FederatedIdentityCredentialsClient.Get +// method. +func (client *FederatedIdentityCredentialsClient) Get(ctx context.Context, resourceGroupName string, resourceName string, federatedIdentityCredentialResourceName string, options *FederatedIdentityCredentialsClientGetOptions) (FederatedIdentityCredentialsClientGetResponse, error) { + var err error + const operationName = "FederatedIdentityCredentialsClient.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, resourceName, federatedIdentityCredentialResourceName, options) + if err != nil { + return FederatedIdentityCredentialsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return FederatedIdentityCredentialsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return FederatedIdentityCredentialsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *FederatedIdentityCredentialsClient) getCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, federatedIdentityCredentialResourceName string, _ *FederatedIdentityCredentialsClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials/{federatedIdentityCredentialResourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if federatedIdentityCredentialResourceName == "" { + return nil, errors.New("parameter federatedIdentityCredentialResourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{federatedIdentityCredentialResourceName}", url.PathEscape(federatedIdentityCredentialResourceName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *FederatedIdentityCredentialsClient) getHandleResponse(resp *http.Response) (FederatedIdentityCredentialsClientGetResponse, error) { + result := FederatedIdentityCredentialsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FederatedIdentityCredential); err != nil { + return FederatedIdentityCredentialsClientGetResponse{}, err + } + return result, nil +} + +// NewListPager - Lists all the federated identity credentials under the specified user assigned identity. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the resource group. The name is case insensitive. +// - resourceName - The name of the identity resource. +// - options - FederatedIdentityCredentialsClientListOptions contains the optional parameters for the FederatedIdentityCredentialsClient.NewListPager +// method. +func (client *FederatedIdentityCredentialsClient) NewListPager(resourceGroupName string, resourceName string, options *FederatedIdentityCredentialsClientListOptions) *runtime.Pager[FederatedIdentityCredentialsClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[FederatedIdentityCredentialsClientListResponse]{ + More: func(page FederatedIdentityCredentialsClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *FederatedIdentityCredentialsClientListResponse) (FederatedIdentityCredentialsClientListResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "FederatedIdentityCredentialsClient.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, resourceName, options) + }, nil) + if err != nil { + return FederatedIdentityCredentialsClientListResponse{}, err + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *FederatedIdentityCredentialsClient) listCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, options *FederatedIdentityCredentialsClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}/federatedIdentityCredentials" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Skiptoken != nil { + reqQP.Set("$skiptoken", *options.Skiptoken) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *FederatedIdentityCredentialsClient) listHandleResponse(resp *http.Response) (FederatedIdentityCredentialsClientListResponse, error) { + result := FederatedIdentityCredentialsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.FederatedIdentityCredentialsListResult); err != nil { + return FederatedIdentityCredentialsClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models.go new file mode 100644 index 000000000..6bf497095 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models.go @@ -0,0 +1,212 @@ +// 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 armmsi + +import "time" + +// FederatedIdentityCredential - Describes a federated identity credential. +type FederatedIdentityCredential struct { + // The properties associated with the federated identity credential. + Properties *FederatedIdentityCredentialProperties + + // READ-ONLY; Fully qualified resource ID for the resource. E.g. "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}" + ID *string + + // READ-ONLY; The name of the resource + Name *string + + // READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information. + SystemData *SystemData + + // READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts" + Type *string +} + +// FederatedIdentityCredentialProperties - The properties associated with a federated identity credential. +type FederatedIdentityCredentialProperties struct { + // REQUIRED; The list of audiences that can appear in the issued token. + Audiences []*string + + // REQUIRED; The URL of the issuer to be trusted. + Issuer *string + + // REQUIRED; The identifier of the external identity. + Subject *string +} + +// FederatedIdentityCredentialsListResult - Values returned by the List operation for federated identity credentials. +type FederatedIdentityCredentialsListResult struct { + // The url to get the next page of results, if any. + NextLink *string + + // The collection of federated identity credentials returned by the listing operation. + Value []*FederatedIdentityCredential +} + +// Identity - Describes an identity resource. +type Identity struct { + // REQUIRED; The geo-location where the resource lives + Location *string + + // Resource tags. + Tags map[string]*string + + // READ-ONLY; Fully qualified resource ID for the resource. E.g. "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}" + ID *string + + // READ-ONLY; The name of the resource + Name *string + + // READ-ONLY; The properties associated with the identity. + Properties *UserAssignedIdentityProperties + + // READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information. + SystemData *SystemData + + // READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts" + Type *string +} + +// IdentityUpdate - Describes an identity resource. +type IdentityUpdate struct { + // The geo-location where the resource lives + Location *string + + // Resource tags + Tags map[string]*string + + // READ-ONLY; Fully qualified resource ID for the resource. E.g. "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}" + ID *string + + // READ-ONLY; The name of the resource + Name *string + + // READ-ONLY; The properties associated with the identity. + Properties *UserAssignedIdentityProperties + + // READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information. + SystemData *SystemData + + // READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts" + Type *string +} + +// Operation supported by the Microsoft.ManagedIdentity REST API. +type Operation struct { + // The object that describes the operation. + Display *OperationDisplay + + // The name of the REST Operation. This is of the format {provider}/{resource}/{operation}. + Name *string +} + +// OperationDisplay - The object that describes the operation. +type OperationDisplay struct { + // A description of the operation. + Description *string + + // The type of operation. For example: read, write, delete. + Operation *string + + // Friendly name of the resource provider. + Provider *string + + // The resource type on which the operation is performed. + Resource *string +} + +// OperationListResult - A list of operations supported by Microsoft.ManagedIdentity Resource Provider. +type OperationListResult struct { + // The url to get the next page of results, if any. + NextLink *string + + // A list of operations supported by Microsoft.ManagedIdentity Resource Provider. + Value []*Operation +} + +// SystemAssignedIdentity - Describes a system assigned identity resource. +type SystemAssignedIdentity struct { + // REQUIRED; The geo-location where the resource lives + Location *string + + // Resource tags + Tags map[string]*string + + // READ-ONLY; Fully qualified resource ID for the resource. E.g. "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}" + ID *string + + // READ-ONLY; The name of the resource + Name *string + + // READ-ONLY; The properties associated with the identity. + Properties *SystemAssignedIdentityProperties + + // READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information. + SystemData *SystemData + + // READ-ONLY; The type of the resource. E.g. "Microsoft.Compute/virtualMachines" or "Microsoft.Storage/storageAccounts" + Type *string +} + +// SystemAssignedIdentityProperties - The properties associated with the system assigned identity. +type SystemAssignedIdentityProperties struct { + // READ-ONLY; The id of the app associated with the identity. This is a random generated UUID by MSI. + ClientID *string + + // READ-ONLY; The ManagedServiceIdentity DataPlane URL that can be queried to obtain the identity credentials. + ClientSecretURL *string + + // READ-ONLY; The id of the service principal object associated with the created identity. + PrincipalID *string + + // READ-ONLY; The id of the tenant which the identity belongs to. + TenantID *string +} + +// SystemData - Metadata pertaining to creation and last modification of the resource. +type SystemData struct { + // The timestamp of resource creation (UTC). + CreatedAt *time.Time + + // The identity that created the resource. + CreatedBy *string + + // The type of identity that created the resource. + CreatedByType *CreatedByType + + // The timestamp of resource last modification (UTC) + LastModifiedAt *time.Time + + // The identity that last modified the resource. + LastModifiedBy *string + + // The type of identity that last modified the resource. + LastModifiedByType *CreatedByType +} + +// UserAssignedIdentitiesListResult - Values returned by the List operation. +type UserAssignedIdentitiesListResult struct { + // The url to get the next page of results, if any. + NextLink *string + + // The collection of userAssignedIdentities returned by the listing operation. + Value []*Identity +} + +// UserAssignedIdentityProperties - The properties associated with the user assigned identity. +type UserAssignedIdentityProperties struct { + // Enum to configure regional restrictions on identity assignment, as necessary. + IsolationScope *IsolationScope + + // READ-ONLY; The id of the app associated with the identity. This is a random generated UUID by MSI. + ClientID *string + + // READ-ONLY; The id of the service principal object associated with the created identity. + PrincipalID *string + + // READ-ONLY; The id of the tenant which the identity belongs to. + TenantID *string +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models_serde.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models_serde.go new file mode 100644 index 000000000..323bfb103 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models_serde.go @@ -0,0 +1,552 @@ +// 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 armmsi + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" +) + +// MarshalJSON implements the json.Marshaller interface for type FederatedIdentityCredential. +func (f FederatedIdentityCredential) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", f.ID) + populate(objectMap, "name", f.Name) + populate(objectMap, "properties", f.Properties) + populate(objectMap, "systemData", f.SystemData) + populate(objectMap, "type", f.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type FederatedIdentityCredential. +func (f *FederatedIdentityCredential) 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", f, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &f.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &f.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &f.Properties) + delete(rawMsg, key) + case "systemData": + err = unpopulate(val, "SystemData", &f.SystemData) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &f.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type FederatedIdentityCredentialProperties. +func (f FederatedIdentityCredentialProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "audiences", f.Audiences) + populate(objectMap, "issuer", f.Issuer) + populate(objectMap, "subject", f.Subject) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type FederatedIdentityCredentialProperties. +func (f *FederatedIdentityCredentialProperties) 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", f, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "audiences": + err = unpopulate(val, "Audiences", &f.Audiences) + delete(rawMsg, key) + case "issuer": + err = unpopulate(val, "Issuer", &f.Issuer) + delete(rawMsg, key) + case "subject": + err = unpopulate(val, "Subject", &f.Subject) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type FederatedIdentityCredentialsListResult. +func (f FederatedIdentityCredentialsListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", f.NextLink) + populate(objectMap, "value", f.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type FederatedIdentityCredentialsListResult. +func (f *FederatedIdentityCredentialsListResult) 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", f, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &f.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &f.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", f, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Identity. +func (i Identity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", i.ID) + populate(objectMap, "location", i.Location) + populate(objectMap, "name", i.Name) + populate(objectMap, "properties", i.Properties) + populate(objectMap, "systemData", i.SystemData) + populate(objectMap, "tags", i.Tags) + populate(objectMap, "type", i.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Identity. +func (i *Identity) 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", i, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &i.ID) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &i.Location) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &i.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &i.Properties) + delete(rawMsg, key) + case "systemData": + err = unpopulate(val, "SystemData", &i.SystemData) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &i.Tags) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &i.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", i, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type IdentityUpdate. +func (i IdentityUpdate) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", i.ID) + populate(objectMap, "location", i.Location) + populate(objectMap, "name", i.Name) + populate(objectMap, "properties", i.Properties) + populate(objectMap, "systemData", i.SystemData) + populate(objectMap, "tags", i.Tags) + populate(objectMap, "type", i.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type IdentityUpdate. +func (i *IdentityUpdate) 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", i, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &i.ID) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &i.Location) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &i.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &i.Properties) + delete(rawMsg, key) + case "systemData": + err = unpopulate(val, "SystemData", &i.SystemData) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &i.Tags) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &i.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", i, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Operation. +func (o Operation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "display", o.Display) + populate(objectMap, "name", o.Name) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Operation. +func (o *Operation) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "display": + err = unpopulate(val, "Display", &o.Display) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &o.Name) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OperationDisplay. +func (o OperationDisplay) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", o.Description) + populate(objectMap, "operation", o.Operation) + populate(objectMap, "provider", o.Provider) + populate(objectMap, "resource", o.Resource) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OperationDisplay. +func (o *OperationDisplay) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &o.Description) + delete(rawMsg, key) + case "operation": + err = unpopulate(val, "Operation", &o.Operation) + delete(rawMsg, key) + case "provider": + err = unpopulate(val, "Provider", &o.Provider) + delete(rawMsg, key) + case "resource": + err = unpopulate(val, "Resource", &o.Resource) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OperationListResult. +func (o OperationListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", o.NextLink) + populate(objectMap, "value", o.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OperationListResult. +func (o *OperationListResult) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &o.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &o.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SystemAssignedIdentity. +func (s SystemAssignedIdentity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", s.ID) + populate(objectMap, "location", s.Location) + populate(objectMap, "name", s.Name) + populate(objectMap, "properties", s.Properties) + populate(objectMap, "systemData", s.SystemData) + populate(objectMap, "tags", s.Tags) + populate(objectMap, "type", s.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SystemAssignedIdentity. +func (s *SystemAssignedIdentity) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &s.ID) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &s.Location) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &s.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &s.Properties) + delete(rawMsg, key) + case "systemData": + err = unpopulate(val, "SystemData", &s.SystemData) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &s.Tags) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &s.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SystemAssignedIdentityProperties. +func (s SystemAssignedIdentityProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "clientId", s.ClientID) + populate(objectMap, "clientSecretUrl", s.ClientSecretURL) + populate(objectMap, "principalId", s.PrincipalID) + populate(objectMap, "tenantId", s.TenantID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SystemAssignedIdentityProperties. +func (s *SystemAssignedIdentityProperties) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "clientId": + err = unpopulate(val, "ClientID", &s.ClientID) + delete(rawMsg, key) + case "clientSecretUrl": + err = unpopulate(val, "ClientSecretURL", &s.ClientSecretURL) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &s.PrincipalID) + delete(rawMsg, key) + case "tenantId": + err = unpopulate(val, "TenantID", &s.TenantID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SystemData. +func (s SystemData) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateDateTimeRFC3339(objectMap, "createdAt", s.CreatedAt) + populate(objectMap, "createdBy", s.CreatedBy) + populate(objectMap, "createdByType", s.CreatedByType) + populateDateTimeRFC3339(objectMap, "lastModifiedAt", s.LastModifiedAt) + populate(objectMap, "lastModifiedBy", s.LastModifiedBy) + populate(objectMap, "lastModifiedByType", s.LastModifiedByType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SystemData. +func (s *SystemData) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "createdAt": + err = unpopulateDateTimeRFC3339(val, "CreatedAt", &s.CreatedAt) + delete(rawMsg, key) + case "createdBy": + err = unpopulate(val, "CreatedBy", &s.CreatedBy) + delete(rawMsg, key) + case "createdByType": + err = unpopulate(val, "CreatedByType", &s.CreatedByType) + delete(rawMsg, key) + case "lastModifiedAt": + err = unpopulateDateTimeRFC3339(val, "LastModifiedAt", &s.LastModifiedAt) + delete(rawMsg, key) + case "lastModifiedBy": + err = unpopulate(val, "LastModifiedBy", &s.LastModifiedBy) + delete(rawMsg, key) + case "lastModifiedByType": + err = unpopulate(val, "LastModifiedByType", &s.LastModifiedByType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type UserAssignedIdentitiesListResult. +func (u UserAssignedIdentitiesListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", u.NextLink) + populate(objectMap, "value", u.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type UserAssignedIdentitiesListResult. +func (u *UserAssignedIdentitiesListResult) 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", u, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &u.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &u.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", u, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type UserAssignedIdentityProperties. +func (u UserAssignedIdentityProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "clientId", u.ClientID) + populate(objectMap, "isolationScope", u.IsolationScope) + populate(objectMap, "principalId", u.PrincipalID) + populate(objectMap, "tenantId", u.TenantID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type UserAssignedIdentityProperties. +func (u *UserAssignedIdentityProperties) 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", u, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "clientId": + err = unpopulate(val, "ClientID", &u.ClientID) + delete(rawMsg, key) + case "isolationScope": + err = unpopulate(val, "IsolationScope", &u.IsolationScope) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &u.PrincipalID) + delete(rawMsg, key) + case "tenantId": + err = unpopulate(val, "TenantID", &u.TenantID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", u, err) + } + } + return nil +} + +func populate(m map[string]any, k string, v any) { + 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 any) error { + if data == nil || string(data) == "null" { + return nil + } + if err := json.Unmarshal(data, v); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/operations_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/operations_client.go new file mode 100644 index 000000000..c16b57ca2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/operations_client.go @@ -0,0 +1,85 @@ +// 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 armmsi + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" +) + +// OperationsClient contains the methods for the Operations group. +// Don't use this type directly, use NewOperationsClient() instead. +type OperationsClient struct { + 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. +func NewOperationsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*OperationsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &OperationsClient{ + internal: cl, + } + return client, nil +} + +// NewListPager - Lists available operations for the Microsoft.ManagedIdentity provider +// +// Generated from API version 2024-11-30 +// - 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) { + 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 + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *OperationsClient) listCreateRequest(ctx context.Context, _ *OperationsClientListOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.ManagedIdentity/operations" + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *OperationsClient) listHandleResponse(resp *http.Response) (OperationsClientListResponse, error) { + result := OperationsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.OperationListResult); err != nil { + return OperationsClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/options.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/options.go new file mode 100644 index 000000000..6b67faa9a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/options.go @@ -0,0 +1,82 @@ +// 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 armmsi + +// FederatedIdentityCredentialsClientCreateOrUpdateOptions contains the optional parameters for the FederatedIdentityCredentialsClient.CreateOrUpdate +// method. +type FederatedIdentityCredentialsClientCreateOrUpdateOptions struct { + // placeholder for future optional parameters +} + +// FederatedIdentityCredentialsClientDeleteOptions contains the optional parameters for the FederatedIdentityCredentialsClient.Delete +// method. +type FederatedIdentityCredentialsClientDeleteOptions struct { + // placeholder for future optional parameters +} + +// FederatedIdentityCredentialsClientGetOptions contains the optional parameters for the FederatedIdentityCredentialsClient.Get +// method. +type FederatedIdentityCredentialsClientGetOptions struct { + // placeholder for future optional parameters +} + +// FederatedIdentityCredentialsClientListOptions contains the optional parameters for the FederatedIdentityCredentialsClient.NewListPager +// method. +type FederatedIdentityCredentialsClientListOptions struct { + // A skip token is used to continue retrieving items after an operation returns a partial result. If a previous response contains + // a nextLink element, the value of the nextLink element will include a + // skipToken parameter that specifies a starting point to use for subsequent calls. + Skiptoken *string + + // Number of records to return. + Top *int32 +} + +// OperationsClientListOptions contains the optional parameters for the OperationsClient.NewListPager method. +type OperationsClientListOptions struct { + // placeholder for future optional parameters +} + +// SystemAssignedIdentitiesClientGetByScopeOptions contains the optional parameters for the SystemAssignedIdentitiesClient.GetByScope +// method. +type SystemAssignedIdentitiesClientGetByScopeOptions struct { + // placeholder for future optional parameters +} + +// UserAssignedIdentitiesClientCreateOrUpdateOptions contains the optional parameters for the UserAssignedIdentitiesClient.CreateOrUpdate +// method. +type UserAssignedIdentitiesClientCreateOrUpdateOptions struct { + // placeholder for future optional parameters +} + +// UserAssignedIdentitiesClientDeleteOptions contains the optional parameters for the UserAssignedIdentitiesClient.Delete +// method. +type UserAssignedIdentitiesClientDeleteOptions struct { + // placeholder for future optional parameters +} + +// UserAssignedIdentitiesClientGetOptions contains the optional parameters for the UserAssignedIdentitiesClient.Get method. +type UserAssignedIdentitiesClientGetOptions struct { + // placeholder for future optional parameters +} + +// UserAssignedIdentitiesClientListByResourceGroupOptions contains the optional parameters for the UserAssignedIdentitiesClient.NewListByResourceGroupPager +// method. +type UserAssignedIdentitiesClientListByResourceGroupOptions struct { + // placeholder for future optional parameters +} + +// UserAssignedIdentitiesClientListBySubscriptionOptions contains the optional parameters for the UserAssignedIdentitiesClient.NewListBySubscriptionPager +// method. +type UserAssignedIdentitiesClientListBySubscriptionOptions struct { + // placeholder for future optional parameters +} + +// UserAssignedIdentitiesClientUpdateOptions contains the optional parameters for the UserAssignedIdentitiesClient.Update +// method. +type UserAssignedIdentitiesClientUpdateOptions struct { + // placeholder for future optional parameters +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/responses.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/responses.go new file mode 100644 index 000000000..420661fd2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/responses.go @@ -0,0 +1,76 @@ +// 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 armmsi + +// FederatedIdentityCredentialsClientCreateOrUpdateResponse contains the response from method FederatedIdentityCredentialsClient.CreateOrUpdate. +type FederatedIdentityCredentialsClientCreateOrUpdateResponse struct { + // Describes a federated identity credential. + FederatedIdentityCredential +} + +// FederatedIdentityCredentialsClientDeleteResponse contains the response from method FederatedIdentityCredentialsClient.Delete. +type FederatedIdentityCredentialsClientDeleteResponse struct { + // placeholder for future response values +} + +// FederatedIdentityCredentialsClientGetResponse contains the response from method FederatedIdentityCredentialsClient.Get. +type FederatedIdentityCredentialsClientGetResponse struct { + // Describes a federated identity credential. + FederatedIdentityCredential +} + +// FederatedIdentityCredentialsClientListResponse contains the response from method FederatedIdentityCredentialsClient.NewListPager. +type FederatedIdentityCredentialsClientListResponse struct { + // Values returned by the List operation for federated identity credentials. + FederatedIdentityCredentialsListResult +} + +// OperationsClientListResponse contains the response from method OperationsClient.NewListPager. +type OperationsClientListResponse struct { + // A list of operations supported by Microsoft.ManagedIdentity Resource Provider. + OperationListResult +} + +// SystemAssignedIdentitiesClientGetByScopeResponse contains the response from method SystemAssignedIdentitiesClient.GetByScope. +type SystemAssignedIdentitiesClientGetByScopeResponse struct { + // Describes a system assigned identity resource. + SystemAssignedIdentity +} + +// UserAssignedIdentitiesClientCreateOrUpdateResponse contains the response from method UserAssignedIdentitiesClient.CreateOrUpdate. +type UserAssignedIdentitiesClientCreateOrUpdateResponse struct { + // Describes an identity resource. + Identity +} + +// UserAssignedIdentitiesClientDeleteResponse contains the response from method UserAssignedIdentitiesClient.Delete. +type UserAssignedIdentitiesClientDeleteResponse struct { + // placeholder for future response values +} + +// UserAssignedIdentitiesClientGetResponse contains the response from method UserAssignedIdentitiesClient.Get. +type UserAssignedIdentitiesClientGetResponse struct { + // Describes an identity resource. + Identity +} + +// UserAssignedIdentitiesClientListByResourceGroupResponse contains the response from method UserAssignedIdentitiesClient.NewListByResourceGroupPager. +type UserAssignedIdentitiesClientListByResourceGroupResponse struct { + // Values returned by the List operation. + UserAssignedIdentitiesListResult +} + +// UserAssignedIdentitiesClientListBySubscriptionResponse contains the response from method UserAssignedIdentitiesClient.NewListBySubscriptionPager. +type UserAssignedIdentitiesClientListBySubscriptionResponse struct { + // Values returned by the List operation. + UserAssignedIdentitiesListResult +} + +// UserAssignedIdentitiesClientUpdateResponse contains the response from method UserAssignedIdentitiesClient.Update. +type UserAssignedIdentitiesClientUpdateResponse struct { + // Describes an identity resource. + Identity +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/systemassignedidentities_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/systemassignedidentities_client.go new file mode 100644 index 000000000..f87357240 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/systemassignedidentities_client.go @@ -0,0 +1,89 @@ +// 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 armmsi + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "strings" +) + +// SystemAssignedIdentitiesClient contains the methods for the SystemAssignedIdentities group. +// Don't use this type directly, use NewSystemAssignedIdentitiesClient() instead. +type SystemAssignedIdentitiesClient struct { + internal *arm.Client +} + +// NewSystemAssignedIdentitiesClient creates a new instance of SystemAssignedIdentitiesClient with the specified values. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewSystemAssignedIdentitiesClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*SystemAssignedIdentitiesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &SystemAssignedIdentitiesClient{ + internal: cl, + } + return client, nil +} + +// GetByScope - Gets the systemAssignedIdentity available under the specified RP scope. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - scope - The resource provider scope of the resource. Parent resource being extended by Managed Identities. +// - options - SystemAssignedIdentitiesClientGetByScopeOptions contains the optional parameters for the SystemAssignedIdentitiesClient.GetByScope +// method. +func (client *SystemAssignedIdentitiesClient) GetByScope(ctx context.Context, scope string, options *SystemAssignedIdentitiesClientGetByScopeOptions) (SystemAssignedIdentitiesClientGetByScopeResponse, error) { + var err error + const operationName = "SystemAssignedIdentitiesClient.GetByScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getByScopeCreateRequest(ctx, scope, options) + if err != nil { + return SystemAssignedIdentitiesClientGetByScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return SystemAssignedIdentitiesClientGetByScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return SystemAssignedIdentitiesClientGetByScopeResponse{}, err + } + resp, err := client.getByScopeHandleResponse(httpResp) + return resp, err +} + +// getByScopeCreateRequest creates the GetByScope request. +func (client *SystemAssignedIdentitiesClient) getByScopeCreateRequest(ctx context.Context, scope string, _ *SystemAssignedIdentitiesClientGetByScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.ManagedIdentity/identities/default" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getByScopeHandleResponse handles the GetByScope response. +func (client *SystemAssignedIdentitiesClient) getByScopeHandleResponse(resp *http.Response) (SystemAssignedIdentitiesClientGetByScopeResponse, error) { + result := SystemAssignedIdentitiesClientGetByScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.SystemAssignedIdentity); err != nil { + return SystemAssignedIdentitiesClientGetByScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/time_rfc3339.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/time_rfc3339.go new file mode 100644 index 000000000..141269078 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/time_rfc3339.go @@ -0,0 +1,110 @@ +// 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 armmsi + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" + "regexp" + "strings" + "time" +) + +// 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+)*"*$`) + +const ( + utcDateTime = "2006-01-02T15:04:05.999999999" + utcDateTimeJSON = `"` + utcDateTime + `"` + utcDateTimeNoT = "2006-01-02 15:04:05.999999999" + utcDateTimeJSONNoT = `"` + utcDateTimeNoT + `"` + dateTimeNoT = `2006-01-02 15:04:05.999999999Z07:00` + dateTimeJSON = `"` + time.RFC3339Nano + `"` + dateTimeJSONNoT = `"` + dateTimeNoT + `"` +) + +type dateTimeRFC3339 time.Time + +func (t dateTimeRFC3339) MarshalJSON() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalJSON() +} + +func (t dateTimeRFC3339) MarshalText() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalText() +} + +func (t *dateTimeRFC3339) UnmarshalJSON(data []byte) error { + tzOffset := tzOffsetRegex.Match(data) + hasT := strings.Contains(string(data), "T") || strings.Contains(string(data), "t") + var layout string + if tzOffset && hasT { + layout = dateTimeJSON + } else if tzOffset { + layout = dateTimeJSONNoT + } else if hasT { + layout = utcDateTimeJSON + } else { + layout = utcDateTimeJSONNoT + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) UnmarshalText(data []byte) error { + if len(data) == 0 { + return nil + } + tzOffset := tzOffsetRegex.Match(data) + hasT := strings.Contains(string(data), "T") || strings.Contains(string(data), "t") + var layout string + if tzOffset && hasT { + layout = time.RFC3339Nano + } else if tzOffset { + layout = dateTimeNoT + } else if hasT { + layout = utcDateTime + } else { + layout = utcDateTimeNoT + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) Parse(layout, value string) error { + p, err := time.Parse(layout, strings.ToUpper(value)) + *t = dateTimeRFC3339(p) + return err +} + +func (t dateTimeRFC3339) String() string { + return time.Time(t).Format(time.RFC3339Nano) +} + +func populateDateTimeRFC3339(m map[string]any, k string, t *time.Time) { + if t == nil { + return + } else if azcore.IsNullValue(t) { + m[k] = nil + return + } else if reflect.ValueOf(t).IsNil() { + return + } + m[k] = (*dateTimeRFC3339)(t) +} + +func unpopulateDateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error { + if data == nil || string(data) == "null" { + return nil + } + var aux dateTimeRFC3339 + if err := json.Unmarshal(data, &aux); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + *t = (*time.Time)(&aux) + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/userassignedidentities_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/userassignedidentities_client.go new file mode 100644 index 000000000..454e4c0c3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/userassignedidentities_client.go @@ -0,0 +1,414 @@ +// 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 armmsi + +import ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// UserAssignedIdentitiesClient contains the methods for the UserAssignedIdentities group. +// Don't use this type directly, use NewUserAssignedIdentitiesClient() instead. +type UserAssignedIdentitiesClient struct { + internal *arm.Client + subscriptionID string +} + +// NewUserAssignedIdentitiesClient creates a new instance of UserAssignedIdentitiesClient with the specified values. +// - subscriptionID - The Id of the Subscription to which the identity belongs. +// - credential - used to authorize requests. Usually a credential from azidentity. +// - options - pass nil to accept the default values. +func NewUserAssignedIdentitiesClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*UserAssignedIdentitiesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &UserAssignedIdentitiesClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// CreateOrUpdate - Create or update an identity in the specified subscription and resource group. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the Resource Group to which the identity belongs. +// - resourceName - The name of the identity resource. +// - parameters - Parameters to create or update the identity +// - options - UserAssignedIdentitiesClientCreateOrUpdateOptions contains the optional parameters for the UserAssignedIdentitiesClient.CreateOrUpdate +// method. +func (client *UserAssignedIdentitiesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceName string, parameters Identity, options *UserAssignedIdentitiesClientCreateOrUpdateOptions) (UserAssignedIdentitiesClientCreateOrUpdateResponse, error) { + var err error + const operationName = "UserAssignedIdentitiesClient.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, resourceName, parameters, options) + if err != nil { + return UserAssignedIdentitiesClientCreateOrUpdateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return UserAssignedIdentitiesClientCreateOrUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return UserAssignedIdentitiesClientCreateOrUpdateResponse{}, err + } + resp, err := client.createOrUpdateHandleResponse(httpResp) + return resp, err +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *UserAssignedIdentitiesClient) createOrUpdateCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, parameters Identity, _ *UserAssignedIdentitiesClientCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createOrUpdateHandleResponse handles the CreateOrUpdate response. +func (client *UserAssignedIdentitiesClient) createOrUpdateHandleResponse(resp *http.Response) (UserAssignedIdentitiesClientCreateOrUpdateResponse, error) { + result := UserAssignedIdentitiesClientCreateOrUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Identity); err != nil { + return UserAssignedIdentitiesClientCreateOrUpdateResponse{}, err + } + return result, nil +} + +// Delete - Deletes the identity. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the Resource Group to which the identity belongs. +// - resourceName - The name of the identity resource. +// - options - UserAssignedIdentitiesClientDeleteOptions contains the optional parameters for the UserAssignedIdentitiesClient.Delete +// method. +func (client *UserAssignedIdentitiesClient) Delete(ctx context.Context, resourceGroupName string, resourceName string, options *UserAssignedIdentitiesClientDeleteOptions) (UserAssignedIdentitiesClientDeleteResponse, error) { + var err error + const operationName = "UserAssignedIdentitiesClient.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, resourceGroupName, resourceName, options) + if err != nil { + return UserAssignedIdentitiesClientDeleteResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return UserAssignedIdentitiesClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return UserAssignedIdentitiesClientDeleteResponse{}, err + } + return UserAssignedIdentitiesClientDeleteResponse{}, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *UserAssignedIdentitiesClient) deleteCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, _ *UserAssignedIdentitiesClientDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Get - Gets the identity. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the Resource Group to which the identity belongs. +// - resourceName - The name of the identity resource. +// - options - UserAssignedIdentitiesClientGetOptions contains the optional parameters for the UserAssignedIdentitiesClient.Get +// method. +func (client *UserAssignedIdentitiesClient) Get(ctx context.Context, resourceGroupName string, resourceName string, options *UserAssignedIdentitiesClientGetOptions) (UserAssignedIdentitiesClientGetResponse, error) { + var err error + const operationName = "UserAssignedIdentitiesClient.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, resourceName, options) + if err != nil { + return UserAssignedIdentitiesClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return UserAssignedIdentitiesClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return UserAssignedIdentitiesClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *UserAssignedIdentitiesClient) getCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, _ *UserAssignedIdentitiesClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *UserAssignedIdentitiesClient) getHandleResponse(resp *http.Response) (UserAssignedIdentitiesClientGetResponse, error) { + result := UserAssignedIdentitiesClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Identity); err != nil { + return UserAssignedIdentitiesClientGetResponse{}, err + } + return result, nil +} + +// NewListByResourceGroupPager - Lists all the userAssignedIdentities available under the specified ResourceGroup. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the Resource Group to which the identity belongs. +// - options - UserAssignedIdentitiesClientListByResourceGroupOptions contains the optional parameters for the UserAssignedIdentitiesClient.NewListByResourceGroupPager +// method. +func (client *UserAssignedIdentitiesClient) NewListByResourceGroupPager(resourceGroupName string, options *UserAssignedIdentitiesClientListByResourceGroupOptions) *runtime.Pager[UserAssignedIdentitiesClientListByResourceGroupResponse] { + return runtime.NewPager(runtime.PagingHandler[UserAssignedIdentitiesClientListByResourceGroupResponse]{ + More: func(page UserAssignedIdentitiesClientListByResourceGroupResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *UserAssignedIdentitiesClientListByResourceGroupResponse) (UserAssignedIdentitiesClientListByResourceGroupResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "UserAssignedIdentitiesClient.NewListByResourceGroupPager") + 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.listByResourceGroupCreateRequest(ctx, resourceGroupName, options) + }, nil) + if err != nil { + return UserAssignedIdentitiesClientListByResourceGroupResponse{}, err + } + return client.listByResourceGroupHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listByResourceGroupCreateRequest creates the ListByResourceGroup request. +func (client *UserAssignedIdentitiesClient) listByResourceGroupCreateRequest(ctx context.Context, resourceGroupName string, _ *UserAssignedIdentitiesClientListByResourceGroupOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listByResourceGroupHandleResponse handles the ListByResourceGroup response. +func (client *UserAssignedIdentitiesClient) listByResourceGroupHandleResponse(resp *http.Response) (UserAssignedIdentitiesClientListByResourceGroupResponse, error) { + result := UserAssignedIdentitiesClientListByResourceGroupResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.UserAssignedIdentitiesListResult); err != nil { + return UserAssignedIdentitiesClientListByResourceGroupResponse{}, err + } + return result, nil +} + +// NewListBySubscriptionPager - Lists all the userAssignedIdentities available under the specified subscription. +// +// Generated from API version 2024-11-30 +// - options - UserAssignedIdentitiesClientListBySubscriptionOptions contains the optional parameters for the UserAssignedIdentitiesClient.NewListBySubscriptionPager +// method. +func (client *UserAssignedIdentitiesClient) NewListBySubscriptionPager(options *UserAssignedIdentitiesClientListBySubscriptionOptions) *runtime.Pager[UserAssignedIdentitiesClientListBySubscriptionResponse] { + return runtime.NewPager(runtime.PagingHandler[UserAssignedIdentitiesClientListBySubscriptionResponse]{ + More: func(page UserAssignedIdentitiesClientListBySubscriptionResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *UserAssignedIdentitiesClientListBySubscriptionResponse) (UserAssignedIdentitiesClientListBySubscriptionResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "UserAssignedIdentitiesClient.NewListBySubscriptionPager") + 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.listBySubscriptionCreateRequest(ctx, options) + }, nil) + if err != nil { + return UserAssignedIdentitiesClientListBySubscriptionResponse{}, err + } + return client.listBySubscriptionHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listBySubscriptionCreateRequest creates the ListBySubscription request. +func (client *UserAssignedIdentitiesClient) listBySubscriptionCreateRequest(ctx context.Context, _ *UserAssignedIdentitiesClientListBySubscriptionOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.ManagedIdentity/userAssignedIdentities" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listBySubscriptionHandleResponse handles the ListBySubscription response. +func (client *UserAssignedIdentitiesClient) listBySubscriptionHandleResponse(resp *http.Response) (UserAssignedIdentitiesClientListBySubscriptionResponse, error) { + result := UserAssignedIdentitiesClientListBySubscriptionResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.UserAssignedIdentitiesListResult); err != nil { + return UserAssignedIdentitiesClientListBySubscriptionResponse{}, err + } + return result, nil +} + +// Update - Update an identity in the specified subscription and resource group. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2024-11-30 +// - resourceGroupName - The name of the Resource Group to which the identity belongs. +// - resourceName - The name of the identity resource. +// - parameters - Parameters to update the identity +// - options - UserAssignedIdentitiesClientUpdateOptions contains the optional parameters for the UserAssignedIdentitiesClient.Update +// method. +func (client *UserAssignedIdentitiesClient) Update(ctx context.Context, resourceGroupName string, resourceName string, parameters IdentityUpdate, options *UserAssignedIdentitiesClientUpdateOptions) (UserAssignedIdentitiesClientUpdateResponse, error) { + var err error + const operationName = "UserAssignedIdentitiesClient.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, resourceName, parameters, options) + if err != nil { + return UserAssignedIdentitiesClientUpdateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return UserAssignedIdentitiesClientUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return UserAssignedIdentitiesClientUpdateResponse{}, err + } + resp, err := client.updateHandleResponse(httpResp) + return resp, err +} + +// updateCreateRequest creates the Update request. +func (client *UserAssignedIdentitiesClient) updateCreateRequest(ctx context.Context, resourceGroupName string, resourceName string, parameters IdentityUpdate, _ *UserAssignedIdentitiesClientUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{resourceName}" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2024-11-30") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// updateHandleResponse handles the Update response. +func (client *UserAssignedIdentitiesClient) updateHandleResponse(resp *http.Response) (UserAssignedIdentitiesClientUpdateResponse, error) { + result := UserAssignedIdentitiesClientUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Identity); err != nil { + return UserAssignedIdentitiesClientUpdateResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/CHANGELOG.md new file mode 100644 index 000000000..7186a65f1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/CHANGELOG.md @@ -0,0 +1,45 @@ +# Release History + +## 1.2.0 (2023-11-24) +### Features Added + +- Support for test fakes and OpenTelemetry trace spans. + + +## 1.2.0-beta.3 (2023-10-09) + +### Other Changes + +- Updated to latest `azcore` beta. + +## 1.2.0-beta.2 (2023-07-19) + +### Bug Fixes + +- Fixed a potential panic in faked paged and long-running operations. + +## 1.2.0-beta.1 (2023-06-12) + +### Features Added + +- Support for test fakes and OpenTelemetry trace spans. + +## 1.1.1 (2023-04-14) +### Bug Fixes + +- Fix serialization bug of empty value of `any` type. + + +## 1.1.0 (2023-03-27) +### Features Added + +- New struct `ClientFactory` which is a client factory used to create any client in this module + + +## 1.0.0 (2022-05-16) + +The package of `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources` is using our [next generation design principles](https://azure.github.io/azure-sdk/general_introduction.html) since version 1.0.0, which contains breaking changes. + +To migrate the existing applications to the latest version, please refer to [Migration Guide](https://aka.ms/azsdk/go/mgmt/migration). + +To learn more, please refer to our documentation [Quick Start](https://aka.ms/azsdk/go/mgmt). \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/LICENSE.txt new file mode 100644 index 000000000..dc0c2ffb3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/README.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/README.md new file mode 100644 index 000000000..fbe11f6c6 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/README.md @@ -0,0 +1,100 @@ +# Azure Resources Module for Go + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources) + +The `armresources` module provides operations for working with Azure Resources. + +[Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/resourcemanager/resources/armresources) + +# Getting started + +## Prerequisites + +- an [Azure subscription](https://azure.microsoft.com/free/) +- 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 + +This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management. + +Install the Azure Resources module: + +```sh +go get github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources +``` + +## Authorization + +When creating a client, you will need to provide a credential for authenticating with Azure Resources. The `azidentity` module provides facilities for various ways of authenticating with Azure including client/secret, certificate, managed identity, and more. + +```go +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). + +## Client Factory + +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 +clientFactory, err := armresources.NewClientFactory(, 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). + +```go +options := arm.ClientOptions { + ClientOptions: azcore.ClientOptions { + Cloud: cloud.AzureChina, + }, +} +clientFactory, err := armresources.NewClientFactory(, 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) +- [Resource](https://aka.ms/azsdk/go/mgmt/samples?path=sdk/resourcemanager/resource/resources) + +## Provide Feedback + +If you encounter bugs or have suggestions, please +[open an issue](https://github.com/Azure/azure-sdk-for-go/issues) and assign the `Resources` label. + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require +you to agree to a Contributor License Agreement (CLA) declaring that you have +the right to, and actually do, grant us the rights to use your contribution. +For details, visit [https://cla.microsoft.com](https://cla.microsoft.com). + +When you submit a pull request, a CLA-bot will automatically determine whether +you need to provide a CLA and decorate the PR appropriately (e.g., label, +comment). Simply follow the instructions provided by the bot. You will only +need to do this once across all repos using our CLA. + +This project has adopted the +[Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information, see the +[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) +or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any +additional questions or comments. \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/assets.json b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/assets.json new file mode 100644 index 000000000..cd6e59432 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/assets.json @@ -0,0 +1,6 @@ +{ + "AssetsRepo": "Azure/azure-sdk-assets", + "AssetsRepoPrefixPath": "go", + "TagPrefix": "go/resourcemanager/resources/armresources", + "Tag": "go/resourcemanager/resources/armresources_ab8e63cc21" +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/autorest.md b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/autorest.md new file mode 100644 index 000000000..58dea419a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/autorest.md @@ -0,0 +1,13 @@ +### AutoRest Configuration + +> see https://aka.ms/autorest + +``` yaml +azure-arm: true +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.2.0 +package-resources: true +``` diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/build.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/build.go new file mode 100644 index 000000000..546b96f36 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/build.go @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// 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 ../../../../eng/scripts/build.ps1 -skipBuild -cleanGenerated -format -tidy -generate resourcemanager/resources/armresources + +package armresources diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/ci.yml b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/ci.yml new file mode 100644 index 000000000..bf846e65b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/ci.yml @@ -0,0 +1,28 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/resources/armresources/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/resourcemanager/resources/armresources/ + +stages: +- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + IncludeRelease: true + ServiceDirectory: 'resourcemanager/resources/armresources' diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/client.go new file mode 100644 index 000000000..46fde2c78 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/client.go @@ -0,0 +1,1042 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strconv" + "strings" +) + +// Client contains the methods for the Resources group. +// Don't use this type directly, use NewClient() instead. +type Client struct { + internal *arm.Client + subscriptionID string +} + +// NewClient creates a new instance of Client 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. +func NewClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*Client, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &Client{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// CheckExistence - Checks whether a resource exists. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group containing the resource to check. The name is case insensitive. +// - resourceProviderNamespace - The resource provider of the resource to check. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type. +// - resourceName - The name of the resource to check whether it exists. +// - apiVersion - The API version to use for the operation. +// - options - ClientCheckExistenceOptions contains the optional parameters for the Client.CheckExistence method. +func (client *Client) CheckExistence(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientCheckExistenceOptions) (ClientCheckExistenceResponse, error) { + var err error + const operationName = "Client.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, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) + if err != nil { + return ClientCheckExistenceResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientCheckExistenceResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return ClientCheckExistenceResponse{}, err + } + return ClientCheckExistenceResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceCreateRequest creates the CheckExistence request. +func (client *Client) checkExistenceCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientCheckExistenceOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckExistenceByID - Checks by ID whether a resource exists. +// +// Generated from API version 2021-04-01 +// - resourceID - The fully qualified ID of the resource, including the resource name and resource type. Use the format, +// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} +// - apiVersion - The API version to use for the operation. +// - options - ClientCheckExistenceByIDOptions contains the optional parameters for the Client.CheckExistenceByID method. +func (client *Client) CheckExistenceByID(ctx context.Context, resourceID string, apiVersion string, options *ClientCheckExistenceByIDOptions) (ClientCheckExistenceByIDResponse, error) { + var err error + const operationName = "Client.CheckExistenceByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkExistenceByIDCreateRequest(ctx, resourceID, apiVersion, options) + if err != nil { + return ClientCheckExistenceByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientCheckExistenceByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return ClientCheckExistenceByIDResponse{}, err + } + return ClientCheckExistenceByIDResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceByIDCreateRequest creates the CheckExistenceByID request. +func (client *Client) checkExistenceByIDCreateRequest(ctx context.Context, resourceID string, apiVersion string, options *ClientCheckExistenceByIDOptions) (*policy.Request, error) { + urlPath := "/{resourceId}" + urlPath = strings.ReplaceAll(urlPath, "{resourceId}", resourceID) + req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginCreateOrUpdate - Creates a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group for the resource. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type of the resource to create. +// - resourceName - The name of the resource to create. +// - apiVersion - The API version to use for the operation. +// - parameters - Parameters for creating or updating the resource. +// - options - ClientBeginCreateOrUpdateOptions contains the optional parameters for the Client.BeginCreateOrUpdate method. +func (client *Client) BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource, options *ClientBeginCreateOrUpdateOptions) (*runtime.Poller[ClientCreateOrUpdateResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdate(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientCreateOrUpdateResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientCreateOrUpdateResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdate - Creates a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) createOrUpdate(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource, options *ClientBeginCreateOrUpdateOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginCreateOrUpdate" + 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, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *Client) createOrUpdateCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource, options *ClientBeginCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginCreateOrUpdateByID - Create a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceID - The fully qualified ID of the resource, including the resource name and resource type. Use the format, +// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} +// - apiVersion - The API version to use for the operation. +// - parameters - Create or update resource parameters. +// - options - ClientBeginCreateOrUpdateByIDOptions contains the optional parameters for the Client.BeginCreateOrUpdateByID +// method. +func (client *Client) BeginCreateOrUpdateByID(ctx context.Context, resourceID string, apiVersion string, parameters GenericResource, options *ClientBeginCreateOrUpdateByIDOptions) (*runtime.Poller[ClientCreateOrUpdateByIDResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdateByID(ctx, resourceID, apiVersion, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientCreateOrUpdateByIDResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientCreateOrUpdateByIDResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdateByID - Create a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) createOrUpdateByID(ctx context.Context, resourceID string, apiVersion string, parameters GenericResource, options *ClientBeginCreateOrUpdateByIDOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginCreateOrUpdateByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createOrUpdateByIDCreateRequest(ctx, resourceID, apiVersion, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateByIDCreateRequest creates the CreateOrUpdateByID request. +func (client *Client) createOrUpdateByIDCreateRequest(ctx context.Context, resourceID string, apiVersion string, parameters GenericResource, options *ClientBeginCreateOrUpdateByIDOptions) (*policy.Request, error) { + urlPath := "/{resourceId}" + urlPath = strings.ReplaceAll(urlPath, "{resourceId}", resourceID) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginDelete - Deletes a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group that contains the resource to delete. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type. +// - resourceName - The name of the resource to delete. +// - apiVersion - The API version to use for the operation. +// - options - ClientBeginDeleteOptions contains the optional parameters for the Client.BeginDelete method. +func (client *Client) BeginDelete(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientBeginDeleteOptions) (*runtime.Poller[ClientDeleteResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteOperation(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientDeleteResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientDeleteResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// Delete - Deletes a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) deleteOperation(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientBeginDeleteOptions) (*http.Response, error) { + var err error + const operationName = "Client.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, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *Client) deleteCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientBeginDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginDeleteByID - Deletes a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceID - The fully qualified ID of the resource, including the resource name and resource type. Use the format, +// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} +// - apiVersion - The API version to use for the operation. +// - options - ClientBeginDeleteByIDOptions contains the optional parameters for the Client.BeginDeleteByID method. +func (client *Client) BeginDeleteByID(ctx context.Context, resourceID string, apiVersion string, options *ClientBeginDeleteByIDOptions) (*runtime.Poller[ClientDeleteByIDResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteByID(ctx, resourceID, apiVersion, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientDeleteByIDResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientDeleteByIDResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// DeleteByID - Deletes a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) deleteByID(ctx context.Context, resourceID string, apiVersion string, options *ClientBeginDeleteByIDOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginDeleteByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteByIDCreateRequest(ctx, resourceID, apiVersion, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteByIDCreateRequest creates the DeleteByID request. +func (client *Client) deleteByIDCreateRequest(ctx context.Context, resourceID string, apiVersion string, options *ClientBeginDeleteByIDOptions) (*policy.Request, error) { + urlPath := "/{resourceId}" + urlPath = strings.ReplaceAll(urlPath, "{resourceId}", resourceID) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// Get - Gets a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group containing the resource to get. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type of the resource. +// - resourceName - The name of the resource to get. +// - apiVersion - The API version to use for the operation. +// - options - ClientGetOptions contains the optional parameters for the Client.Get method. +func (client *Client) Get(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientGetOptions) (ClientGetResponse, error) { + var err error + const operationName = "Client.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, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, options) + if err != nil { + return ClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *Client) getCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, options *ClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *Client) getHandleResponse(resp *http.Response) (ClientGetResponse, error) { + result := ClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.GenericResource); err != nil { + return ClientGetResponse{}, err + } + return result, nil +} + +// GetByID - Gets a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceID - The fully qualified ID of the resource, including the resource name and resource type. Use the format, +// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} +// - apiVersion - The API version to use for the operation. +// - options - ClientGetByIDOptions contains the optional parameters for the Client.GetByID method. +func (client *Client) GetByID(ctx context.Context, resourceID string, apiVersion string, options *ClientGetByIDOptions) (ClientGetByIDResponse, error) { + var err error + const operationName = "Client.GetByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.getByIDCreateRequest(ctx, resourceID, apiVersion, options) + if err != nil { + return ClientGetByIDResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetByIDResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetByIDResponse{}, err + } + resp, err := client.getByIDHandleResponse(httpResp) + return resp, err +} + +// getByIDCreateRequest creates the GetByID request. +func (client *Client) getByIDCreateRequest(ctx context.Context, resourceID string, apiVersion string, options *ClientGetByIDOptions) (*policy.Request, error) { + urlPath := "/{resourceId}" + urlPath = strings.ReplaceAll(urlPath, "{resourceId}", resourceID) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getByIDHandleResponse handles the GetByID response. +func (client *Client) getByIDHandleResponse(resp *http.Response) (ClientGetByIDResponse, error) { + result := ClientGetByIDResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.GenericResource); err != nil { + return ClientGetByIDResponse{}, err + } + return result, nil +} + +// NewListPager - Get all the resources in a subscription. +// +// Generated from API version 2021-04-01 +// - options - ClientListOptions contains the optional parameters for the Client.NewListPager method. +func (client *Client) NewListPager(options *ClientListOptions) *runtime.Pager[ClientListResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListResponse]{ + More: func(page ClientListResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListResponse) (ClientListResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "Client.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 ClientListResponse{}, err + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *Client) listCreateRequest(ctx context.Context, options *ClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resources" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *Client) listHandleResponse(resp *http.Response) (ClientListResponse, error) { + result := ClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ResourceListResult); err != nil { + return ClientListResponse{}, err + } + return result, nil +} + +// NewListByResourceGroupPager - Get all the resources for a resource group. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The resource group with the resources to get. +// - options - ClientListByResourceGroupOptions contains the optional parameters for the Client.NewListByResourceGroupPager +// method. +func (client *Client) NewListByResourceGroupPager(resourceGroupName string, options *ClientListByResourceGroupOptions) *runtime.Pager[ClientListByResourceGroupResponse] { + return runtime.NewPager(runtime.PagingHandler[ClientListByResourceGroupResponse]{ + More: func(page ClientListByResourceGroupResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *ClientListByResourceGroupResponse) (ClientListByResourceGroupResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "Client.NewListByResourceGroupPager") + 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.listByResourceGroupCreateRequest(ctx, resourceGroupName, options) + }, nil) + if err != nil { + return ClientListByResourceGroupResponse{}, err + } + return client.listByResourceGroupHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listByResourceGroupCreateRequest creates the ListByResourceGroup request. +func (client *Client) listByResourceGroupCreateRequest(ctx context.Context, resourceGroupName string, options *ClientListByResourceGroupOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/resources" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listByResourceGroupHandleResponse handles the ListByResourceGroup response. +func (client *Client) listByResourceGroupHandleResponse(resp *http.Response) (ClientListByResourceGroupResponse, error) { + result := ClientListByResourceGroupResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ResourceListResult); err != nil { + return ClientListByResourceGroupResponse{}, err + } + return result, nil +} + +// BeginMoveResources - The resources to be moved must be in the same source resource group in the source subscription being +// used. The target resource group may be in a different subscription. When moving resources, both the +// source group and the target group are locked for the duration of the operation. Write and delete operations are blocked +// on the groups until the move completes. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - sourceResourceGroupName - The name of the resource group from the source subscription containing the resources to be moved. +// - parameters - Parameters for moving resources. +// - options - ClientBeginMoveResourcesOptions contains the optional parameters for the Client.BeginMoveResources method. +func (client *Client) BeginMoveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo, options *ClientBeginMoveResourcesOptions) (*runtime.Poller[ClientMoveResourcesResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.moveResources(ctx, sourceResourceGroupName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientMoveResourcesResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientMoveResourcesResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// MoveResources - The resources to be moved must be in the same source resource group in the source subscription being used. +// The target resource group may be in a different subscription. When moving resources, both the +// source group and the target group are locked for the duration of the operation. Write and delete operations are blocked +// on the groups until the move completes. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) moveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo, options *ClientBeginMoveResourcesOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginMoveResources" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.moveResourcesCreateRequest(ctx, sourceResourceGroupName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// moveResourcesCreateRequest creates the MoveResources request. +func (client *Client) moveResourcesCreateRequest(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo, options *ClientBeginMoveResourcesOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/moveResources" + if sourceResourceGroupName == "" { + return nil, errors.New("parameter sourceResourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{sourceResourceGroupName}", url.PathEscape(sourceResourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginUpdate - Updates a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group for the resource. The name is case insensitive. +// - resourceProviderNamespace - The namespace of the resource provider. +// - parentResourcePath - The parent resource identity. +// - resourceType - The resource type of the resource to update. +// - resourceName - The name of the resource to update. +// - apiVersion - The API version to use for the operation. +// - parameters - Parameters for updating the resource. +// - options - ClientBeginUpdateOptions contains the optional parameters for the Client.BeginUpdate method. +func (client *Client) BeginUpdate(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource, options *ClientBeginUpdateOptions) (*runtime.Poller[ClientUpdateResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.update(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientUpdateResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientUpdateResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// Update - Updates a resource. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) update(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource, options *ClientBeginUpdateOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginUpdate" + 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, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// updateCreateRequest creates the Update request. +func (client *Client) updateCreateRequest(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource, options *ClientBeginUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + urlPath = strings.ReplaceAll(urlPath, "{parentResourcePath}", parentResourcePath) + urlPath = strings.ReplaceAll(urlPath, "{resourceType}", resourceType) + if resourceName == "" { + return nil, errors.New("parameter resourceName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceName}", url.PathEscape(resourceName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginUpdateByID - Updates a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceID - The fully qualified ID of the resource, including the resource name and resource type. Use the format, +// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name} +// - apiVersion - The API version to use for the operation. +// - parameters - Update resource parameters. +// - options - ClientBeginUpdateByIDOptions contains the optional parameters for the Client.BeginUpdateByID method. +func (client *Client) BeginUpdateByID(ctx context.Context, resourceID string, apiVersion string, parameters GenericResource, options *ClientBeginUpdateByIDOptions) (*runtime.Poller[ClientUpdateByIDResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.updateByID(ctx, resourceID, apiVersion, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientUpdateByIDResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientUpdateByIDResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// UpdateByID - Updates a resource by ID. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) updateByID(ctx context.Context, resourceID string, apiVersion string, parameters GenericResource, options *ClientBeginUpdateByIDOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginUpdateByID" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.updateByIDCreateRequest(ctx, resourceID, apiVersion, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// updateByIDCreateRequest creates the UpdateByID request. +func (client *Client) updateByIDCreateRequest(ctx context.Context, resourceID string, apiVersion string, parameters GenericResource, options *ClientBeginUpdateByIDOptions) (*policy.Request, error) { + urlPath := "/{resourceId}" + urlPath = strings.ReplaceAll(urlPath, "{resourceId}", resourceID) + req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", apiVersion) + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginValidateMoveResources - This operation checks whether the specified resources can be moved to the target. The resources +// to be moved must be in the same source resource group in the source subscription being used. The target +// resource group may be in a different subscription. If validation succeeds, it returns HTTP response code 204 (no content). +// If validation fails, it returns HTTP response code 409 (Conflict) with an +// error message. Retrieve the URL in the Location header value to check the result of the long-running operation. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - sourceResourceGroupName - The name of the resource group from the source subscription containing the resources to be validated +// for move. +// - parameters - Parameters for moving resources. +// - options - ClientBeginValidateMoveResourcesOptions contains the optional parameters for the Client.BeginValidateMoveResources +// method. +func (client *Client) BeginValidateMoveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo, options *ClientBeginValidateMoveResourcesOptions) (*runtime.Poller[ClientValidateMoveResourcesResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.validateMoveResources(ctx, sourceResourceGroupName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ClientValidateMoveResourcesResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ClientValidateMoveResourcesResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// ValidateMoveResources - This operation checks whether the specified resources can be moved to the target. The resources +// to be moved must be in the same source resource group in the source subscription being used. The target +// resource group may be in a different subscription. If validation succeeds, it returns HTTP response code 204 (no content). +// If validation fails, it returns HTTP response code 409 (Conflict) with an +// error message. Retrieve the URL in the Location header value to check the result of the long-running operation. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *Client) validateMoveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo, options *ClientBeginValidateMoveResourcesOptions) (*http.Response, error) { + var err error + const operationName = "Client.BeginValidateMoveResources" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateMoveResourcesCreateRequest(ctx, sourceResourceGroupName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// validateMoveResourcesCreateRequest creates the ValidateMoveResources request. +func (client *Client) validateMoveResourcesCreateRequest(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo, options *ClientBeginValidateMoveResourcesOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/validateMoveResources" + if sourceResourceGroupName == "" { + return nil, errors.New("parameter sourceResourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{sourceResourceGroupName}", url.PathEscape(sourceResourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/client_factory.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/client_factory.go new file mode 100644 index 000000000..bcd6487d6 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/client_factory.go @@ -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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/constants.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/constants.go new file mode 100644 index 000000000..6cf0f0dc3 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/constants.go @@ -0,0 +1,402 @@ +//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 + +const ( + 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. +type AliasPathAttributes string + +const ( + // AliasPathAttributesModifiable - The token that the alias path is referring to is modifiable by policies with 'modify' effect. + AliasPathAttributesModifiable AliasPathAttributes = "Modifiable" + // AliasPathAttributesNone - The token that the alias path is referring to has no attributes. + AliasPathAttributesNone AliasPathAttributes = "None" +) + +// PossibleAliasPathAttributesValues returns the possible values for the AliasPathAttributes const type. +func PossibleAliasPathAttributesValues() []AliasPathAttributes { + return []AliasPathAttributes{ + AliasPathAttributesModifiable, + AliasPathAttributesNone, + } +} + +// AliasPathTokenType - The type of the token that the alias path is referring to. +type AliasPathTokenType string + +const ( + // AliasPathTokenTypeAny - The token type can be anything. + AliasPathTokenTypeAny AliasPathTokenType = "Any" + // AliasPathTokenTypeArray - The token type is array. + AliasPathTokenTypeArray AliasPathTokenType = "Array" + // AliasPathTokenTypeBoolean - The token type is boolean. + AliasPathTokenTypeBoolean AliasPathTokenType = "Boolean" + // AliasPathTokenTypeInteger - The token type is integer. + AliasPathTokenTypeInteger AliasPathTokenType = "Integer" + // AliasPathTokenTypeNotSpecified - The token type is not specified. + AliasPathTokenTypeNotSpecified AliasPathTokenType = "NotSpecified" + // AliasPathTokenTypeNumber - The token type is number. + AliasPathTokenTypeNumber AliasPathTokenType = "Number" + // AliasPathTokenTypeObject - The token type is object. + AliasPathTokenTypeObject AliasPathTokenType = "Object" + // AliasPathTokenTypeString - The token type is string. + AliasPathTokenTypeString AliasPathTokenType = "String" +) + +// PossibleAliasPathTokenTypeValues returns the possible values for the AliasPathTokenType const type. +func PossibleAliasPathTokenTypeValues() []AliasPathTokenType { + return []AliasPathTokenType{ + AliasPathTokenTypeAny, + AliasPathTokenTypeArray, + AliasPathTokenTypeBoolean, + AliasPathTokenTypeInteger, + AliasPathTokenTypeNotSpecified, + AliasPathTokenTypeNumber, + AliasPathTokenTypeObject, + AliasPathTokenTypeString, + } +} + +// AliasPatternType - The type of alias pattern +type AliasPatternType string + +const ( + // 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{ + AliasPatternTypeExtract, + AliasPatternTypeNotSpecified, + } +} + +// AliasType - The type of the alias. +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" +) + +// PossibleAliasTypeValues returns the possible values for the AliasType const type. +func PossibleAliasTypeValues() []AliasType { + return []AliasType{ + AliasTypeMask, + AliasTypeNotSpecified, + AliasTypePlainText, + } +} + +// ChangeType - Type of change that will be made to the resource when the deployment is executed. +type ChangeType string + +const ( + // ChangeTypeCreate - The resource does not exist in the current state but is present in the desired state. The resource will + // be created when the deployment is executed. + ChangeTypeCreate ChangeType = "Create" + // 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" + // 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" + // 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" +) + +// PossibleChangeTypeValues returns the possible values for the ChangeType const type. +func PossibleChangeTypeValues() []ChangeType { + return []ChangeType{ + ChangeTypeCreate, + ChangeTypeDelete, + ChangeTypeDeploy, + ChangeTypeIgnore, + ChangeTypeModify, + ChangeTypeNoChange, + ChangeTypeUnsupported, + } +} + +// DeploymentMode - The mode that is used to deploy resources. This value can be either Incremental or Complete. In Incremental +// mode, resources are deployed without deleting existing resources that are not included in +// the template. In Complete mode, resources are deployed and existing resources in the resource group that are not included +// in the template are deleted. Be careful when using Complete mode as you may +// unintentionally delete resources. +type DeploymentMode string + +const ( + DeploymentModeComplete DeploymentMode = "Complete" + DeploymentModeIncremental DeploymentMode = "Incremental" +) + +// PossibleDeploymentModeValues returns the possible values for the DeploymentMode const type. +func PossibleDeploymentModeValues() []DeploymentMode { + return []DeploymentMode{ + DeploymentModeComplete, + DeploymentModeIncremental, + } +} + +// ExpressionEvaluationOptionsScopeType - The scope to be used for evaluation of parameters, variables and functions in a +// nested template. +type ExpressionEvaluationOptionsScopeType string + +const ( + ExpressionEvaluationOptionsScopeTypeInner ExpressionEvaluationOptionsScopeType = "Inner" + ExpressionEvaluationOptionsScopeTypeNotSpecified ExpressionEvaluationOptionsScopeType = "NotSpecified" + ExpressionEvaluationOptionsScopeTypeOuter ExpressionEvaluationOptionsScopeType = "Outer" +) + +// PossibleExpressionEvaluationOptionsScopeTypeValues returns the possible values for the ExpressionEvaluationOptionsScopeType const type. +func PossibleExpressionEvaluationOptionsScopeTypeValues() []ExpressionEvaluationOptionsScopeType { + return []ExpressionEvaluationOptionsScopeType{ + ExpressionEvaluationOptionsScopeTypeInner, + ExpressionEvaluationOptionsScopeTypeNotSpecified, + ExpressionEvaluationOptionsScopeTypeOuter, + } +} + +// ExtendedLocationType - The extended location type. +type ExtendedLocationType string + +const ( + ExtendedLocationTypeEdgeZone ExtendedLocationType = "EdgeZone" +) + +// PossibleExtendedLocationTypeValues returns the possible values for the ExtendedLocationType const type. +func PossibleExtendedLocationTypeValues() []ExtendedLocationType { + return []ExtendedLocationType{ + ExtendedLocationTypeEdgeZone, + } +} + +// OnErrorDeploymentType - The deployment on error behavior type. Possible values are LastSuccessful and SpecificDeployment. +type OnErrorDeploymentType string + +const ( + OnErrorDeploymentTypeLastSuccessful OnErrorDeploymentType = "LastSuccessful" + OnErrorDeploymentTypeSpecificDeployment OnErrorDeploymentType = "SpecificDeployment" +) + +// PossibleOnErrorDeploymentTypeValues returns the possible values for the OnErrorDeploymentType const type. +func PossibleOnErrorDeploymentTypeValues() []OnErrorDeploymentType { + return []OnErrorDeploymentType{ + OnErrorDeploymentTypeLastSuccessful, + OnErrorDeploymentTypeSpecificDeployment, + } +} + +// PropertyChangeType - The type of property change. +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" + // PropertyChangeTypeDelete - The property exists in the current state and is missing from the desired state. It will be deleted + // when the deployment is executed. + PropertyChangeTypeDelete PropertyChangeType = "Delete" + // 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" + // PropertyChangeTypeNoEffect - The property will not be set or updated. + PropertyChangeTypeNoEffect PropertyChangeType = "NoEffect" +) + +// PossiblePropertyChangeTypeValues returns the possible values for the PropertyChangeType const type. +func PossiblePropertyChangeTypeValues() []PropertyChangeType { + return []PropertyChangeType{ + PropertyChangeTypeArray, + PropertyChangeTypeCreate, + PropertyChangeTypeDelete, + PropertyChangeTypeModify, + PropertyChangeTypeNoEffect, + } +} + +// ProviderAuthorizationConsentState - The provider authorization consent state. +type ProviderAuthorizationConsentState string + +const ( + ProviderAuthorizationConsentStateConsented ProviderAuthorizationConsentState = "Consented" + ProviderAuthorizationConsentStateNotRequired ProviderAuthorizationConsentState = "NotRequired" + ProviderAuthorizationConsentStateNotSpecified ProviderAuthorizationConsentState = "NotSpecified" + ProviderAuthorizationConsentStateRequired ProviderAuthorizationConsentState = "Required" +) + +// PossibleProviderAuthorizationConsentStateValues returns the possible values for the ProviderAuthorizationConsentState const type. +func PossibleProviderAuthorizationConsentStateValues() []ProviderAuthorizationConsentState { + return []ProviderAuthorizationConsentState{ + ProviderAuthorizationConsentStateConsented, + ProviderAuthorizationConsentStateNotRequired, + ProviderAuthorizationConsentStateNotSpecified, + ProviderAuthorizationConsentStateRequired, + } +} + +// ProvisioningOperation - The name of the current provisioning operation. +type ProvisioningOperation string + +const ( + // 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" + // 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{ + ProvisioningOperationAction, + ProvisioningOperationAzureAsyncOperationWaiting, + ProvisioningOperationCreate, + ProvisioningOperationDelete, + ProvisioningOperationDeploymentCleanup, + ProvisioningOperationEvaluateDeploymentOutput, + ProvisioningOperationNotSpecified, + ProvisioningOperationRead, + ProvisioningOperationResourceCacheWaiting, + ProvisioningOperationWaiting, + } +} + +// ProvisioningState - Denotes the state of provisioning. +type ProvisioningState string + +const ( + ProvisioningStateAccepted ProvisioningState = "Accepted" + ProvisioningStateCanceled ProvisioningState = "Canceled" + ProvisioningStateCreated ProvisioningState = "Created" + ProvisioningStateCreating ProvisioningState = "Creating" + ProvisioningStateDeleted ProvisioningState = "Deleted" + ProvisioningStateDeleting ProvisioningState = "Deleting" + ProvisioningStateFailed ProvisioningState = "Failed" + ProvisioningStateNotSpecified ProvisioningState = "NotSpecified" + ProvisioningStateReady ProvisioningState = "Ready" + ProvisioningStateRunning ProvisioningState = "Running" + ProvisioningStateSucceeded ProvisioningState = "Succeeded" + ProvisioningStateUpdating ProvisioningState = "Updating" +) + +// PossibleProvisioningStateValues returns the possible values for the ProvisioningState const type. +func PossibleProvisioningStateValues() []ProvisioningState { + return []ProvisioningState{ + ProvisioningStateAccepted, + ProvisioningStateCanceled, + ProvisioningStateCreated, + ProvisioningStateCreating, + ProvisioningStateDeleted, + ProvisioningStateDeleting, + ProvisioningStateFailed, + ProvisioningStateNotSpecified, + ProvisioningStateReady, + ProvisioningStateRunning, + ProvisioningStateSucceeded, + ProvisioningStateUpdating, + } +} + +// ResourceIdentityType - The identity type. +type ResourceIdentityType string + +const ( + 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{ + ResourceIdentityTypeNone, + ResourceIdentityTypeSystemAssigned, + ResourceIdentityTypeSystemAssignedUserAssigned, + ResourceIdentityTypeUserAssigned, + } +} + +// TagsPatchOperation - The operation type for the patch API. +type TagsPatchOperation string + +const ( + // TagsPatchOperationDelete - The 'delete' option allows selectively deleting tags based on given names or name/value pairs. + TagsPatchOperationDelete TagsPatchOperation = "Delete" + // TagsPatchOperationMerge - The 'merge' option allows adding tags with new names and updating the values of tags with existing + // names. + TagsPatchOperationMerge TagsPatchOperation = "Merge" + // TagsPatchOperationReplace - The 'replace' option replaces the entire set of existing tags with a new set. + TagsPatchOperationReplace TagsPatchOperation = "Replace" +) + +// PossibleTagsPatchOperationValues returns the possible values for the TagsPatchOperation const type. +func PossibleTagsPatchOperationValues() []TagsPatchOperation { + return []TagsPatchOperation{ + TagsPatchOperationDelete, + TagsPatchOperationMerge, + TagsPatchOperationReplace, + } +} + +// WhatIfResultFormat - The format of the What-If results +type WhatIfResultFormat string + +const ( + WhatIfResultFormatFullResourcePayloads WhatIfResultFormat = "FullResourcePayloads" + WhatIfResultFormatResourceIDOnly WhatIfResultFormat = "ResourceIdOnly" +) + +// PossibleWhatIfResultFormatValues returns the possible values for the WhatIfResultFormat const type. +func PossibleWhatIfResultFormatValues() []WhatIfResultFormat { + return []WhatIfResultFormat{ + WhatIfResultFormatFullResourcePayloads, + WhatIfResultFormatResourceIDOnly, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/deploymentoperations_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/deploymentoperations_client.go new file mode 100644 index 000000000..ec1e1ab80 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/deploymentoperations_client.go @@ -0,0 +1,685 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strconv" + "strings" +) + +// DeploymentOperationsClient contains the methods for the DeploymentOperations group. +// Don't use this type directly, use NewDeploymentOperationsClient() instead. +type DeploymentOperationsClient struct { + internal *arm.Client + subscriptionID string +} + +// 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. +func NewDeploymentOperationsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*DeploymentOperationsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &DeploymentOperationsClient{ + subscriptionID: subscriptionID, + 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentOperationsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentOperationsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *DeploymentOperationsClient) getCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, operationID string, options *DeploymentOperationsClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations/{operationId}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if operationID == "" { + return nil, errors.New("parameter operationID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{operationId}", url.PathEscape(operationID)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *DeploymentOperationsClient) getHandleResponse(resp *http.Response) (DeploymentOperationsClientGetResponse, error) { + result := DeploymentOperationsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperation); err != nil { + return DeploymentOperationsClientGetResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, err + } + resp, err := client.getAtManagementGroupScopeHandleResponse(httpResp) + return resp, err +} + +// getAtManagementGroupScopeCreateRequest creates the GetAtManagementGroupScope request. +func (client *DeploymentOperationsClient) getAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if operationID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtManagementGroupScopeHandleResponse handles the GetAtManagementGroupScope response. +func (client *DeploymentOperationsClient) getAtManagementGroupScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientGetAtManagementGroupScopeResponse, error) { + result := DeploymentOperationsClientGetAtManagementGroupScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperation); err != nil { + return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentOperationsClientGetAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentOperationsClientGetAtScopeResponse{}, err + } + resp, err := client.getAtScopeHandleResponse(httpResp) + return resp, err +} + +// getAtScopeCreateRequest creates the GetAtScope request. +func (client *DeploymentOperationsClient) getAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if operationID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtScopeHandleResponse handles the GetAtScope response. +func (client *DeploymentOperationsClient) getAtScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientGetAtScopeResponse, error) { + result := DeploymentOperationsClientGetAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperation); err != nil { + return DeploymentOperationsClientGetAtScopeResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, err + } + resp, err := client.getAtSubscriptionScopeHandleResponse(httpResp) + return resp, err +} + +// getAtSubscriptionScopeCreateRequest creates the GetAtSubscriptionScope request. +func (client *DeploymentOperationsClient) getAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if operationID == "" { + return nil, errors.New("parameter operationID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{operationId}", url.PathEscape(operationID)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtSubscriptionScopeHandleResponse handles the GetAtSubscriptionScope response. +func (client *DeploymentOperationsClient) getAtSubscriptionScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientGetAtSubscriptionScopeResponse, error) { + result := DeploymentOperationsClientGetAtSubscriptionScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperation); err != nil { + return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentOperationsClientGetAtTenantScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentOperationsClientGetAtTenantScopeResponse{}, err + } + resp, err := client.getAtTenantScopeHandleResponse(httpResp) + return resp, err +} + +// getAtTenantScopeCreateRequest creates the GetAtTenantScope request. +func (client *DeploymentOperationsClient) getAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}/operations/{operationId}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if operationID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtTenantScopeHandleResponse handles the GetAtTenantScope response. +func (client *DeploymentOperationsClient) getAtTenantScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientGetAtTenantScopeResponse, error) { + result := DeploymentOperationsClientGetAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperation); err != nil { + return DeploymentOperationsClientGetAtTenantScopeResponse{}, err + } + return result, nil +} + +// NewListPager - Gets all deployments operations for a deployment. +// +// 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.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) { + 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 + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *DeploymentOperationsClient) listCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentOperationsClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *DeploymentOperationsClient) listHandleResponse(resp *http.Response) (DeploymentOperationsClientListResponse, error) { + result := DeploymentOperationsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperationsListResult); err != nil { + return DeploymentOperationsClientListResponse{}, err + } + return result, nil +} + +// NewListAtManagementGroupScopePager - Gets all deployments operations for a deployment. +// +// 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.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) { + 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 + } + return client.listAtManagementGroupScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtManagementGroupScopeCreateRequest creates the ListAtManagementGroupScope request. +func (client *DeploymentOperationsClient) listAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, options *DeploymentOperationsClientListAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtManagementGroupScopeHandleResponse handles the ListAtManagementGroupScope response. +func (client *DeploymentOperationsClient) listAtManagementGroupScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientListAtManagementGroupScopeResponse, error) { + result := DeploymentOperationsClientListAtManagementGroupScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperationsListResult); err != nil { + return DeploymentOperationsClientListAtManagementGroupScopeResponse{}, err + } + return result, nil +} + +// NewListAtScopePager - Gets all deployments operations for a deployment. +// +// 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.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) { + 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 + } + return client.listAtScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtScopeCreateRequest creates the ListAtScope request. +func (client *DeploymentOperationsClient) listAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, options *DeploymentOperationsClientListAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/operations" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtScopeHandleResponse handles the ListAtScope response. +func (client *DeploymentOperationsClient) listAtScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientListAtScopeResponse, error) { + result := DeploymentOperationsClientListAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperationsListResult); err != nil { + return DeploymentOperationsClientListAtScopeResponse{}, err + } + return result, nil +} + +// NewListAtSubscriptionScopePager - Gets all deployments operations for a deployment. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + return client.listAtSubscriptionScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtSubscriptionScopeCreateRequest creates the ListAtSubscriptionScope request. +func (client *DeploymentOperationsClient) listAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentOperationsClientListAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/operations" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtSubscriptionScopeHandleResponse handles the ListAtSubscriptionScope response. +func (client *DeploymentOperationsClient) listAtSubscriptionScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientListAtSubscriptionScopeResponse, error) { + result := DeploymentOperationsClientListAtSubscriptionScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperationsListResult); err != nil { + return DeploymentOperationsClientListAtSubscriptionScopeResponse{}, err + } + return result, nil +} + +// NewListAtTenantScopePager - Gets all deployments operations for a deployment. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + return client.listAtTenantScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtTenantScopeCreateRequest creates the ListAtTenantScope request. +func (client *DeploymentOperationsClient) listAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentOperationsClientListAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}/operations" + if deploymentName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtTenantScopeHandleResponse handles the ListAtTenantScope response. +func (client *DeploymentOperationsClient) listAtTenantScopeHandleResponse(resp *http.Response) (DeploymentOperationsClientListAtTenantScopeResponse, error) { + result := DeploymentOperationsClientListAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentOperationsListResult); err != nil { + return DeploymentOperationsClientListAtTenantScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/deployments_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/deployments_client.go new file mode 100644 index 000000000..2e9eff6b7 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/deployments_client.go @@ -0,0 +1,2995 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strconv" + "strings" +) + +// DeploymentsClient contains the methods for the Deployments group. +// Don't use this type directly, use NewDeploymentsClient() instead. +type DeploymentsClient struct { + internal *arm.Client + subscriptionID string +} + +// NewDeploymentsClient creates a new instance of DeploymentsClient 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. +func NewDeploymentsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*DeploymentsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &DeploymentsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// CalculateTemplateHash - Calculate the hash of the given template. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - templateParam - The template provided to calculate hash. +// - options - DeploymentsClientCalculateTemplateHashOptions contains the optional parameters for the DeploymentsClient.CalculateTemplateHash +// method. +func (client *DeploymentsClient) CalculateTemplateHash(ctx context.Context, templateParam any, options *DeploymentsClientCalculateTemplateHashOptions) (DeploymentsClientCalculateTemplateHashResponse, error) { + var err error + const operationName = "DeploymentsClient.CalculateTemplateHash" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.calculateTemplateHashCreateRequest(ctx, templateParam, options) + if err != nil { + return DeploymentsClientCalculateTemplateHashResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCalculateTemplateHashResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCalculateTemplateHashResponse{}, err + } + resp, err := client.calculateTemplateHashHandleResponse(httpResp) + return resp, err +} + +// calculateTemplateHashCreateRequest creates the CalculateTemplateHash request. +func (client *DeploymentsClient) calculateTemplateHashCreateRequest(ctx context.Context, templateParam any, options *DeploymentsClientCalculateTemplateHashOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/calculateTemplateHash" + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, templateParam); err != nil { + return nil, err + } + return req, nil +} + +// calculateTemplateHashHandleResponse handles the CalculateTemplateHash response. +func (client *DeploymentsClient) calculateTemplateHashHandleResponse(resp *http.Response) (DeploymentsClientCalculateTemplateHashResponse, error) { + result := DeploymentsClientCalculateTemplateHashResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TemplateHashResult); err != nil { + return DeploymentsClientCalculateTemplateHashResponse{}, err + } + return result, nil +} + +// Cancel - You can cancel a deployment only if the provisioningState is Accepted or Running. After the deployment is canceled, +// the provisioningState is set to Canceled. Canceling a template deployment stops the +// currently running template deployment and leaves the resource group partially deployed. +// 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 - DeploymentsClientCancelOptions contains the optional parameters for the DeploymentsClient.Cancel method. +func (client *DeploymentsClient) Cancel(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientCancelOptions) (DeploymentsClientCancelResponse, error) { + var err error + const operationName = "DeploymentsClient.Cancel" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelCreateRequest(ctx, resourceGroupName, deploymentName, options) + if err != nil { + return DeploymentsClientCancelResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCancelResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCancelResponse{}, err + } + return DeploymentsClientCancelResponse{}, nil +} + +// cancelCreateRequest creates the Cancel request. +func (client *DeploymentsClient) cancelCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientCancelOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CancelAtManagementGroupScope - You can cancel a deployment only if the provisioningState is Accepted or Running. After +// the deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment stops the +// currently running template deployment and leaves the resources partially deployed. +// 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 - DeploymentsClientCancelAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtManagementGroupScope +// method. +func (client *DeploymentsClient) CancelAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientCancelAtManagementGroupScopeOptions) (DeploymentsClientCancelAtManagementGroupScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CancelAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, options) + if err != nil { + return DeploymentsClientCancelAtManagementGroupScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCancelAtManagementGroupScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCancelAtManagementGroupScopeResponse{}, err + } + return DeploymentsClientCancelAtManagementGroupScopeResponse{}, nil +} + +// cancelAtManagementGroupScopeCreateRequest creates the CancelAtManagementGroupScope request. +func (client *DeploymentsClient) cancelAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientCancelAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CancelAtScope - You can cancel a deployment only if the provisioningState is Accepted or Running. After the deployment +// is canceled, the provisioningState is set to Canceled. Canceling a template deployment stops the +// currently running template deployment and leaves the resources partially deployed. +// 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 - DeploymentsClientCancelAtScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtScope +// method. +func (client *DeploymentsClient) CancelAtScope(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientCancelAtScopeOptions) (DeploymentsClientCancelAtScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CancelAtScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelAtScopeCreateRequest(ctx, scope, deploymentName, options) + if err != nil { + return DeploymentsClientCancelAtScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCancelAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCancelAtScopeResponse{}, err + } + return DeploymentsClientCancelAtScopeResponse{}, nil +} + +// cancelAtScopeCreateRequest creates the CancelAtScope request. +func (client *DeploymentsClient) cancelAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientCancelAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CancelAtSubscriptionScope - You can cancel a deployment only if the provisioningState is Accepted or Running. After the +// deployment is canceled, the provisioningState is set to Canceled. Canceling a template deployment stops the +// currently running template deployment and leaves the resources partially deployed. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCancelAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtSubscriptionScope +// method. +func (client *DeploymentsClient) CancelAtSubscriptionScope(ctx context.Context, deploymentName string, options *DeploymentsClientCancelAtSubscriptionScopeOptions) (DeploymentsClientCancelAtSubscriptionScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CancelAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelAtSubscriptionScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return DeploymentsClientCancelAtSubscriptionScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCancelAtSubscriptionScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCancelAtSubscriptionScopeResponse{}, err + } + return DeploymentsClientCancelAtSubscriptionScopeResponse{}, nil +} + +// cancelAtSubscriptionScopeCreateRequest creates the CancelAtSubscriptionScope request. +func (client *DeploymentsClient) cancelAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientCancelAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CancelAtTenantScope - You can cancel a deployment only if the provisioningState is Accepted or Running. After the deployment +// is canceled, the provisioningState is set to Canceled. Canceling a template deployment stops the +// currently running template deployment and leaves the resources partially deployed. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCancelAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtTenantScope +// method. +func (client *DeploymentsClient) CancelAtTenantScope(ctx context.Context, deploymentName string, options *DeploymentsClientCancelAtTenantScopeOptions) (DeploymentsClientCancelAtTenantScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CancelAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.cancelAtTenantScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return DeploymentsClientCancelAtTenantScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCancelAtTenantScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCancelAtTenantScopeResponse{}, err + } + return DeploymentsClientCancelAtTenantScopeResponse{}, nil +} + +// cancelAtTenantScopeCreateRequest creates the CancelAtTenantScope request. +func (client *DeploymentsClient) cancelAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientCancelAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}/cancel" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckExistence - Checks whether the deployment exists. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group with the deployment to check. The name is case insensitive. +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCheckExistenceOptions contains the optional parameters for the DeploymentsClient.CheckExistence +// method. +func (client *DeploymentsClient) CheckExistence(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientCheckExistenceOptions) (DeploymentsClientCheckExistenceResponse, error) { + var err error + const operationName = "DeploymentsClient.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, deploymentName, options) + if err != nil { + return DeploymentsClientCheckExistenceResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCheckExistenceResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCheckExistenceResponse{}, err + } + return DeploymentsClientCheckExistenceResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceCreateRequest creates the CheckExistence request. +func (client *DeploymentsClient) checkExistenceCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientCheckExistenceOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckExistenceAtManagementGroupScope - Checks whether the deployment exists. +// +// Generated from API version 2021-04-01 +// - groupID - The management group ID. +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCheckExistenceAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtManagementGroupScope +// method. +func (client *DeploymentsClient) CheckExistenceAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientCheckExistenceAtManagementGroupScopeOptions) (DeploymentsClientCheckExistenceAtManagementGroupScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CheckExistenceAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkExistenceAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, options) + if err != nil { + return DeploymentsClientCheckExistenceAtManagementGroupScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCheckExistenceAtManagementGroupScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCheckExistenceAtManagementGroupScopeResponse{}, err + } + return DeploymentsClientCheckExistenceAtManagementGroupScopeResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceAtManagementGroupScopeCreateRequest creates the CheckExistenceAtManagementGroupScope request. +func (client *DeploymentsClient) checkExistenceAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientCheckExistenceAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckExistenceAtScope - Checks whether the deployment exists. +// +// Generated from API version 2021-04-01 +// - scope - The resource scope. +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCheckExistenceAtScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtScope +// method. +func (client *DeploymentsClient) CheckExistenceAtScope(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientCheckExistenceAtScopeOptions) (DeploymentsClientCheckExistenceAtScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CheckExistenceAtScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkExistenceAtScopeCreateRequest(ctx, scope, deploymentName, options) + if err != nil { + return DeploymentsClientCheckExistenceAtScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCheckExistenceAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCheckExistenceAtScopeResponse{}, err + } + return DeploymentsClientCheckExistenceAtScopeResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceAtScopeCreateRequest creates the CheckExistenceAtScope request. +func (client *DeploymentsClient) checkExistenceAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientCheckExistenceAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckExistenceAtSubscriptionScope - Checks whether the deployment exists. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCheckExistenceAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtSubscriptionScope +// method. +func (client *DeploymentsClient) CheckExistenceAtSubscriptionScope(ctx context.Context, deploymentName string, options *DeploymentsClientCheckExistenceAtSubscriptionScopeOptions) (DeploymentsClientCheckExistenceAtSubscriptionScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CheckExistenceAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkExistenceAtSubscriptionScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return DeploymentsClientCheckExistenceAtSubscriptionScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCheckExistenceAtSubscriptionScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCheckExistenceAtSubscriptionScopeResponse{}, err + } + return DeploymentsClientCheckExistenceAtSubscriptionScopeResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceAtSubscriptionScopeCreateRequest creates the CheckExistenceAtSubscriptionScope request. +func (client *DeploymentsClient) checkExistenceAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientCheckExistenceAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// CheckExistenceAtTenantScope - Checks whether the deployment exists. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientCheckExistenceAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtTenantScope +// method. +func (client *DeploymentsClient) CheckExistenceAtTenantScope(ctx context.Context, deploymentName string, options *DeploymentsClientCheckExistenceAtTenantScopeOptions) (DeploymentsClientCheckExistenceAtTenantScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.CheckExistenceAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.checkExistenceAtTenantScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return DeploymentsClientCheckExistenceAtTenantScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientCheckExistenceAtTenantScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientCheckExistenceAtTenantScopeResponse{}, err + } + return DeploymentsClientCheckExistenceAtTenantScopeResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceAtTenantScopeCreateRequest creates the CheckExistenceAtTenantScope request. +func (client *DeploymentsClient) checkExistenceAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientCheckExistenceAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginCreateOrUpdate - You can provide the template and parameters directly in the request or link to JSON files. +// 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 deploy the resources to. The name is case insensitive. The resource +// group must already exist. +// - deploymentName - The name of the deployment. +// - parameters - Additional parameters supplied to the operation. +// - options - DeploymentsClientBeginCreateOrUpdateOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdate +// method. +func (client *DeploymentsClient) BeginCreateOrUpdate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateOptions) (*runtime.Poller[DeploymentsClientCreateOrUpdateResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdate(ctx, resourceGroupName, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientCreateOrUpdateResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientCreateOrUpdateResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdate - You can provide the template and parameters directly in the request or link to JSON files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) createOrUpdate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginCreateOrUpdate" + 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, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *DeploymentsClient) createOrUpdateCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginCreateOrUpdateAtManagementGroupScope - You can provide the template and parameters directly in the request or link +// to JSON files. +// 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. +// - parameters - Additional parameters supplied to the operation. +// - options - DeploymentsClientBeginCreateOrUpdateAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtManagementGroupScope +// method. +func (client *DeploymentsClient) BeginCreateOrUpdateAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginCreateOrUpdateAtManagementGroupScopeOptions) (*runtime.Poller[DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdateAtManagementGroupScope(ctx, groupID, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdateAtManagementGroupScope - You can provide the template and parameters directly in the request or link to JSON +// files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) createOrUpdateAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginCreateOrUpdateAtManagementGroupScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginCreateOrUpdateAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createOrUpdateAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateAtManagementGroupScopeCreateRequest creates the CreateOrUpdateAtManagementGroupScope request. +func (client *DeploymentsClient) createOrUpdateAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginCreateOrUpdateAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginCreateOrUpdateAtScope - You can provide the template and parameters directly in the request or link to JSON files. +// 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. +// - parameters - Additional parameters supplied to the operation. +// - options - DeploymentsClientBeginCreateOrUpdateAtScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtScope +// method. +func (client *DeploymentsClient) BeginCreateOrUpdateAtScope(ctx context.Context, scope string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateAtScopeOptions) (*runtime.Poller[DeploymentsClientCreateOrUpdateAtScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdateAtScope(ctx, scope, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientCreateOrUpdateAtScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientCreateOrUpdateAtScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdateAtScope - You can provide the template and parameters directly in the request or link to JSON files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) createOrUpdateAtScope(ctx context.Context, scope string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateAtScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginCreateOrUpdateAtScope" + 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, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateAtScopeCreateRequest creates the CreateOrUpdateAtScope request. +func (client *DeploymentsClient) createOrUpdateAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginCreateOrUpdateAtSubscriptionScope - You can provide the template and parameters directly in the request or link to +// JSON files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - parameters - Additional parameters supplied to the operation. +// - options - DeploymentsClientBeginCreateOrUpdateAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtSubscriptionScope +// method. +func (client *DeploymentsClient) BeginCreateOrUpdateAtSubscriptionScope(ctx context.Context, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateAtSubscriptionScopeOptions) (*runtime.Poller[DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdateAtSubscriptionScope(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdateAtSubscriptionScope - You can provide the template and parameters directly in the request or link to JSON +// files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) createOrUpdateAtSubscriptionScope(ctx context.Context, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateAtSubscriptionScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginCreateOrUpdateAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createOrUpdateAtSubscriptionScopeCreateRequest(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateAtSubscriptionScopeCreateRequest creates the CreateOrUpdateAtSubscriptionScope request. +func (client *DeploymentsClient) createOrUpdateAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, parameters Deployment, options *DeploymentsClientBeginCreateOrUpdateAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginCreateOrUpdateAtTenantScope - You can provide the template and parameters directly in the request or link to JSON +// files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - parameters - Additional parameters supplied to the operation. +// - options - DeploymentsClientBeginCreateOrUpdateAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtTenantScope +// method. +func (client *DeploymentsClient) BeginCreateOrUpdateAtTenantScope(ctx context.Context, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginCreateOrUpdateAtTenantScopeOptions) (*runtime.Poller[DeploymentsClientCreateOrUpdateAtTenantScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.createOrUpdateAtTenantScope(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientCreateOrUpdateAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientCreateOrUpdateAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// CreateOrUpdateAtTenantScope - You can provide the template and parameters directly in the request or link to JSON files. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) createOrUpdateAtTenantScope(ctx context.Context, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginCreateOrUpdateAtTenantScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginCreateOrUpdateAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.createOrUpdateAtTenantScopeCreateRequest(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// createOrUpdateAtTenantScopeCreateRequest creates the CreateOrUpdateAtTenantScope request. +func (client *DeploymentsClient) createOrUpdateAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginCreateOrUpdateAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginDelete - A template deployment that is currently running cannot be deleted. Deleting a template deployment removes +// the associated deployment operations. Deleting a template deployment does not affect the state +// of the resource group. This is an asynchronous operation that returns a status of 202 until the template deployment is +// successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to the URI in the Location header returns a status +// of 202. When the process finishes, the URI in the Location header returns a +// status of 204 on success. If the asynchronous request failed, the URI in the Location header returns an error-level status +// code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group with the deployment to delete. The name is case insensitive. +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientBeginDeleteOptions contains the optional parameters for the DeploymentsClient.BeginDelete method. +func (client *DeploymentsClient) BeginDelete(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientBeginDeleteOptions) (*runtime.Poller[DeploymentsClientDeleteResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteOperation(ctx, resourceGroupName, deploymentName, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientDeleteResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientDeleteResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// Delete - A template deployment that is currently running cannot be deleted. Deleting a template deployment removes the +// associated deployment operations. Deleting a template deployment does not affect the state +// of the resource group. This is an asynchronous operation that returns a status of 202 until the template deployment is +// successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to the URI in the Location header returns a status +// of 202. When the process finishes, the URI in the Location header returns a +// status of 204 on success. If the asynchronous request failed, the URI in the Location header returns an error-level status +// code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) deleteOperation(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientBeginDeleteOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.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, deploymentName, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *DeploymentsClient) deleteCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientBeginDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginDeleteAtManagementGroupScope - A template deployment that is currently running cannot be deleted. Deleting a template +// deployment removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// 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 - DeploymentsClientBeginDeleteAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtManagementGroupScope +// method. +func (client *DeploymentsClient) BeginDeleteAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientBeginDeleteAtManagementGroupScopeOptions) (*runtime.Poller[DeploymentsClientDeleteAtManagementGroupScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteAtManagementGroupScope(ctx, groupID, deploymentName, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientDeleteAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientDeleteAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// DeleteAtManagementGroupScope - A template deployment that is currently running cannot be deleted. Deleting a template deployment +// removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) deleteAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientBeginDeleteAtManagementGroupScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginDeleteAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteAtManagementGroupScopeCreateRequest creates the DeleteAtManagementGroupScope request. +func (client *DeploymentsClient) deleteAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientBeginDeleteAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginDeleteAtScope - A template deployment that is currently running cannot be deleted. Deleting a template deployment +// removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// 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 - DeploymentsClientBeginDeleteAtScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtScope +// method. +func (client *DeploymentsClient) BeginDeleteAtScope(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientBeginDeleteAtScopeOptions) (*runtime.Poller[DeploymentsClientDeleteAtScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteAtScope(ctx, scope, deploymentName, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientDeleteAtScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientDeleteAtScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// DeleteAtScope - A template deployment that is currently running cannot be deleted. Deleting a template deployment removes +// the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) deleteAtScope(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientBeginDeleteAtScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginDeleteAtScope" + 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, deploymentName, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteAtScopeCreateRequest creates the DeleteAtScope request. +func (client *DeploymentsClient) deleteAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientBeginDeleteAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginDeleteAtSubscriptionScope - A template deployment that is currently running cannot be deleted. Deleting a template +// deployment removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientBeginDeleteAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtSubscriptionScope +// method. +func (client *DeploymentsClient) BeginDeleteAtSubscriptionScope(ctx context.Context, deploymentName string, options *DeploymentsClientBeginDeleteAtSubscriptionScopeOptions) (*runtime.Poller[DeploymentsClientDeleteAtSubscriptionScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteAtSubscriptionScope(ctx, deploymentName, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientDeleteAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientDeleteAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// DeleteAtSubscriptionScope - A template deployment that is currently running cannot be deleted. Deleting a template deployment +// removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) deleteAtSubscriptionScope(ctx context.Context, deploymentName string, options *DeploymentsClientBeginDeleteAtSubscriptionScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginDeleteAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteAtSubscriptionScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteAtSubscriptionScopeCreateRequest creates the DeleteAtSubscriptionScope request. +func (client *DeploymentsClient) deleteAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientBeginDeleteAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// BeginDeleteAtTenantScope - A template deployment that is currently running cannot be deleted. Deleting a template deployment +// removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - options - DeploymentsClientBeginDeleteAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtTenantScope +// method. +func (client *DeploymentsClient) BeginDeleteAtTenantScope(ctx context.Context, deploymentName string, options *DeploymentsClientBeginDeleteAtTenantScopeOptions) (*runtime.Poller[DeploymentsClientDeleteAtTenantScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.deleteAtTenantScope(ctx, deploymentName, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientDeleteAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientDeleteAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// DeleteAtTenantScope - A template deployment that is currently running cannot be deleted. Deleting a template deployment +// removes the associated deployment operations. This is an asynchronous operation that returns a status +// of 202 until the template deployment is successfully deleted. The Location response header contains the URI that is used +// to obtain the status of the process. While the process is running, a call to +// the URI in the Location header returns a status of 202. When the process finishes, the URI in the Location header returns +// a status of 204 on success. If the asynchronous request failed, the URI in the +// Location header returns an error-level status code. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) deleteAtTenantScope(ctx context.Context, deploymentName string, options *DeploymentsClientBeginDeleteAtTenantScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginDeleteAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.deleteAtTenantScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusAccepted, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteAtTenantScopeCreateRequest creates the DeleteAtTenantScope request. +func (client *DeploymentsClient) deleteAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientBeginDeleteAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// ExportTemplate - Exports the template used for specified 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 - DeploymentsClientExportTemplateOptions contains the optional parameters for the DeploymentsClient.ExportTemplate +// method. +func (client *DeploymentsClient) ExportTemplate(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientExportTemplateOptions) (DeploymentsClientExportTemplateResponse, error) { + var err error + const operationName = "DeploymentsClient.ExportTemplate" + 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, deploymentName, options) + if err != nil { + return DeploymentsClientExportTemplateResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientExportTemplateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientExportTemplateResponse{}, err + } + resp, err := client.exportTemplateHandleResponse(httpResp) + return resp, err +} + +// exportTemplateCreateRequest creates the ExportTemplate request. +func (client *DeploymentsClient) exportTemplateCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientExportTemplateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// exportTemplateHandleResponse handles the ExportTemplate response. +func (client *DeploymentsClient) exportTemplateHandleResponse(resp *http.Response) (DeploymentsClientExportTemplateResponse, error) { + result := DeploymentsClientExportTemplateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExportResult); err != nil { + return DeploymentsClientExportTemplateResponse{}, err + } + return result, nil +} + +// ExportTemplateAtManagementGroupScope - Exports the template used for specified 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 - DeploymentsClientExportTemplateAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtManagementGroupScope +// method. +func (client *DeploymentsClient) ExportTemplateAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientExportTemplateAtManagementGroupScopeOptions) (DeploymentsClientExportTemplateAtManagementGroupScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.ExportTemplateAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.exportTemplateAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, options) + if err != nil { + return DeploymentsClientExportTemplateAtManagementGroupScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientExportTemplateAtManagementGroupScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientExportTemplateAtManagementGroupScopeResponse{}, err + } + resp, err := client.exportTemplateAtManagementGroupScopeHandleResponse(httpResp) + return resp, err +} + +// exportTemplateAtManagementGroupScopeCreateRequest creates the ExportTemplateAtManagementGroupScope request. +func (client *DeploymentsClient) exportTemplateAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientExportTemplateAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// exportTemplateAtManagementGroupScopeHandleResponse handles the ExportTemplateAtManagementGroupScope response. +func (client *DeploymentsClient) exportTemplateAtManagementGroupScopeHandleResponse(resp *http.Response) (DeploymentsClientExportTemplateAtManagementGroupScopeResponse, error) { + result := DeploymentsClientExportTemplateAtManagementGroupScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExportResult); err != nil { + return DeploymentsClientExportTemplateAtManagementGroupScopeResponse{}, err + } + return result, nil +} + +// ExportTemplateAtScope - Exports the template used for specified 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 - DeploymentsClientExportTemplateAtScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtScope +// method. +func (client *DeploymentsClient) ExportTemplateAtScope(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientExportTemplateAtScopeOptions) (DeploymentsClientExportTemplateAtScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.ExportTemplateAtScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.exportTemplateAtScopeCreateRequest(ctx, scope, deploymentName, options) + if err != nil { + return DeploymentsClientExportTemplateAtScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientExportTemplateAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientExportTemplateAtScopeResponse{}, err + } + resp, err := client.exportTemplateAtScopeHandleResponse(httpResp) + return resp, err +} + +// exportTemplateAtScopeCreateRequest creates the ExportTemplateAtScope request. +func (client *DeploymentsClient) exportTemplateAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientExportTemplateAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// exportTemplateAtScopeHandleResponse handles the ExportTemplateAtScope response. +func (client *DeploymentsClient) exportTemplateAtScopeHandleResponse(resp *http.Response) (DeploymentsClientExportTemplateAtScopeResponse, error) { + result := DeploymentsClientExportTemplateAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExportResult); err != nil { + return DeploymentsClientExportTemplateAtScopeResponse{}, err + } + return result, nil +} + +// ExportTemplateAtSubscriptionScope - Exports the template used for specified 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 - DeploymentsClientExportTemplateAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtSubscriptionScope +// method. +func (client *DeploymentsClient) ExportTemplateAtSubscriptionScope(ctx context.Context, deploymentName string, options *DeploymentsClientExportTemplateAtSubscriptionScopeOptions) (DeploymentsClientExportTemplateAtSubscriptionScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.ExportTemplateAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.exportTemplateAtSubscriptionScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return DeploymentsClientExportTemplateAtSubscriptionScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientExportTemplateAtSubscriptionScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientExportTemplateAtSubscriptionScopeResponse{}, err + } + resp, err := client.exportTemplateAtSubscriptionScopeHandleResponse(httpResp) + return resp, err +} + +// exportTemplateAtSubscriptionScopeCreateRequest creates the ExportTemplateAtSubscriptionScope request. +func (client *DeploymentsClient) exportTemplateAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientExportTemplateAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// exportTemplateAtSubscriptionScopeHandleResponse handles the ExportTemplateAtSubscriptionScope response. +func (client *DeploymentsClient) exportTemplateAtSubscriptionScopeHandleResponse(resp *http.Response) (DeploymentsClientExportTemplateAtSubscriptionScopeResponse, error) { + result := DeploymentsClientExportTemplateAtSubscriptionScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExportResult); err != nil { + return DeploymentsClientExportTemplateAtSubscriptionScopeResponse{}, err + } + return result, nil +} + +// ExportTemplateAtTenantScope - Exports the template used for specified 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 - DeploymentsClientExportTemplateAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtTenantScope +// method. +func (client *DeploymentsClient) ExportTemplateAtTenantScope(ctx context.Context, deploymentName string, options *DeploymentsClientExportTemplateAtTenantScopeOptions) (DeploymentsClientExportTemplateAtTenantScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.ExportTemplateAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.exportTemplateAtTenantScopeCreateRequest(ctx, deploymentName, options) + if err != nil { + return DeploymentsClientExportTemplateAtTenantScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientExportTemplateAtTenantScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientExportTemplateAtTenantScopeResponse{}, err + } + resp, err := client.exportTemplateAtTenantScopeHandleResponse(httpResp) + return resp, err +} + +// exportTemplateAtTenantScopeCreateRequest creates the ExportTemplateAtTenantScope request. +func (client *DeploymentsClient) exportTemplateAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientExportTemplateAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// exportTemplateAtTenantScopeHandleResponse handles the ExportTemplateAtTenantScope response. +func (client *DeploymentsClient) exportTemplateAtTenantScopeHandleResponse(resp *http.Response) (DeploymentsClientExportTemplateAtTenantScopeResponse, error) { + result := DeploymentsClientExportTemplateAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExportResult); err != nil { + return DeploymentsClientExportTemplateAtTenantScopeResponse{}, err + } + return result, nil +} + +// Get - Gets 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 - DeploymentsClientGetOptions contains the optional parameters for the DeploymentsClient.Get method. +func (client *DeploymentsClient) Get(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientGetOptions) (DeploymentsClientGetResponse, error) { + var err error + const operationName = "DeploymentsClient.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, options) + if err != nil { + return DeploymentsClientGetResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *DeploymentsClient) getCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, options *DeploymentsClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *DeploymentsClient) getHandleResponse(resp *http.Response) (DeploymentsClientGetResponse, error) { + result := DeploymentsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExtended); err != nil { + return DeploymentsClientGetResponse{}, err + } + return result, nil +} + +// GetAtManagementGroupScope - Gets 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 - DeploymentsClientGetAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.GetAtManagementGroupScope +// method. +func (client *DeploymentsClient) GetAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientGetAtManagementGroupScopeOptions) (DeploymentsClientGetAtManagementGroupScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.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, options) + if err != nil { + return DeploymentsClientGetAtManagementGroupScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientGetAtManagementGroupScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientGetAtManagementGroupScopeResponse{}, err + } + resp, err := client.getAtManagementGroupScopeHandleResponse(httpResp) + return resp, err +} + +// getAtManagementGroupScopeCreateRequest creates the GetAtManagementGroupScope request. +func (client *DeploymentsClient) getAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, options *DeploymentsClientGetAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtManagementGroupScopeHandleResponse handles the GetAtManagementGroupScope response. +func (client *DeploymentsClient) getAtManagementGroupScopeHandleResponse(resp *http.Response) (DeploymentsClientGetAtManagementGroupScopeResponse, error) { + result := DeploymentsClientGetAtManagementGroupScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExtended); err != nil { + return DeploymentsClientGetAtManagementGroupScopeResponse{}, err + } + return result, nil +} + +// GetAtScope - Gets 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 - DeploymentsClientGetAtScopeOptions contains the optional parameters for the DeploymentsClient.GetAtScope method. +func (client *DeploymentsClient) GetAtScope(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientGetAtScopeOptions) (DeploymentsClientGetAtScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.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, options) + if err != nil { + return DeploymentsClientGetAtScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientGetAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientGetAtScopeResponse{}, err + } + resp, err := client.getAtScopeHandleResponse(httpResp) + return resp, err +} + +// getAtScopeCreateRequest creates the GetAtScope request. +func (client *DeploymentsClient) getAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, options *DeploymentsClientGetAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtScopeHandleResponse handles the GetAtScope response. +func (client *DeploymentsClient) getAtScopeHandleResponse(resp *http.Response) (DeploymentsClientGetAtScopeResponse, error) { + result := DeploymentsClientGetAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExtended); err != nil { + return DeploymentsClientGetAtScopeResponse{}, err + } + return result, nil +} + +// GetAtSubscriptionScope - Gets 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 - DeploymentsClientGetAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.GetAtSubscriptionScope +// method. +func (client *DeploymentsClient) GetAtSubscriptionScope(ctx context.Context, deploymentName string, options *DeploymentsClientGetAtSubscriptionScopeOptions) (DeploymentsClientGetAtSubscriptionScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.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, options) + if err != nil { + return DeploymentsClientGetAtSubscriptionScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientGetAtSubscriptionScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientGetAtSubscriptionScopeResponse{}, err + } + resp, err := client.getAtSubscriptionScopeHandleResponse(httpResp) + return resp, err +} + +// getAtSubscriptionScopeCreateRequest creates the GetAtSubscriptionScope request. +func (client *DeploymentsClient) getAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientGetAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtSubscriptionScopeHandleResponse handles the GetAtSubscriptionScope response. +func (client *DeploymentsClient) getAtSubscriptionScopeHandleResponse(resp *http.Response) (DeploymentsClientGetAtSubscriptionScopeResponse, error) { + result := DeploymentsClientGetAtSubscriptionScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExtended); err != nil { + return DeploymentsClientGetAtSubscriptionScopeResponse{}, err + } + return result, nil +} + +// GetAtTenantScope - Gets 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 - DeploymentsClientGetAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.GetAtTenantScope +// method. +func (client *DeploymentsClient) GetAtTenantScope(ctx context.Context, deploymentName string, options *DeploymentsClientGetAtTenantScopeOptions) (DeploymentsClientGetAtTenantScopeResponse, error) { + var err error + const operationName = "DeploymentsClient.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, options) + if err != nil { + return DeploymentsClientGetAtTenantScopeResponse{}, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return DeploymentsClientGetAtTenantScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return DeploymentsClientGetAtTenantScopeResponse{}, err + } + resp, err := client.getAtTenantScopeHandleResponse(httpResp) + return resp, err +} + +// getAtTenantScopeCreateRequest creates the GetAtTenantScope request. +func (client *DeploymentsClient) getAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, options *DeploymentsClientGetAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}" + if deploymentName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtTenantScopeHandleResponse handles the GetAtTenantScope response. +func (client *DeploymentsClient) getAtTenantScopeHandleResponse(resp *http.Response) (DeploymentsClientGetAtTenantScopeResponse, error) { + result := DeploymentsClientGetAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentExtended); err != nil { + return DeploymentsClientGetAtTenantScopeResponse{}, err + } + return result, nil +} + +// NewListAtManagementGroupScopePager - Get all the deployments for a management group. +// +// Generated from API version 2021-04-01 +// - groupID - The management group ID. +// - options - DeploymentsClientListAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtManagementGroupScopePager +// method. +func (client *DeploymentsClient) NewListAtManagementGroupScopePager(groupID string, options *DeploymentsClientListAtManagementGroupScopeOptions) *runtime.Pager[DeploymentsClientListAtManagementGroupScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[DeploymentsClientListAtManagementGroupScopeResponse]{ + More: func(page DeploymentsClientListAtManagementGroupScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DeploymentsClientListAtManagementGroupScopeResponse) (DeploymentsClientListAtManagementGroupScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentsClient.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, options) + }, nil) + if err != nil { + return DeploymentsClientListAtManagementGroupScopeResponse{}, err + } + return client.listAtManagementGroupScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtManagementGroupScopeCreateRequest creates the ListAtManagementGroupScope request. +func (client *DeploymentsClient) listAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, options *DeploymentsClientListAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtManagementGroupScopeHandleResponse handles the ListAtManagementGroupScope response. +func (client *DeploymentsClient) listAtManagementGroupScopeHandleResponse(resp *http.Response) (DeploymentsClientListAtManagementGroupScopeResponse, error) { + result := DeploymentsClientListAtManagementGroupScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentListResult); err != nil { + return DeploymentsClientListAtManagementGroupScopeResponse{}, err + } + return result, nil +} + +// NewListAtScopePager - Get all the deployments at the given scope. +// +// Generated from API version 2021-04-01 +// - scope - The resource scope. +// - options - DeploymentsClientListAtScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtScopePager +// method. +func (client *DeploymentsClient) NewListAtScopePager(scope string, options *DeploymentsClientListAtScopeOptions) *runtime.Pager[DeploymentsClientListAtScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[DeploymentsClientListAtScopeResponse]{ + More: func(page DeploymentsClientListAtScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DeploymentsClientListAtScopeResponse) (DeploymentsClientListAtScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentsClient.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, options) + }, nil) + if err != nil { + return DeploymentsClientListAtScopeResponse{}, err + } + return client.listAtScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtScopeCreateRequest creates the ListAtScope request. +func (client *DeploymentsClient) listAtScopeCreateRequest(ctx context.Context, scope string, options *DeploymentsClientListAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtScopeHandleResponse handles the ListAtScope response. +func (client *DeploymentsClient) listAtScopeHandleResponse(resp *http.Response) (DeploymentsClientListAtScopeResponse, error) { + result := DeploymentsClientListAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentListResult); err != nil { + return DeploymentsClientListAtScopeResponse{}, err + } + return result, nil +} + +// NewListAtSubscriptionScopePager - Get all the deployments for a subscription. +// +// Generated from API version 2021-04-01 +// - options - DeploymentsClientListAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtSubscriptionScopePager +// method. +func (client *DeploymentsClient) NewListAtSubscriptionScopePager(options *DeploymentsClientListAtSubscriptionScopeOptions) *runtime.Pager[DeploymentsClientListAtSubscriptionScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[DeploymentsClientListAtSubscriptionScopeResponse]{ + More: func(page DeploymentsClientListAtSubscriptionScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DeploymentsClientListAtSubscriptionScopeResponse) (DeploymentsClientListAtSubscriptionScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentsClient.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, options) + }, nil) + if err != nil { + return DeploymentsClientListAtSubscriptionScopeResponse{}, err + } + return client.listAtSubscriptionScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtSubscriptionScopeCreateRequest creates the ListAtSubscriptionScope request. +func (client *DeploymentsClient) listAtSubscriptionScopeCreateRequest(ctx context.Context, options *DeploymentsClientListAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtSubscriptionScopeHandleResponse handles the ListAtSubscriptionScope response. +func (client *DeploymentsClient) listAtSubscriptionScopeHandleResponse(resp *http.Response) (DeploymentsClientListAtSubscriptionScopeResponse, error) { + result := DeploymentsClientListAtSubscriptionScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentListResult); err != nil { + return DeploymentsClientListAtSubscriptionScopeResponse{}, err + } + return result, nil +} + +// NewListAtTenantScopePager - Get all the deployments at the tenant scope. +// +// Generated from API version 2021-04-01 +// - options - DeploymentsClientListAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtTenantScopePager +// method. +func (client *DeploymentsClient) NewListAtTenantScopePager(options *DeploymentsClientListAtTenantScopeOptions) *runtime.Pager[DeploymentsClientListAtTenantScopeResponse] { + return runtime.NewPager(runtime.PagingHandler[DeploymentsClientListAtTenantScopeResponse]{ + More: func(page DeploymentsClientListAtTenantScopeResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DeploymentsClientListAtTenantScopeResponse) (DeploymentsClientListAtTenantScopeResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentsClient.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 DeploymentsClientListAtTenantScopeResponse{}, err + } + return client.listAtTenantScopeHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listAtTenantScopeCreateRequest creates the ListAtTenantScope request. +func (client *DeploymentsClient) listAtTenantScopeCreateRequest(ctx context.Context, options *DeploymentsClientListAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/" + req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtTenantScopeHandleResponse handles the ListAtTenantScope response. +func (client *DeploymentsClient) listAtTenantScopeHandleResponse(resp *http.Response) (DeploymentsClientListAtTenantScopeResponse, error) { + result := DeploymentsClientListAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentListResult); err != nil { + return DeploymentsClientListAtTenantScopeResponse{}, err + } + return result, nil +} + +// NewListByResourceGroupPager - Get all the deployments for a resource group. +// +// Generated from API version 2021-04-01 +// - resourceGroupName - The name of the resource group with the deployments to get. The name is case insensitive. +// - options - DeploymentsClientListByResourceGroupOptions contains the optional parameters for the DeploymentsClient.NewListByResourceGroupPager +// method. +func (client *DeploymentsClient) NewListByResourceGroupPager(resourceGroupName string, options *DeploymentsClientListByResourceGroupOptions) *runtime.Pager[DeploymentsClientListByResourceGroupResponse] { + return runtime.NewPager(runtime.PagingHandler[DeploymentsClientListByResourceGroupResponse]{ + More: func(page DeploymentsClientListByResourceGroupResponse) bool { + return page.NextLink != nil && len(*page.NextLink) > 0 + }, + Fetcher: func(ctx context.Context, page *DeploymentsClientListByResourceGroupResponse) (DeploymentsClientListByResourceGroupResponse, error) { + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentsClient.NewListByResourceGroupPager") + 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.listByResourceGroupCreateRequest(ctx, resourceGroupName, options) + }, nil) + if err != nil { + return DeploymentsClientListByResourceGroupResponse{}, err + } + return client.listByResourceGroupHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listByResourceGroupCreateRequest creates the ListByResourceGroup request. +func (client *DeploymentsClient) listByResourceGroupCreateRequest(ctx context.Context, resourceGroupName string, options *DeploymentsClientListByResourceGroupOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listByResourceGroupHandleResponse handles the ListByResourceGroup response. +func (client *DeploymentsClient) listByResourceGroupHandleResponse(resp *http.Response) (DeploymentsClientListByResourceGroupResponse, error) { + result := DeploymentsClientListByResourceGroupResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.DeploymentListResult); err != nil { + return DeploymentsClientListByResourceGroupResponse{}, err + } + return result, nil +} + +// BeginValidate - Validates whether the specified template is syntactically correct and will be accepted by Azure Resource +// Manager.. +// 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 template will be deployed to. The name is case insensitive. +// - deploymentName - The name of the deployment. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginValidateOptions contains the optional parameters for the DeploymentsClient.BeginValidate +// method. +func (client *DeploymentsClient) BeginValidate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateOptions) (*runtime.Poller[DeploymentsClientValidateResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.validate(ctx, resourceGroupName, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientValidateResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientValidateResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// Validate - Validates whether the specified template is syntactically correct and will be accepted by Azure Resource Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) validate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginValidate" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateCreateRequest(ctx, resourceGroupName, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusBadRequest) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// validateCreateRequest creates the Validate request. +func (client *DeploymentsClient) validateCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/validate" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginValidateAtManagementGroupScope - Validates whether the specified template is syntactically correct and will be accepted +// by Azure Resource Manager.. +// 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. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginValidateAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtManagementGroupScope +// method. +func (client *DeploymentsClient) BeginValidateAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginValidateAtManagementGroupScopeOptions) (*runtime.Poller[DeploymentsClientValidateAtManagementGroupScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.validateAtManagementGroupScope(ctx, groupID, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientValidateAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientValidateAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// ValidateAtManagementGroupScope - Validates whether the specified template is syntactically correct and will be accepted +// by Azure Resource Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) validateAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginValidateAtManagementGroupScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginValidateAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusBadRequest) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// validateAtManagementGroupScopeCreateRequest creates the ValidateAtManagementGroupScope request. +func (client *DeploymentsClient) validateAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginValidateAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/validate" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginValidateAtScope - Validates whether the specified template is syntactically correct and will be accepted by Azure +// Resource Manager.. +// 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. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginValidateAtScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtScope +// method. +func (client *DeploymentsClient) BeginValidateAtScope(ctx context.Context, scope string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateAtScopeOptions) (*runtime.Poller[DeploymentsClientValidateAtScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.validateAtScope(ctx, scope, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientValidateAtScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientValidateAtScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// ValidateAtScope - Validates whether the specified template is syntactically correct and will be accepted by Azure Resource +// Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) validateAtScope(ctx context.Context, scope string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateAtScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginValidateAtScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateAtScopeCreateRequest(ctx, scope, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusBadRequest) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// validateAtScopeCreateRequest creates the ValidateAtScope request. +func (client *DeploymentsClient) validateAtScopeCreateRequest(ctx context.Context, scope string, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateAtScopeOptions) (*policy.Request, error) { + urlPath := "/{scope}/providers/Microsoft.Resources/deployments/{deploymentName}/validate" + urlPath = strings.ReplaceAll(urlPath, "{scope}", scope) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginValidateAtSubscriptionScope - Validates whether the specified template is syntactically correct and will be accepted +// by Azure Resource Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginValidateAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtSubscriptionScope +// method. +func (client *DeploymentsClient) BeginValidateAtSubscriptionScope(ctx context.Context, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateAtSubscriptionScopeOptions) (*runtime.Poller[DeploymentsClientValidateAtSubscriptionScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.validateAtSubscriptionScope(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientValidateAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientValidateAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// ValidateAtSubscriptionScope - Validates whether the specified template is syntactically correct and will be accepted by +// Azure Resource Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) validateAtSubscriptionScope(ctx context.Context, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateAtSubscriptionScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginValidateAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateAtSubscriptionScopeCreateRequest(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusBadRequest) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// validateAtSubscriptionScopeCreateRequest creates the ValidateAtSubscriptionScope request. +func (client *DeploymentsClient) validateAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, parameters Deployment, options *DeploymentsClientBeginValidateAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/validate" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginValidateAtTenantScope - Validates whether the specified template is syntactically correct and will be accepted by +// Azure Resource Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginValidateAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtTenantScope +// method. +func (client *DeploymentsClient) BeginValidateAtTenantScope(ctx context.Context, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginValidateAtTenantScopeOptions) (*runtime.Poller[DeploymentsClientValidateAtTenantScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.validateAtTenantScope(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientValidateAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientValidateAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// ValidateAtTenantScope - Validates whether the specified template is syntactically correct and will be accepted by Azure +// Resource Manager.. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) validateAtTenantScope(ctx context.Context, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginValidateAtTenantScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginValidateAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.validateAtTenantScopeCreateRequest(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted, http.StatusBadRequest) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// validateAtTenantScopeCreateRequest creates the ValidateAtTenantScope request. +func (client *DeploymentsClient) validateAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, parameters ScopedDeployment, options *DeploymentsClientBeginValidateAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}/validate" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginWhatIf - Returns changes that will be made by the deployment if executed at the scope of the 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 the template will be deployed to. The name is case insensitive. +// - deploymentName - The name of the deployment. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginWhatIfOptions contains the optional parameters for the DeploymentsClient.BeginWhatIf method. +func (client *DeploymentsClient) BeginWhatIf(ctx context.Context, resourceGroupName string, deploymentName string, parameters DeploymentWhatIf, options *DeploymentsClientBeginWhatIfOptions) (*runtime.Poller[DeploymentsClientWhatIfResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.whatIf(ctx, resourceGroupName, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientWhatIfResponse]{ + FinalStateVia: runtime.FinalStateViaLocation, + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientWhatIfResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// WhatIf - Returns changes that will be made by the deployment if executed at the scope of the resource group. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) whatIf(ctx context.Context, resourceGroupName string, deploymentName string, parameters DeploymentWhatIf, options *DeploymentsClientBeginWhatIfOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginWhatIf" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.whatIfCreateRequest(ctx, resourceGroupName, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// whatIfCreateRequest creates the WhatIf request. +func (client *DeploymentsClient) whatIfCreateRequest(ctx context.Context, resourceGroupName string, deploymentName string, parameters DeploymentWhatIf, options *DeploymentsClientBeginWhatIfOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginWhatIfAtManagementGroupScope - Returns changes that will be made by the deployment if executed at the scope of the +// management group. +// 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. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginWhatIfAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginWhatIfAtManagementGroupScope +// method. +func (client *DeploymentsClient) BeginWhatIfAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtManagementGroupScopeOptions) (*runtime.Poller[DeploymentsClientWhatIfAtManagementGroupScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.whatIfAtManagementGroupScope(ctx, groupID, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientWhatIfAtManagementGroupScopeResponse]{ + FinalStateVia: runtime.FinalStateViaLocation, + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientWhatIfAtManagementGroupScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// WhatIfAtManagementGroupScope - Returns changes that will be made by the deployment if executed at the scope of the management +// group. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) whatIfAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtManagementGroupScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginWhatIfAtManagementGroupScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.whatIfAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// whatIfAtManagementGroupScopeCreateRequest creates the WhatIfAtManagementGroupScope request. +func (client *DeploymentsClient) whatIfAtManagementGroupScopeCreateRequest(ctx context.Context, groupID string, deploymentName string, parameters ScopedDeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf" + if groupID == "" { + return nil, errors.New("parameter groupID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID)) + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginWhatIfAtSubscriptionScope - Returns changes that will be made by the deployment if executed at the scope of the subscription. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - parameters - Parameters to What If. +// - options - DeploymentsClientBeginWhatIfAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginWhatIfAtSubscriptionScope +// method. +func (client *DeploymentsClient) BeginWhatIfAtSubscriptionScope(ctx context.Context, deploymentName string, parameters DeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtSubscriptionScopeOptions) (*runtime.Poller[DeploymentsClientWhatIfAtSubscriptionScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.whatIfAtSubscriptionScope(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientWhatIfAtSubscriptionScopeResponse]{ + FinalStateVia: runtime.FinalStateViaLocation, + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientWhatIfAtSubscriptionScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// WhatIfAtSubscriptionScope - Returns changes that will be made by the deployment if executed at the scope of the subscription. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) whatIfAtSubscriptionScope(ctx context.Context, deploymentName string, parameters DeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtSubscriptionScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginWhatIfAtSubscriptionScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.whatIfAtSubscriptionScopeCreateRequest(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// whatIfAtSubscriptionScopeCreateRequest creates the WhatIfAtSubscriptionScope request. +func (client *DeploymentsClient) whatIfAtSubscriptionScopeCreateRequest(ctx context.Context, deploymentName string, parameters DeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtSubscriptionScopeOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// BeginWhatIfAtTenantScope - Returns changes that will be made by the deployment if executed at the scope of the tenant group. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +// - deploymentName - The name of the deployment. +// - parameters - Parameters to validate. +// - options - DeploymentsClientBeginWhatIfAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginWhatIfAtTenantScope +// method. +func (client *DeploymentsClient) BeginWhatIfAtTenantScope(ctx context.Context, deploymentName string, parameters ScopedDeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtTenantScopeOptions) (*runtime.Poller[DeploymentsClientWhatIfAtTenantScopeResponse], error) { + if options == nil || options.ResumeToken == "" { + resp, err := client.whatIfAtTenantScope(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[DeploymentsClientWhatIfAtTenantScopeResponse]{ + FinalStateVia: runtime.FinalStateViaLocation, + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[DeploymentsClientWhatIfAtTenantScopeResponse]{ + Tracer: client.internal.Tracer(), + }) + } +} + +// WhatIfAtTenantScope - Returns changes that will be made by the deployment if executed at the scope of the tenant group. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2021-04-01 +func (client *DeploymentsClient) whatIfAtTenantScope(ctx context.Context, deploymentName string, parameters ScopedDeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtTenantScopeOptions) (*http.Response, error) { + var err error + const operationName = "DeploymentsClient.BeginWhatIfAtTenantScope" + ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName) + ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil) + defer func() { endSpan(err) }() + req, err := client.whatIfAtTenantScopeCreateRequest(ctx, deploymentName, parameters, options) + if err != nil { + return nil, err + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// whatIfAtTenantScopeCreateRequest creates the WhatIfAtTenantScope request. +func (client *DeploymentsClient) whatIfAtTenantScopeCreateRequest(ctx context.Context, deploymentName string, parameters ScopedDeploymentWhatIf, options *DeploymentsClientBeginWhatIfAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Resources/deployments/{deploymentName}/whatIf" + if deploymentName == "" { + return nil, errors.New("parameter deploymentName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/models.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/models.go new file mode 100644 index 000000000..ce98f859a --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/models.go @@ -0,0 +1,1173 @@ +//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 "time" + +type APIProfile struct { + // READ-ONLY; The API version. + APIVersion *string + + // READ-ONLY; The profile version. + ProfileVersion *string +} + +// Alias - The alias type. +type Alias struct { + // The default path for an alias. + DefaultPath *string + + // The default pattern for an alias. + DefaultPattern *AliasPattern + + // The alias name. + Name *string + + // The paths for an alias. + Paths []*AliasPath + + // The type of the alias. + Type *AliasType + + // READ-ONLY; The default alias path metadata. Applies to the default path and to any alias path that doesn't have metadata + DefaultMetadata *AliasPathMetadata +} + +// AliasPath - The type of the paths for alias. +type AliasPath struct { + // The API versions. + APIVersions []*string + + // The path of an alias. + Path *string + + // The pattern for an alias path. + Pattern *AliasPattern + + // READ-ONLY; The metadata of the alias path. If missing, fall back to the default metadata of the alias. + Metadata *AliasPathMetadata +} + +type AliasPathMetadata struct { + // READ-ONLY; The attributes of the token that the alias path is referring to. + Attributes *AliasPathAttributes + + // READ-ONLY; The type of the token that the alias path is referring to. + Type *AliasPathTokenType +} + +// AliasPattern - The type of the pattern for an alias path. +type AliasPattern struct { + // The alias pattern phrase. + Phrase *string + + // The type of alias pattern + Type *AliasPatternType + + // The alias pattern variable. + Variable *string +} + +// BasicDependency - Deployment dependency information. +type BasicDependency struct { + // The ID of the dependency. + ID *string + + // The dependency resource name. + ResourceName *string + + // The dependency resource type. + ResourceType *string +} + +// DebugSetting - The debug setting. +type DebugSetting struct { + // Specifies the type of information to log for debugging. The permitted values are none, requestContent, responseContent, + // or both requestContent and responseContent separated by a comma. The default is + // none. When setting this value, carefully consider the type of information you are passing in during deployment. By logging + // information about the request or response, you could potentially expose + // sensitive data that is retrieved through the deployment operations. + DetailLevel *string +} + +// Dependency - Deployment dependency information. +type Dependency struct { + // The list of dependencies. + DependsOn []*BasicDependency + + // The ID of the dependency. + ID *string + + // The dependency resource name. + ResourceName *string + + // The dependency resource type. + ResourceType *string +} + +// Deployment operation parameters. +type Deployment struct { + // REQUIRED; The deployment properties. + Properties *DeploymentProperties + + // The location to store the deployment data. + Location *string + + // Deployment tags + Tags map[string]*string +} + +// DeploymentExportResult - The deployment export result. +type DeploymentExportResult struct { + // The template content. + Template any +} + +// DeploymentExtended - Deployment information. +type DeploymentExtended struct { + // the location of the deployment. + Location *string + + // Deployment properties. + Properties *DeploymentPropertiesExtended + + // Deployment tags + Tags map[string]*string + + // READ-ONLY; The ID of the deployment. + ID *string + + // READ-ONLY; The name of the deployment. + Name *string + + // READ-ONLY; The type of the deployment. + Type *string +} + +// DeploymentExtendedFilter - Deployment filter. +type DeploymentExtendedFilter struct { + // The provisioning state. + ProvisioningState *string +} + +// DeploymentListResult - List of deployments. +type DeploymentListResult struct { + // An array of deployments. + Value []*DeploymentExtended + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// DeploymentOperation - Deployment operation information. +type DeploymentOperation struct { + // Deployment properties. + Properties *DeploymentOperationProperties + + // READ-ONLY; Full deployment operation ID. + ID *string + + // READ-ONLY; Deployment operation ID. + OperationID *string +} + +// DeploymentOperationProperties - Deployment operation properties. +type DeploymentOperationProperties struct { + // READ-ONLY; The duration of the operation. + Duration *string + + // READ-ONLY; The name of the current provisioning operation. + ProvisioningOperation *ProvisioningOperation + + // READ-ONLY; The state of the provisioning. + ProvisioningState *string + + // READ-ONLY; The HTTP request message. + Request *HTTPMessage + + // READ-ONLY; The HTTP response message. + Response *HTTPMessage + + // READ-ONLY; Deployment operation service request id. + ServiceRequestID *string + + // READ-ONLY; Operation status code from the resource provider. This property may not be set if a response has not yet been + // received. + StatusCode *string + + // READ-ONLY; Operation status message from the resource provider. This property is optional. It will only be provided if + // an error was received from the resource provider. + StatusMessage *StatusMessage + + // READ-ONLY; The target resource. + TargetResource *TargetResource + + // READ-ONLY; The date and time of the operation. + Timestamp *time.Time +} + +// DeploymentOperationsListResult - List of deployment operations. +type DeploymentOperationsListResult struct { + // An array of deployment operations. + Value []*DeploymentOperation + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// DeploymentProperties - Deployment properties. +type DeploymentProperties struct { + // REQUIRED; The mode that is used to deploy resources. This value can be either Incremental or Complete. In Incremental mode, + // resources are deployed without deleting existing resources that are not included in + // the template. In Complete mode, resources are deployed and existing resources in the resource group that are not included + // in the template are deleted. Be careful when using Complete mode as you may + // unintentionally delete resources. + Mode *DeploymentMode + + // The debug setting of the deployment. + DebugSetting *DebugSetting + + // Specifies whether template expressions are evaluated within the scope of the parent template or nested template. Only applicable + // to nested templates. If not specified, default value is outer. + ExpressionEvaluationOptions *ExpressionEvaluationOptions + + // The deployment on error behavior. + OnErrorDeployment *OnErrorDeployment + + // Name and value pairs that define the deployment parameters for the template. You use this element when you want to provide + // the parameter values directly in the request rather than link to an existing + // parameter file. Use either the parametersLink property or the parameters property, but not both. It can be a JObject or + // a well formed JSON string. + Parameters any + + // The URI of parameters file. You use this element to link to an existing parameters file. Use either the parametersLink + // property or the parameters property, but not both. + ParametersLink *ParametersLink + + // The template content. You use this element when you want to pass the template syntax directly in the request rather than + // link to an existing template. It can be a JObject or well-formed JSON string. + // Use either the templateLink property or the template property, but not both. + Template any + + // The URI of the template. Use either the templateLink property or the template property, but not both. + TemplateLink *TemplateLink +} + +// DeploymentPropertiesExtended - Deployment properties with additional details. +type DeploymentPropertiesExtended struct { + // READ-ONLY; The correlation ID of the deployment. + CorrelationID *string + + // READ-ONLY; The debug setting of the deployment. + DebugSetting *DebugSetting + + // READ-ONLY; The list of deployment dependencies. + Dependencies []*Dependency + + // READ-ONLY; The duration of the template deployment. + Duration *string + + // READ-ONLY; The deployment error. + Error *ErrorResponse + + // READ-ONLY; The deployment mode. Possible values are Incremental and Complete. + Mode *DeploymentMode + + // READ-ONLY; The deployment on error behavior. + OnErrorDeployment *OnErrorDeploymentExtended + + // READ-ONLY; Array of provisioned resources. + OutputResources []*ResourceReference + + // READ-ONLY; Key/value pairs that represent deployment output. + Outputs any + + // READ-ONLY; Deployment parameters. + Parameters any + + // READ-ONLY; The URI referencing the parameters. + ParametersLink *ParametersLink + + // READ-ONLY; The list of resource providers needed for the deployment. + Providers []*Provider + + // READ-ONLY; Denotes the state of provisioning. + ProvisioningState *ProvisioningState + + // READ-ONLY; The hash produced for the template. + TemplateHash *string + + // READ-ONLY; The URI referencing the template. + TemplateLink *TemplateLink + + // READ-ONLY; The timestamp of the template deployment. + Timestamp *time.Time + + // READ-ONLY; Array of validated resources. + ValidatedResources []*ResourceReference +} + +// DeploymentValidateResult - Information from validate template deployment response. +type DeploymentValidateResult struct { + // The template deployment properties. + Properties *DeploymentPropertiesExtended + + // READ-ONLY; The deployment validation error. + Error *ErrorResponse +} + +// DeploymentWhatIf - Deployment What-if operation parameters. +type DeploymentWhatIf struct { + // REQUIRED; The deployment properties. + Properties *DeploymentWhatIfProperties + + // The location to store the deployment data. + Location *string +} + +// DeploymentWhatIfProperties - Deployment What-if properties. +type DeploymentWhatIfProperties struct { + // REQUIRED; The mode that is used to deploy resources. This value can be either Incremental or Complete. In Incremental mode, + // resources are deployed without deleting existing resources that are not included in + // the template. In Complete mode, resources are deployed and existing resources in the resource group that are not included + // in the template are deleted. Be careful when using Complete mode as you may + // unintentionally delete resources. + Mode *DeploymentMode + + // The debug setting of the deployment. + DebugSetting *DebugSetting + + // Specifies whether template expressions are evaluated within the scope of the parent template or nested template. Only applicable + // to nested templates. If not specified, default value is outer. + ExpressionEvaluationOptions *ExpressionEvaluationOptions + + // The deployment on error behavior. + OnErrorDeployment *OnErrorDeployment + + // Name and value pairs that define the deployment parameters for the template. You use this element when you want to provide + // the parameter values directly in the request rather than link to an existing + // parameter file. Use either the parametersLink property or the parameters property, but not both. It can be a JObject or + // a well formed JSON string. + Parameters any + + // The URI of parameters file. You use this element to link to an existing parameters file. Use either the parametersLink + // property or the parameters property, but not both. + ParametersLink *ParametersLink + + // The template content. You use this element when you want to pass the template syntax directly in the request rather than + // link to an existing template. It can be a JObject or well-formed JSON string. + // Use either the templateLink property or the template property, but not both. + Template any + + // The URI of the template. Use either the templateLink property or the template property, but not both. + TemplateLink *TemplateLink + + // Optional What-If operation settings. + WhatIfSettings *DeploymentWhatIfSettings +} + +// DeploymentWhatIfSettings - Deployment What-If operation settings. +type DeploymentWhatIfSettings struct { + // The format of the What-If results + ResultFormat *WhatIfResultFormat +} + +// ErrorAdditionalInfo - The resource management error additional info. +type ErrorAdditionalInfo struct { + // READ-ONLY; The additional info. + Info any + + // READ-ONLY; The additional info type. + Type *string +} + +// ErrorResponse - Common error response for all Azure Resource Manager APIs to return error details for failed operations. +// (This also follows the OData error response format.) +type ErrorResponse struct { + // READ-ONLY; The error additional info. + AdditionalInfo []*ErrorAdditionalInfo + + // READ-ONLY; The error code. + Code *string + + // READ-ONLY; The error details. + Details []*ErrorResponse + + // READ-ONLY; The error message. + Message *string + + // READ-ONLY; The error target. + Target *string +} + +// ExportTemplateRequest - Export resource group template request parameters. +type ExportTemplateRequest struct { + // The export template options. A CSV-formatted list containing zero or more of the following: 'IncludeParameterDefaultValue', + // 'IncludeComments', 'SkipResourceNameParameterization', + // 'SkipAllParameterization' + Options *string + + // The IDs of the resources to filter the export by. To export all resources, supply an array with single entry '*'. + Resources []*string +} + +// ExpressionEvaluationOptions - Specifies whether template expressions are evaluated within the scope of the parent template +// or nested template. +type ExpressionEvaluationOptions struct { + // The scope to be used for evaluation of parameters, variables and functions in a nested template. + Scope *ExpressionEvaluationOptionsScopeType +} + +// ExtendedLocation - Resource extended location. +type ExtendedLocation struct { + // The extended location name. + Name *string + + // The extended location type. + Type *ExtendedLocationType +} + +// GenericResource - Resource information. +type GenericResource struct { + // Resource extended location. + ExtendedLocation *ExtendedLocation + + // The identity of the resource. + Identity *Identity + + // The kind of the resource. + Kind *string + + // Resource location + Location *string + + // ID of the resource that manages this resource. + ManagedBy *string + + // The plan of the resource. + Plan *Plan + + // The resource properties. + Properties any + + // The SKU of the resource. + SKU *SKU + + // Resource tags + Tags map[string]*string + + // READ-ONLY; Resource ID + ID *string + + // READ-ONLY; Resource name + Name *string + + // READ-ONLY; Resource type + Type *string +} + +// GenericResourceExpanded - Resource information. +type GenericResourceExpanded struct { + // Resource extended location. + ExtendedLocation *ExtendedLocation + + // The identity of the resource. + Identity *Identity + + // The kind of the resource. + Kind *string + + // Resource location + Location *string + + // ID of the resource that manages this resource. + ManagedBy *string + + // The plan of the resource. + Plan *Plan + + // The resource properties. + Properties any + + // The SKU of the resource. + SKU *SKU + + // Resource tags + Tags map[string]*string + + // READ-ONLY; The changed time of the resource. This is only present if requested via the $expand query parameter. + ChangedTime *time.Time + + // READ-ONLY; The created time of the resource. This is only present if requested via the $expand query parameter. + CreatedTime *time.Time + + // READ-ONLY; Resource ID + ID *string + + // READ-ONLY; Resource name + Name *string + + // READ-ONLY; The provisioning state of the resource. This is only present if requested via the $expand query parameter. + ProvisioningState *string + + // READ-ONLY; Resource type + Type *string +} + +// GenericResourceFilter - Resource filter. +type GenericResourceFilter struct { + // The resource type. + ResourceType *string + + // The tag name. + Tagname *string + + // The tag value. + Tagvalue *string +} + +// HTTPMessage - HTTP message. +type HTTPMessage struct { + // HTTP message content. + Content any +} + +// Identity for the resource. +type Identity struct { + // The identity type. + Type *ResourceIdentityType + + // The list of user identities associated with the resource. The user identity dictionary key references will be ARM resource + // ids in the form: + // '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'. + UserAssignedIdentities map[string]*IdentityUserAssignedIdentitiesValue + + // READ-ONLY; The principal ID of resource identity. + PrincipalID *string + + // READ-ONLY; The tenant ID of resource. + TenantID *string +} + +type IdentityUserAssignedIdentitiesValue struct { + // READ-ONLY; The client id of user assigned identity. + ClientID *string + + // READ-ONLY; The principal id of user assigned identity. + PrincipalID *string +} + +// MoveInfo - Parameters of move resources. +type MoveInfo struct { + // The IDs of the resources. + Resources []*string + + // The target resource group. + TargetResourceGroup *string +} + +// OnErrorDeployment - Deployment on error behavior. +type OnErrorDeployment struct { + // The deployment to be used on error case. + DeploymentName *string + + // The deployment on error behavior type. Possible values are LastSuccessful and SpecificDeployment. + Type *OnErrorDeploymentType +} + +// OnErrorDeploymentExtended - Deployment on error behavior with additional details. +type OnErrorDeploymentExtended struct { + // The deployment to be used on error case. + DeploymentName *string + + // The deployment on error behavior type. Possible values are LastSuccessful and SpecificDeployment. + Type *OnErrorDeploymentType + + // READ-ONLY; The state of the provisioning for the on error deployment. + ProvisioningState *string +} + +// Operation - Microsoft.Resources operation +type Operation struct { + // The object that represents the operation. + Display *OperationDisplay + + // Operation name: {provider}/{resource}/{operation} + Name *string +} + +// OperationDisplay - The object that represents the operation. +type OperationDisplay struct { + // Description of the operation. + Description *string + + // Operation type: Read, write, delete, etc. + Operation *string + + // Service provider: Microsoft.Resources + Provider *string + + // Resource on which the operation is performed: Profile, endpoint, etc. + Resource *string +} + +// OperationListResult - 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. +type OperationListResult struct { + // URL to get the next set of operation list results if there are any. + NextLink *string + + // List of Microsoft.Resources operations. + Value []*Operation +} + +// ParametersLink - Entity representing the reference to the deployment parameters. +type ParametersLink struct { + // REQUIRED; The URI of the parameters file. + URI *string + + // If included, must match the ContentVersion in the template. + ContentVersion *string +} + +// Permission - Role definition permissions. +type Permission struct { + // Allowed actions. + Actions []*string + + // Allowed Data actions. + DataActions []*string + + // Denied actions. + NotActions []*string + + // Denied Data actions. + NotDataActions []*string +} + +// Plan for the resource. +type Plan struct { + // The plan ID. + Name *string + + // The offer ID. + Product *string + + // The promotion code. + PromotionCode *string + + // The publisher ID. + Publisher *string + + // The plan's version. + Version *string +} + +// Provider - Resource provider information. +type Provider struct { + // The namespace of the resource provider. + Namespace *string + + // The provider authorization consent state. + ProviderAuthorizationConsentState *ProviderAuthorizationConsentState + + // READ-ONLY; The provider ID. + ID *string + + // READ-ONLY; The registration policy of the resource provider. + RegistrationPolicy *string + + // READ-ONLY; The registration state of the resource provider. + RegistrationState *string + + // READ-ONLY; The collection of provider resource types. + ResourceTypes []*ProviderResourceType +} + +// ProviderConsentDefinition - The provider consent. +type ProviderConsentDefinition struct { + // A value indicating whether authorization is consented or not. + ConsentToAuthorization *bool +} + +// ProviderExtendedLocation - The provider extended location. +type ProviderExtendedLocation struct { + // The extended locations for the azure location. + ExtendedLocations []*string + + // The azure location. + Location *string + + // The extended location type. + Type *string +} + +// ProviderListResult - List of resource providers. +type ProviderListResult struct { + // An array of resource providers. + Value []*Provider + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// ProviderPermission - The provider permission +type ProviderPermission struct { + // The application id. + ApplicationID *string + + // Role definition properties. + ManagedByRoleDefinition *RoleDefinition + + // The provider authorization consent state. + ProviderAuthorizationConsentState *ProviderAuthorizationConsentState + + // Role definition properties. + RoleDefinition *RoleDefinition +} + +// ProviderPermissionListResult - List of provider permissions. +type ProviderPermissionListResult struct { + // An array of provider permissions. + Value []*ProviderPermission + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// ProviderRegistrationRequest - The provider registration definition. +type ProviderRegistrationRequest struct { + // The provider consent. + ThirdPartyProviderConsent *ProviderConsentDefinition +} + +// ProviderResourceType - Resource type managed by the resource provider. +type ProviderResourceType struct { + // The API version. + APIVersions []*string + + // The aliases that are supported by this resource type. + Aliases []*Alias + + // The additional capabilities offered by this resource type. + Capabilities *string + + // The location mappings that are supported by this resource type. + LocationMappings []*ProviderExtendedLocation + + // The collection of locations where this resource type can be created. + Locations []*string + + // The properties. + Properties map[string]*string + + // The resource type. + ResourceType *string + ZoneMappings []*ZoneMapping + + // READ-ONLY; The API profiles for the resource provider. + APIProfiles []*APIProfile + + // READ-ONLY; The default API version. + DefaultAPIVersion *string +} + +// ProviderResourceTypeListResult - List of resource types of a resource provider. +type ProviderResourceTypeListResult struct { + // An array of resource types. + Value []*ProviderResourceType + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// Resource - Specified resource. +type Resource struct { + // Resource extended location. + ExtendedLocation *ExtendedLocation + + // Resource location + Location *string + + // Resource tags + Tags map[string]*string + + // READ-ONLY; Resource ID + ID *string + + // READ-ONLY; Resource name + Name *string + + // READ-ONLY; Resource type + Type *string +} + +// ResourceGroup - Resource group information. +type ResourceGroup struct { + // REQUIRED; The location of the resource group. It cannot be changed after the resource group has been created. It must be + // one of the supported Azure locations. + Location *string + + // The ID of the resource that manages this resource group. + ManagedBy *string + + // The resource group properties. + Properties *ResourceGroupProperties + + // The tags attached to the resource group. + Tags map[string]*string + + // READ-ONLY; The ID of the resource group. + ID *string + + // READ-ONLY; The name of the resource group. + Name *string + + // READ-ONLY; The type of the resource group. + Type *string +} + +// ResourceGroupExportResult - Resource group export result. +type ResourceGroupExportResult struct { + // The template export error. + Error *ErrorResponse + + // The template content. + Template any +} + +// ResourceGroupFilter - Resource group filter. +type ResourceGroupFilter struct { + // The tag name. + TagName *string + + // The tag value. + TagValue *string +} + +// ResourceGroupListResult - List of resource groups. +type ResourceGroupListResult struct { + // An array of resource groups. + Value []*ResourceGroup + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// ResourceGroupPatchable - Resource group information. +type ResourceGroupPatchable struct { + // The ID of the resource that manages this resource group. + ManagedBy *string + + // The name of the resource group. + Name *string + + // The resource group properties. + Properties *ResourceGroupProperties + + // The tags attached to the resource group. + Tags map[string]*string +} + +// ResourceGroupProperties - The resource group properties. +type ResourceGroupProperties struct { + // READ-ONLY; The provisioning state. + ProvisioningState *string +} + +// ResourceListResult - List of resource groups. +type ResourceListResult struct { + // An array of resources. + Value []*GenericResourceExpanded + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// ResourceProviderOperationDisplayProperties - Resource provider operation's display properties. +type ResourceProviderOperationDisplayProperties struct { + // Operation description. + Description *string + + // Resource provider operation. + Operation *string + + // Operation provider. + Provider *string + + // Operation description. + Publisher *string + + // Operation resource. + Resource *string +} + +// ResourceReference - The resource Id model. +type ResourceReference struct { + // READ-ONLY; The fully qualified resource Id. + ID *string +} + +// RoleDefinition - Role definition properties. +type RoleDefinition struct { + // The role definition ID. + ID *string + + // If this is a service role. + IsServiceRole *bool + + // The role definition name. + Name *string + + // Role definition permissions. + Permissions []*Permission + + // Role definition assignable scopes. + Scopes []*string +} + +// SKU for the resource. +type SKU struct { + // The SKU capacity. + Capacity *int32 + + // The SKU family. + Family *string + + // The SKU model. + Model *string + + // The SKU name. + Name *string + + // The SKU size. + Size *string + + // The SKU tier. + Tier *string +} + +// ScopedDeployment - Deployment operation parameters. +type ScopedDeployment struct { + // REQUIRED; The location to store the deployment data. + Location *string + + // REQUIRED; The deployment properties. + Properties *DeploymentProperties + + // Deployment tags + Tags map[string]*string +} + +// ScopedDeploymentWhatIf - Deployment What-if operation parameters. +type ScopedDeploymentWhatIf struct { + // REQUIRED; The location to store the deployment data. + Location *string + + // REQUIRED; The deployment properties. + Properties *DeploymentWhatIfProperties +} + +// StatusMessage - Operation status message object. +type StatusMessage struct { + // The error reported by the operation. + Error *ErrorResponse + + // Status of the deployment operation. + Status *string +} + +// SubResource - Sub-resource. +type SubResource struct { + // Resource ID + ID *string +} + +// TagCount - Tag count. +type TagCount struct { + // Type of count. + Type *string + + // Value of count. + Value *int32 +} + +// TagDetails - Tag details. +type TagDetails struct { + // The total number of resources that use the resource tag. When a tag is initially created and has no associated resources, + // the value is 0. + Count *TagCount + + // The tag name. + TagName *string + + // The list of tag values. + Values []*TagValue + + // READ-ONLY; The tag name ID. + ID *string +} + +// TagValue - Tag information. +type TagValue struct { + // The tag value count. + Count *TagCount + + // The tag value. + TagValue *string + + // READ-ONLY; The tag value ID. + ID *string +} + +// Tags - A dictionary of name and value pairs. +type Tags struct { + // Dictionary of + Tags map[string]*string +} + +// TagsListResult - List of subscription tags. +type TagsListResult struct { + // An array of tags. + Value []*TagDetails + + // READ-ONLY; The URL to use for getting the next set of results. + NextLink *string +} + +// TagsPatchResource - Wrapper resource for tags patch API request only. +type TagsPatchResource struct { + // The operation type for the patch API. + Operation *TagsPatchOperation + + // The set of tags. + Properties *Tags +} + +// TagsResource - Wrapper resource for tags API requests and responses. +type TagsResource struct { + // REQUIRED; The set of tags. + Properties *Tags + + // READ-ONLY; The ID of the tags wrapper resource. + ID *string + + // READ-ONLY; The name of the tags wrapper resource. + Name *string + + // READ-ONLY; The type of the tags wrapper resource. + Type *string +} + +// TargetResource - Target resource. +type TargetResource struct { + // The ID of the resource. + ID *string + + // The name of the resource. + ResourceName *string + + // The type of the resource. + ResourceType *string +} + +// TemplateHashResult - Result of the request to calculate template hash. It contains a string of minified template and its +// hash. +type TemplateHashResult struct { + // The minified template string. + MinifiedTemplate *string + + // The template hash. + TemplateHash *string +} + +// TemplateLink - Entity representing the reference to the template. +type TemplateLink struct { + // If included, must match the ContentVersion in the template. + ContentVersion *string + + // The resource id of a Template Spec. Use either the id or uri property, but not both. + ID *string + + // The query string (for example, a SAS token) to be used with the templateLink URI. + QueryString *string + + // The relativePath property can be used to deploy a linked template at a location relative to the parent. If the parent template + // was linked with a TemplateSpec, this will reference an artifact in the + // TemplateSpec. If the parent was linked with a URI, the child deployment will be a combination of the parent and relativePath + // URIs + RelativePath *string + + // The URI of the template to deploy. Use either the uri or id property, but not both. + URI *string +} + +// WhatIfChange - Information about a single resource change predicted by What-If operation. +type WhatIfChange struct { + // REQUIRED; Type of change that will be made to the resource when the deployment is executed. + ChangeType *ChangeType + + // REQUIRED; Resource ID + ResourceID *string + + // The predicted snapshot of the resource after the deployment is executed. + After any + + // The snapshot of the resource before the deployment is executed. + Before any + + // The predicted changes to resource properties. + Delta []*WhatIfPropertyChange + + // The explanation about why the resource is unsupported by What-If. + UnsupportedReason *string +} + +// WhatIfOperationProperties - Deployment operation properties. +type WhatIfOperationProperties struct { + // List of resource changes predicted by What-If operation. + Changes []*WhatIfChange +} + +// WhatIfOperationResult - Result of the What-If operation. Contains a list of predicted changes and a URL link to get to +// the next set of results. +type WhatIfOperationResult struct { + // Error when What-If operation fails. + Error *ErrorResponse + + // What-If operation properties. + Properties *WhatIfOperationProperties + + // Status of the What-If operation. + Status *string +} + +// WhatIfPropertyChange - The predicted change to the resource property. +type WhatIfPropertyChange struct { + // REQUIRED; The path of the property. + Path *string + + // REQUIRED; The type of property change. + PropertyChangeType *PropertyChangeType + + // The value of the property after the deployment is executed. + After any + + // The value of the property before the deployment is executed. + Before any + + // Nested property changes. + Children []*WhatIfPropertyChange +} + +type ZoneMapping struct { + // The location of the zone mapping. + Location *string + Zones []*string +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/models_serde.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/models_serde.go new file mode 100644 index 000000000..5c6e3ac77 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/models_serde.go @@ -0,0 +1,3108 @@ +//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 ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" +) + +// MarshalJSON implements the json.Marshaller interface for type APIProfile. +func (a APIProfile) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "apiVersion", a.APIVersion) + populate(objectMap, "profileVersion", a.ProfileVersion) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type APIProfile. +func (a *APIProfile) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "apiVersion": + err = unpopulate(val, "APIVersion", &a.APIVersion) + delete(rawMsg, key) + case "profileVersion": + err = unpopulate(val, "ProfileVersion", &a.ProfileVersion) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Alias. +func (a Alias) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "defaultMetadata", a.DefaultMetadata) + populate(objectMap, "defaultPath", a.DefaultPath) + populate(objectMap, "defaultPattern", a.DefaultPattern) + populate(objectMap, "name", a.Name) + populate(objectMap, "paths", a.Paths) + populate(objectMap, "type", a.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Alias. +func (a *Alias) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "defaultMetadata": + err = unpopulate(val, "DefaultMetadata", &a.DefaultMetadata) + delete(rawMsg, key) + case "defaultPath": + err = unpopulate(val, "DefaultPath", &a.DefaultPath) + delete(rawMsg, key) + case "defaultPattern": + err = unpopulate(val, "DefaultPattern", &a.DefaultPattern) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &a.Name) + delete(rawMsg, key) + case "paths": + err = unpopulate(val, "Paths", &a.Paths) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &a.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AliasPath. +func (a AliasPath) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "apiVersions", a.APIVersions) + populate(objectMap, "metadata", a.Metadata) + populate(objectMap, "path", a.Path) + populate(objectMap, "pattern", a.Pattern) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AliasPath. +func (a *AliasPath) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "apiVersions": + err = unpopulate(val, "APIVersions", &a.APIVersions) + delete(rawMsg, key) + case "metadata": + err = unpopulate(val, "Metadata", &a.Metadata) + delete(rawMsg, key) + case "path": + err = unpopulate(val, "Path", &a.Path) + delete(rawMsg, key) + case "pattern": + err = unpopulate(val, "Pattern", &a.Pattern) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AliasPathMetadata. +func (a AliasPathMetadata) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "attributes", a.Attributes) + populate(objectMap, "type", a.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AliasPathMetadata. +func (a *AliasPathMetadata) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "attributes": + err = unpopulate(val, "Attributes", &a.Attributes) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &a.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AliasPattern. +func (a AliasPattern) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "phrase", a.Phrase) + populate(objectMap, "type", a.Type) + populate(objectMap, "variable", a.Variable) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AliasPattern. +func (a *AliasPattern) 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", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "phrase": + err = unpopulate(val, "Phrase", &a.Phrase) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &a.Type) + delete(rawMsg, key) + case "variable": + err = unpopulate(val, "Variable", &a.Variable) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type BasicDependency. +func (b BasicDependency) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", b.ID) + populate(objectMap, "resourceName", b.ResourceName) + populate(objectMap, "resourceType", b.ResourceType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type BasicDependency. +func (b *BasicDependency) 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", b, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &b.ID) + delete(rawMsg, key) + case "resourceName": + err = unpopulate(val, "ResourceName", &b.ResourceName) + delete(rawMsg, key) + case "resourceType": + err = unpopulate(val, "ResourceType", &b.ResourceType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", b, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type DebugSetting. +func (d DebugSetting) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "detailLevel", d.DetailLevel) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DebugSetting. +func (d *DebugSetting) 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 "detailLevel": + err = unpopulate(val, "DetailLevel", &d.DetailLevel) + 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 Dependency. +func (d Dependency) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "dependsOn", d.DependsOn) + populate(objectMap, "id", d.ID) + populate(objectMap, "resourceName", d.ResourceName) + populate(objectMap, "resourceType", d.ResourceType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Dependency. +func (d *Dependency) 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 "dependsOn": + err = unpopulate(val, "DependsOn", &d.DependsOn) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &d.ID) + delete(rawMsg, key) + case "resourceName": + err = unpopulate(val, "ResourceName", &d.ResourceName) + delete(rawMsg, key) + case "resourceType": + err = unpopulate(val, "ResourceType", &d.ResourceType) + 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 Deployment. +func (d Deployment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + 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 Deployment. +func (d *Deployment) 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 "location": + err = unpopulate(val, "Location", &d.Location) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &d.Properties) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &d.Tags) + 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 DeploymentExportResult. +func (d DeploymentExportResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "template", d.Template) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentExportResult. +func (d *DeploymentExportResult) 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 "template": + err = unpopulate(val, "Template", &d.Template) + 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 DeploymentExtended. +func (d DeploymentExtended) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", d.ID) + populate(objectMap, "location", d.Location) + populate(objectMap, "name", d.Name) + populate(objectMap, "properties", d.Properties) + populate(objectMap, "tags", d.Tags) + populate(objectMap, "type", d.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentExtended. +func (d *DeploymentExtended) 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 "id": + err = unpopulate(val, "ID", &d.ID) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &d.Location) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &d.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &d.Properties) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &d.Tags) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &d.Type) + 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 DeploymentExtendedFilter. +func (d DeploymentExtendedFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "provisioningState", d.ProvisioningState) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentExtendedFilter. +func (d *DeploymentExtendedFilter) 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 "provisioningState": + err = unpopulate(val, "ProvisioningState", &d.ProvisioningState) + 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 DeploymentListResult. +func (d DeploymentListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", d.NextLink) + populate(objectMap, "value", d.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentListResult. +func (d *DeploymentListResult) 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 "nextLink": + err = unpopulate(val, "NextLink", &d.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &d.Value) + 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 DeploymentOperation. +func (d DeploymentOperation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", d.ID) + populate(objectMap, "operationId", d.OperationID) + populate(objectMap, "properties", d.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentOperation. +func (d *DeploymentOperation) 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 "id": + err = unpopulate(val, "ID", &d.ID) + delete(rawMsg, key) + case "operationId": + err = unpopulate(val, "OperationID", &d.OperationID) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &d.Properties) + 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 DeploymentOperationProperties. +func (d DeploymentOperationProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "duration", d.Duration) + populate(objectMap, "provisioningOperation", d.ProvisioningOperation) + populate(objectMap, "provisioningState", d.ProvisioningState) + populate(objectMap, "request", d.Request) + populate(objectMap, "response", d.Response) + populate(objectMap, "serviceRequestId", d.ServiceRequestID) + populate(objectMap, "statusCode", d.StatusCode) + populate(objectMap, "statusMessage", d.StatusMessage) + populate(objectMap, "targetResource", d.TargetResource) + populateDateTimeRFC3339(objectMap, "timestamp", d.Timestamp) + 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 = unpopulateDateTimeRFC3339(val, "Timestamp", &d.Timestamp) + 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 DeploymentOperationsListResult. +func (d DeploymentOperationsListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", d.NextLink) + populate(objectMap, "value", d.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentOperationsListResult. +func (d *DeploymentOperationsListResult) 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 "nextLink": + err = unpopulate(val, "NextLink", &d.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &d.Value) + 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 DeploymentProperties. +func (d DeploymentProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "debugSetting", d.DebugSetting) + populate(objectMap, "expressionEvaluationOptions", d.ExpressionEvaluationOptions) + populate(objectMap, "mode", d.Mode) + populate(objectMap, "onErrorDeployment", d.OnErrorDeployment) + populateAny(objectMap, "parameters", d.Parameters) + populate(objectMap, "parametersLink", d.ParametersLink) + populateAny(objectMap, "template", d.Template) + populate(objectMap, "templateLink", d.TemplateLink) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentProperties. +func (d *DeploymentProperties) 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 "debugSetting": + err = unpopulate(val, "DebugSetting", &d.DebugSetting) + delete(rawMsg, key) + case "expressionEvaluationOptions": + err = unpopulate(val, "ExpressionEvaluationOptions", &d.ExpressionEvaluationOptions) + 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 "parameters": + err = unpopulate(val, "Parameters", &d.Parameters) + delete(rawMsg, key) + case "parametersLink": + err = unpopulate(val, "ParametersLink", &d.ParametersLink) + delete(rawMsg, key) + case "template": + err = unpopulate(val, "Template", &d.Template) + delete(rawMsg, key) + case "templateLink": + err = unpopulate(val, "TemplateLink", &d.TemplateLink) + 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 DeploymentPropertiesExtended. +func (d DeploymentPropertiesExtended) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "correlationId", d.CorrelationID) + populate(objectMap, "debugSetting", d.DebugSetting) + populate(objectMap, "dependencies", d.Dependencies) + populate(objectMap, "duration", d.Duration) + populate(objectMap, "error", d.Error) + populate(objectMap, "mode", d.Mode) + populate(objectMap, "onErrorDeployment", d.OnErrorDeployment) + populate(objectMap, "outputResources", d.OutputResources) + populateAny(objectMap, "outputs", d.Outputs) + populateAny(objectMap, "parameters", d.Parameters) + populate(objectMap, "parametersLink", d.ParametersLink) + populate(objectMap, "providers", d.Providers) + populate(objectMap, "provisioningState", d.ProvisioningState) + populate(objectMap, "templateHash", d.TemplateHash) + populate(objectMap, "templateLink", d.TemplateLink) + populateDateTimeRFC3339(objectMap, "timestamp", d.Timestamp) + populate(objectMap, "validatedResources", d.ValidatedResources) + return json.Marshal(objectMap) +} + +// 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 = unpopulateDateTimeRFC3339(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 DeploymentValidateResult. +func (d DeploymentValidateResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", d.Error) + populate(objectMap, "properties", d.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentValidateResult. +func (d *DeploymentValidateResult) 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 "error": + err = unpopulate(val, "Error", &d.Error) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &d.Properties) + 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 DeploymentWhatIf. +func (d DeploymentWhatIf) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "location", d.Location) + populate(objectMap, "properties", d.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentWhatIf. +func (d *DeploymentWhatIf) 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 "location": + err = unpopulate(val, "Location", &d.Location) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &d.Properties) + 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 DeploymentWhatIfProperties. +func (d DeploymentWhatIfProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "debugSetting", d.DebugSetting) + populate(objectMap, "expressionEvaluationOptions", d.ExpressionEvaluationOptions) + populate(objectMap, "mode", d.Mode) + populate(objectMap, "onErrorDeployment", d.OnErrorDeployment) + populateAny(objectMap, "parameters", d.Parameters) + populate(objectMap, "parametersLink", d.ParametersLink) + populateAny(objectMap, "template", d.Template) + populate(objectMap, "templateLink", d.TemplateLink) + populate(objectMap, "whatIfSettings", d.WhatIfSettings) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentWhatIfProperties. +func (d *DeploymentWhatIfProperties) 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 "debugSetting": + err = unpopulate(val, "DebugSetting", &d.DebugSetting) + delete(rawMsg, key) + case "expressionEvaluationOptions": + err = unpopulate(val, "ExpressionEvaluationOptions", &d.ExpressionEvaluationOptions) + 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 "parameters": + err = unpopulate(val, "Parameters", &d.Parameters) + delete(rawMsg, key) + case "parametersLink": + err = unpopulate(val, "ParametersLink", &d.ParametersLink) + delete(rawMsg, key) + case "template": + err = unpopulate(val, "Template", &d.Template) + delete(rawMsg, key) + case "templateLink": + err = unpopulate(val, "TemplateLink", &d.TemplateLink) + delete(rawMsg, key) + case "whatIfSettings": + err = unpopulate(val, "WhatIfSettings", &d.WhatIfSettings) + 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 DeploymentWhatIfSettings. +func (d DeploymentWhatIfSettings) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "resultFormat", d.ResultFormat) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentWhatIfSettings. +func (d *DeploymentWhatIfSettings) 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 "resultFormat": + err = unpopulate(val, "ResultFormat", &d.ResultFormat) + 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 ErrorAdditionalInfo. +func (e ErrorAdditionalInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "info", e.Info) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorAdditionalInfo. +func (e *ErrorAdditionalInfo) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "info": + err = unpopulate(val, "Info", &e.Info) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ErrorResponse. +func (e ErrorResponse) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "additionalInfo", e.AdditionalInfo) + populate(objectMap, "code", e.Code) + populate(objectMap, "details", e.Details) + populate(objectMap, "message", e.Message) + populate(objectMap, "target", e.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponse. +func (e *ErrorResponse) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "additionalInfo": + err = unpopulate(val, "AdditionalInfo", &e.AdditionalInfo) + delete(rawMsg, key) + case "code": + err = unpopulate(val, "Code", &e.Code) + delete(rawMsg, key) + case "details": + err = unpopulate(val, "Details", &e.Details) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &e.Message) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &e.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExportTemplateRequest. +func (e ExportTemplateRequest) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "options", e.Options) + populate(objectMap, "resources", e.Resources) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExportTemplateRequest. +func (e *ExportTemplateRequest) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "options": + err = unpopulate(val, "Options", &e.Options) + delete(rawMsg, key) + case "resources": + err = unpopulate(val, "Resources", &e.Resources) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExpressionEvaluationOptions. +func (e ExpressionEvaluationOptions) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "scope", e.Scope) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExpressionEvaluationOptions. +func (e *ExpressionEvaluationOptions) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "scope": + err = unpopulate(val, "Scope", &e.Scope) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ExtendedLocation. +func (e ExtendedLocation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "name", e.Name) + populate(objectMap, "type", e.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ExtendedLocation. +func (e *ExtendedLocation) 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", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "name": + err = unpopulate(val, "Name", &e.Name) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &e.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type GenericResource. +func (g GenericResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + 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) + populateAny(objectMap, "properties", g.Properties) + 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 GenericResource. +func (g *GenericResource) 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 "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 "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 GenericResourceExpanded. +func (g GenericResourceExpanded) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateDateTimeRFC3339(objectMap, "changedTime", g.ChangedTime) + populateDateTimeRFC3339(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) + populateAny(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 = unpopulateDateTimeRFC3339(val, "ChangedTime", &g.ChangedTime) + delete(rawMsg, key) + case "createdTime": + err = unpopulateDateTimeRFC3339(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 GenericResourceFilter. +func (g GenericResourceFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "resourceType", g.ResourceType) + populate(objectMap, "tagname", g.Tagname) + populate(objectMap, "tagvalue", g.Tagvalue) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type GenericResourceFilter. +func (g *GenericResourceFilter) 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 "resourceType": + err = unpopulate(val, "ResourceType", &g.ResourceType) + delete(rawMsg, key) + case "tagname": + err = unpopulate(val, "Tagname", &g.Tagname) + delete(rawMsg, key) + case "tagvalue": + err = unpopulate(val, "Tagvalue", &g.Tagvalue) + 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 HTTPMessage. +func (h HTTPMessage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "content", h.Content) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type HTTPMessage. +func (h *HTTPMessage) 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", h, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "content": + err = unpopulate(val, "Content", &h.Content) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", h, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Identity. +func (i Identity) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "principalId", i.PrincipalID) + populate(objectMap, "tenantId", i.TenantID) + populate(objectMap, "type", i.Type) + populate(objectMap, "userAssignedIdentities", i.UserAssignedIdentities) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Identity. +func (i *Identity) 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", i, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "principalId": + err = unpopulate(val, "PrincipalID", &i.PrincipalID) + delete(rawMsg, key) + case "tenantId": + err = unpopulate(val, "TenantID", &i.TenantID) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &i.Type) + delete(rawMsg, key) + case "userAssignedIdentities": + err = unpopulate(val, "UserAssignedIdentities", &i.UserAssignedIdentities) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", i, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type IdentityUserAssignedIdentitiesValue. +func (i IdentityUserAssignedIdentitiesValue) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "clientId", i.ClientID) + populate(objectMap, "principalId", i.PrincipalID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type IdentityUserAssignedIdentitiesValue. +func (i *IdentityUserAssignedIdentitiesValue) 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", i, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "clientId": + err = unpopulate(val, "ClientID", &i.ClientID) + delete(rawMsg, key) + case "principalId": + err = unpopulate(val, "PrincipalID", &i.PrincipalID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", i, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type MoveInfo. +func (m MoveInfo) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "resources", m.Resources) + populate(objectMap, "targetResourceGroup", m.TargetResourceGroup) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type MoveInfo. +func (m *MoveInfo) 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", m, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "resources": + err = unpopulate(val, "Resources", &m.Resources) + delete(rawMsg, key) + case "targetResourceGroup": + err = unpopulate(val, "TargetResourceGroup", &m.TargetResourceGroup) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OnErrorDeployment. +func (o OnErrorDeployment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "deploymentName", o.DeploymentName) + populate(objectMap, "type", o.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OnErrorDeployment. +func (o *OnErrorDeployment) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "deploymentName": + err = unpopulate(val, "DeploymentName", &o.DeploymentName) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &o.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OnErrorDeploymentExtended. +func (o OnErrorDeploymentExtended) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "deploymentName", o.DeploymentName) + populate(objectMap, "provisioningState", o.ProvisioningState) + populate(objectMap, "type", o.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OnErrorDeploymentExtended. +func (o *OnErrorDeploymentExtended) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "deploymentName": + err = unpopulate(val, "DeploymentName", &o.DeploymentName) + delete(rawMsg, key) + case "provisioningState": + err = unpopulate(val, "ProvisioningState", &o.ProvisioningState) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &o.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Operation. +func (o Operation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "display", o.Display) + populate(objectMap, "name", o.Name) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Operation. +func (o *Operation) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "display": + err = unpopulate(val, "Display", &o.Display) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &o.Name) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OperationDisplay. +func (o OperationDisplay) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", o.Description) + populate(objectMap, "operation", o.Operation) + populate(objectMap, "provider", o.Provider) + populate(objectMap, "resource", o.Resource) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OperationDisplay. +func (o *OperationDisplay) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &o.Description) + delete(rawMsg, key) + case "operation": + err = unpopulate(val, "Operation", &o.Operation) + delete(rawMsg, key) + case "provider": + err = unpopulate(val, "Provider", &o.Provider) + delete(rawMsg, key) + case "resource": + err = unpopulate(val, "Resource", &o.Resource) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type OperationListResult. +func (o OperationListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", o.NextLink) + populate(objectMap, "value", o.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type OperationListResult. +func (o *OperationListResult) 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", o, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &o.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &o.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", o, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ParametersLink. +func (p ParametersLink) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "contentVersion", p.ContentVersion) + populate(objectMap, "uri", p.URI) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ParametersLink. +func (p *ParametersLink) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "contentVersion": + err = unpopulate(val, "ContentVersion", &p.ContentVersion) + delete(rawMsg, key) + case "uri": + err = unpopulate(val, "URI", &p.URI) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Permission. +func (p Permission) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "actions", p.Actions) + populate(objectMap, "dataActions", p.DataActions) + populate(objectMap, "notActions", p.NotActions) + populate(objectMap, "notDataActions", p.NotDataActions) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Permission. +func (p *Permission) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "actions": + err = unpopulate(val, "Actions", &p.Actions) + delete(rawMsg, key) + case "dataActions": + err = unpopulate(val, "DataActions", &p.DataActions) + delete(rawMsg, key) + case "notActions": + err = unpopulate(val, "NotActions", &p.NotActions) + delete(rawMsg, key) + case "notDataActions": + err = unpopulate(val, "NotDataActions", &p.NotDataActions) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Plan. +func (p Plan) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "name", p.Name) + populate(objectMap, "product", p.Product) + populate(objectMap, "promotionCode", p.PromotionCode) + populate(objectMap, "publisher", p.Publisher) + populate(objectMap, "version", p.Version) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Plan. +func (p *Plan) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "name": + err = unpopulate(val, "Name", &p.Name) + delete(rawMsg, key) + case "product": + err = unpopulate(val, "Product", &p.Product) + delete(rawMsg, key) + case "promotionCode": + err = unpopulate(val, "PromotionCode", &p.PromotionCode) + delete(rawMsg, key) + case "publisher": + err = unpopulate(val, "Publisher", &p.Publisher) + delete(rawMsg, key) + case "version": + err = unpopulate(val, "Version", &p.Version) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Provider. +func (p Provider) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", p.ID) + populate(objectMap, "namespace", p.Namespace) + populate(objectMap, "providerAuthorizationConsentState", p.ProviderAuthorizationConsentState) + populate(objectMap, "registrationPolicy", p.RegistrationPolicy) + populate(objectMap, "registrationState", p.RegistrationState) + populate(objectMap, "resourceTypes", p.ResourceTypes) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Provider. +func (p *Provider) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &p.ID) + delete(rawMsg, key) + case "namespace": + err = unpopulate(val, "Namespace", &p.Namespace) + delete(rawMsg, key) + case "providerAuthorizationConsentState": + err = unpopulate(val, "ProviderAuthorizationConsentState", &p.ProviderAuthorizationConsentState) + delete(rawMsg, key) + case "registrationPolicy": + err = unpopulate(val, "RegistrationPolicy", &p.RegistrationPolicy) + delete(rawMsg, key) + case "registrationState": + err = unpopulate(val, "RegistrationState", &p.RegistrationState) + delete(rawMsg, key) + case "resourceTypes": + err = unpopulate(val, "ResourceTypes", &p.ResourceTypes) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderConsentDefinition. +func (p ProviderConsentDefinition) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "consentToAuthorization", p.ConsentToAuthorization) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderConsentDefinition. +func (p *ProviderConsentDefinition) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "consentToAuthorization": + err = unpopulate(val, "ConsentToAuthorization", &p.ConsentToAuthorization) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderExtendedLocation. +func (p ProviderExtendedLocation) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "extendedLocations", p.ExtendedLocations) + populate(objectMap, "location", p.Location) + populate(objectMap, "type", p.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderExtendedLocation. +func (p *ProviderExtendedLocation) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "extendedLocations": + err = unpopulate(val, "ExtendedLocations", &p.ExtendedLocations) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &p.Location) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &p.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderListResult. +func (p ProviderListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", p.NextLink) + populate(objectMap, "value", p.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderListResult. +func (p *ProviderListResult) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &p.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &p.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderPermission. +func (p ProviderPermission) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "applicationId", p.ApplicationID) + populate(objectMap, "managedByRoleDefinition", p.ManagedByRoleDefinition) + populate(objectMap, "providerAuthorizationConsentState", p.ProviderAuthorizationConsentState) + populate(objectMap, "roleDefinition", p.RoleDefinition) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderPermission. +func (p *ProviderPermission) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "applicationId": + err = unpopulate(val, "ApplicationID", &p.ApplicationID) + delete(rawMsg, key) + case "managedByRoleDefinition": + err = unpopulate(val, "ManagedByRoleDefinition", &p.ManagedByRoleDefinition) + delete(rawMsg, key) + case "providerAuthorizationConsentState": + err = unpopulate(val, "ProviderAuthorizationConsentState", &p.ProviderAuthorizationConsentState) + delete(rawMsg, key) + case "roleDefinition": + err = unpopulate(val, "RoleDefinition", &p.RoleDefinition) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderPermissionListResult. +func (p ProviderPermissionListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", p.NextLink) + populate(objectMap, "value", p.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderPermissionListResult. +func (p *ProviderPermissionListResult) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &p.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &p.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderRegistrationRequest. +func (p ProviderRegistrationRequest) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "thirdPartyProviderConsent", p.ThirdPartyProviderConsent) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderRegistrationRequest. +func (p *ProviderRegistrationRequest) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "thirdPartyProviderConsent": + err = unpopulate(val, "ThirdPartyProviderConsent", &p.ThirdPartyProviderConsent) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderResourceType. +func (p ProviderResourceType) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "apiProfiles", p.APIProfiles) + populate(objectMap, "apiVersions", p.APIVersions) + populate(objectMap, "aliases", p.Aliases) + populate(objectMap, "capabilities", p.Capabilities) + populate(objectMap, "defaultApiVersion", p.DefaultAPIVersion) + populate(objectMap, "locationMappings", p.LocationMappings) + populate(objectMap, "locations", p.Locations) + populate(objectMap, "properties", p.Properties) + populate(objectMap, "resourceType", p.ResourceType) + populate(objectMap, "zoneMappings", p.ZoneMappings) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderResourceType. +func (p *ProviderResourceType) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "apiProfiles": + err = unpopulate(val, "APIProfiles", &p.APIProfiles) + delete(rawMsg, key) + case "apiVersions": + err = unpopulate(val, "APIVersions", &p.APIVersions) + delete(rawMsg, key) + case "aliases": + err = unpopulate(val, "Aliases", &p.Aliases) + delete(rawMsg, key) + case "capabilities": + err = unpopulate(val, "Capabilities", &p.Capabilities) + delete(rawMsg, key) + case "defaultApiVersion": + err = unpopulate(val, "DefaultAPIVersion", &p.DefaultAPIVersion) + delete(rawMsg, key) + case "locationMappings": + err = unpopulate(val, "LocationMappings", &p.LocationMappings) + delete(rawMsg, key) + case "locations": + err = unpopulate(val, "Locations", &p.Locations) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &p.Properties) + delete(rawMsg, key) + case "resourceType": + err = unpopulate(val, "ResourceType", &p.ResourceType) + delete(rawMsg, key) + case "zoneMappings": + err = unpopulate(val, "ZoneMappings", &p.ZoneMappings) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ProviderResourceTypeListResult. +func (p ProviderResourceTypeListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", p.NextLink) + populate(objectMap, "value", p.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ProviderResourceTypeListResult. +func (p *ProviderResourceTypeListResult) 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", p, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &p.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &p.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", p, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Resource. +func (r Resource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + 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) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Resource. +func (r *Resource) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "extendedLocation": + err = unpopulate(val, "ExtendedLocation", &r.ExtendedLocation) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &r.Location) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &r.Tags) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceGroup. +func (r ResourceGroup) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + 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) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceGroup. +func (r *ResourceGroup) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "location": + err = unpopulate(val, "Location", &r.Location) + delete(rawMsg, key) + case "managedBy": + err = unpopulate(val, "ManagedBy", &r.ManagedBy) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &r.Tags) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &r.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceGroupExportResult. +func (r ResourceGroupExportResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", r.Error) + populateAny(objectMap, "template", r.Template) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceGroupExportResult. +func (r *ResourceGroupExportResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &r.Error) + delete(rawMsg, key) + case "template": + err = unpopulate(val, "Template", &r.Template) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceGroupFilter. +func (r ResourceGroupFilter) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "tagName", r.TagName) + populate(objectMap, "tagValue", r.TagValue) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceGroupFilter. +func (r *ResourceGroupFilter) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "tagName": + err = unpopulate(val, "TagName", &r.TagName) + delete(rawMsg, key) + case "tagValue": + err = unpopulate(val, "TagValue", &r.TagValue) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceGroupListResult. +func (r ResourceGroupListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceGroupListResult. +func (r *ResourceGroupListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceGroupPatchable. +func (r ResourceGroupPatchable) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "managedBy", r.ManagedBy) + populate(objectMap, "name", r.Name) + populate(objectMap, "properties", r.Properties) + populate(objectMap, "tags", r.Tags) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceGroupPatchable. +func (r *ResourceGroupPatchable) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "managedBy": + err = unpopulate(val, "ManagedBy", &r.ManagedBy) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &r.Properties) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &r.Tags) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceGroupProperties. +func (r ResourceGroupProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "provisioningState", r.ProvisioningState) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceGroupProperties. +func (r *ResourceGroupProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "provisioningState": + err = unpopulate(val, "ProvisioningState", &r.ProvisioningState) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceListResult. +func (r ResourceListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", r.NextLink) + populate(objectMap, "value", r.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceListResult. +func (r *ResourceListResult) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &r.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &r.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceProviderOperationDisplayProperties. +func (r ResourceProviderOperationDisplayProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", r.Description) + populate(objectMap, "operation", r.Operation) + populate(objectMap, "provider", r.Provider) + populate(objectMap, "publisher", r.Publisher) + populate(objectMap, "resource", r.Resource) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceProviderOperationDisplayProperties. +func (r *ResourceProviderOperationDisplayProperties) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &r.Description) + delete(rawMsg, key) + case "operation": + err = unpopulate(val, "Operation", &r.Operation) + delete(rawMsg, key) + case "provider": + err = unpopulate(val, "Provider", &r.Provider) + delete(rawMsg, key) + case "publisher": + err = unpopulate(val, "Publisher", &r.Publisher) + delete(rawMsg, key) + case "resource": + err = unpopulate(val, "Resource", &r.Resource) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ResourceReference. +func (r ResourceReference) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ResourceReference. +func (r *ResourceReference) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type RoleDefinition. +func (r RoleDefinition) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", r.ID) + populate(objectMap, "isServiceRole", r.IsServiceRole) + populate(objectMap, "name", r.Name) + populate(objectMap, "permissions", r.Permissions) + populate(objectMap, "scopes", r.Scopes) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type RoleDefinition. +func (r *RoleDefinition) 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", r, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &r.ID) + delete(rawMsg, key) + case "isServiceRole": + err = unpopulate(val, "IsServiceRole", &r.IsServiceRole) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &r.Name) + delete(rawMsg, key) + case "permissions": + err = unpopulate(val, "Permissions", &r.Permissions) + delete(rawMsg, key) + case "scopes": + err = unpopulate(val, "Scopes", &r.Scopes) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", r, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SKU. +func (s SKU) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "capacity", s.Capacity) + populate(objectMap, "family", s.Family) + populate(objectMap, "model", s.Model) + populate(objectMap, "name", s.Name) + populate(objectMap, "size", s.Size) + populate(objectMap, "tier", s.Tier) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SKU. +func (s *SKU) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "capacity": + err = unpopulate(val, "Capacity", &s.Capacity) + delete(rawMsg, key) + case "family": + err = unpopulate(val, "Family", &s.Family) + delete(rawMsg, key) + case "model": + err = unpopulate(val, "Model", &s.Model) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &s.Name) + delete(rawMsg, key) + case "size": + err = unpopulate(val, "Size", &s.Size) + delete(rawMsg, key) + case "tier": + err = unpopulate(val, "Tier", &s.Tier) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ScopedDeployment. +func (s ScopedDeployment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "location", s.Location) + populate(objectMap, "properties", s.Properties) + populate(objectMap, "tags", s.Tags) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ScopedDeployment. +func (s *ScopedDeployment) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "location": + err = unpopulate(val, "Location", &s.Location) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &s.Properties) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &s.Tags) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ScopedDeploymentWhatIf. +func (s ScopedDeploymentWhatIf) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "location", s.Location) + populate(objectMap, "properties", s.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ScopedDeploymentWhatIf. +func (s *ScopedDeploymentWhatIf) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "location": + err = unpopulate(val, "Location", &s.Location) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &s.Properties) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type StatusMessage. +func (s StatusMessage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", s.Error) + populate(objectMap, "status", s.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type StatusMessage. +func (s *StatusMessage) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &s.Error) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &s.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type SubResource. +func (s SubResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", s.ID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type SubResource. +func (s *SubResource) 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", s, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &s.ID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", s, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagCount. +func (t TagCount) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "type", t.Type) + populate(objectMap, "value", t.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagCount. +func (t *TagCount) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "type": + err = unpopulate(val, "Type", &t.Type) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &t.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagDetails. +func (t TagDetails) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "count", t.Count) + populate(objectMap, "id", t.ID) + populate(objectMap, "tagName", t.TagName) + populate(objectMap, "values", t.Values) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagDetails. +func (t *TagDetails) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "count": + err = unpopulate(val, "Count", &t.Count) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &t.ID) + delete(rawMsg, key) + case "tagName": + err = unpopulate(val, "TagName", &t.TagName) + delete(rawMsg, key) + case "values": + err = unpopulate(val, "Values", &t.Values) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagValue. +func (t TagValue) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "count", t.Count) + populate(objectMap, "id", t.ID) + populate(objectMap, "tagValue", t.TagValue) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagValue. +func (t *TagValue) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "count": + err = unpopulate(val, "Count", &t.Count) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &t.ID) + delete(rawMsg, key) + case "tagValue": + err = unpopulate(val, "TagValue", &t.TagValue) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Tags. +func (t Tags) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "tags", t.Tags) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Tags. +func (t *Tags) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "tags": + err = unpopulate(val, "Tags", &t.Tags) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagsListResult. +func (t TagsListResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "nextLink", t.NextLink) + populate(objectMap, "value", t.Value) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagsListResult. +func (t *TagsListResult) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "nextLink": + err = unpopulate(val, "NextLink", &t.NextLink) + delete(rawMsg, key) + case "value": + err = unpopulate(val, "Value", &t.Value) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagsPatchResource. +func (t TagsPatchResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "operation", t.Operation) + populate(objectMap, "properties", t.Properties) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagsPatchResource. +func (t *TagsPatchResource) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "operation": + err = unpopulate(val, "Operation", &t.Operation) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &t.Properties) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TagsResource. +func (t TagsResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", t.ID) + populate(objectMap, "name", t.Name) + populate(objectMap, "properties", t.Properties) + populate(objectMap, "type", t.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TagsResource. +func (t *TagsResource) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &t.ID) + delete(rawMsg, key) + case "name": + err = unpopulate(val, "Name", &t.Name) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &t.Properties) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &t.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TargetResource. +func (t TargetResource) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", t.ID) + populate(objectMap, "resourceName", t.ResourceName) + populate(objectMap, "resourceType", t.ResourceType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TargetResource. +func (t *TargetResource) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &t.ID) + delete(rawMsg, key) + case "resourceName": + err = unpopulate(val, "ResourceName", &t.ResourceName) + delete(rawMsg, key) + case "resourceType": + err = unpopulate(val, "ResourceType", &t.ResourceType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TemplateHashResult. +func (t TemplateHashResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "minifiedTemplate", t.MinifiedTemplate) + populate(objectMap, "templateHash", t.TemplateHash) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TemplateHashResult. +func (t *TemplateHashResult) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "minifiedTemplate": + err = unpopulate(val, "MinifiedTemplate", &t.MinifiedTemplate) + delete(rawMsg, key) + case "templateHash": + err = unpopulate(val, "TemplateHash", &t.TemplateHash) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type TemplateLink. +func (t TemplateLink) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "contentVersion", t.ContentVersion) + populate(objectMap, "id", t.ID) + populate(objectMap, "queryString", t.QueryString) + populate(objectMap, "relativePath", t.RelativePath) + populate(objectMap, "uri", t.URI) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type TemplateLink. +func (t *TemplateLink) 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", t, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "contentVersion": + err = unpopulate(val, "ContentVersion", &t.ContentVersion) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &t.ID) + delete(rawMsg, key) + case "queryString": + err = unpopulate(val, "QueryString", &t.QueryString) + delete(rawMsg, key) + case "relativePath": + err = unpopulate(val, "RelativePath", &t.RelativePath) + delete(rawMsg, key) + case "uri": + err = unpopulate(val, "URI", &t.URI) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", t, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type WhatIfChange. +func (w WhatIfChange) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "after", w.After) + populateAny(objectMap, "before", w.Before) + populate(objectMap, "changeType", w.ChangeType) + populate(objectMap, "delta", w.Delta) + populate(objectMap, "resourceId", w.ResourceID) + populate(objectMap, "unsupportedReason", w.UnsupportedReason) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type WhatIfChange. +func (w *WhatIfChange) 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", w, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "after": + err = unpopulate(val, "After", &w.After) + delete(rawMsg, key) + case "before": + err = unpopulate(val, "Before", &w.Before) + delete(rawMsg, key) + case "changeType": + err = unpopulate(val, "ChangeType", &w.ChangeType) + delete(rawMsg, key) + case "delta": + err = unpopulate(val, "Delta", &w.Delta) + delete(rawMsg, key) + case "resourceId": + err = unpopulate(val, "ResourceID", &w.ResourceID) + delete(rawMsg, key) + case "unsupportedReason": + err = unpopulate(val, "UnsupportedReason", &w.UnsupportedReason) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", w, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type WhatIfOperationProperties. +func (w WhatIfOperationProperties) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "changes", w.Changes) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type WhatIfOperationProperties. +func (w *WhatIfOperationProperties) 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", w, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "changes": + err = unpopulate(val, "Changes", &w.Changes) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", w, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type WhatIfOperationResult. +func (w WhatIfOperationResult) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", w.Error) + populate(objectMap, "properties", w.Properties) + populate(objectMap, "status", w.Status) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type WhatIfOperationResult. +func (w *WhatIfOperationResult) 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", w, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &w.Error) + delete(rawMsg, key) + case "properties": + err = unpopulate(val, "Properties", &w.Properties) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &w.Status) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", w, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type WhatIfPropertyChange. +func (w WhatIfPropertyChange) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "after", w.After) + populateAny(objectMap, "before", w.Before) + populate(objectMap, "children", w.Children) + populate(objectMap, "path", w.Path) + populate(objectMap, "propertyChangeType", w.PropertyChangeType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type WhatIfPropertyChange. +func (w *WhatIfPropertyChange) 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", w, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "after": + err = unpopulate(val, "After", &w.After) + delete(rawMsg, key) + case "before": + err = unpopulate(val, "Before", &w.Before) + delete(rawMsg, key) + case "children": + err = unpopulate(val, "Children", &w.Children) + delete(rawMsg, key) + case "path": + err = unpopulate(val, "Path", &w.Path) + delete(rawMsg, key) + case "propertyChangeType": + err = unpopulate(val, "PropertyChangeType", &w.PropertyChangeType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", w, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ZoneMapping. +func (z ZoneMapping) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "location", z.Location) + populate(objectMap, "zones", z.Zones) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ZoneMapping. +func (z *ZoneMapping) 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", z, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "location": + err = unpopulate(val, "Location", &z.Location) + delete(rawMsg, key) + case "zones": + err = unpopulate(val, "Zones", &z.Zones) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", z, err) + } + } + return nil +} + +func populate(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else if !reflect.ValueOf(v).IsNil() { + m[k] = v + } +} + +func populateAny(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else { + m[k] = v + } +} + +func unpopulate(data json.RawMessage, fn string, v any) 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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/operations_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/operations_client.go new file mode 100644 index 000000000..e0fc6b961 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/operations_client.go @@ -0,0 +1,88 @@ +//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 ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" +) + +// OperationsClient contains the methods for the Operations group. +// Don't use this type directly, use NewOperationsClient() instead. +type OperationsClient struct { + 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. +func NewOperationsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*OperationsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &OperationsClient{ + internal: cl, + } + return client, nil +} + +// NewListPager - Lists all of the available Microsoft.Resources REST API operations. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *OperationsClient) listHandleResponse(resp *http.Response) (OperationsClientListResponse, error) { + result := OperationsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.OperationListResult); err != nil { + return OperationsClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/options.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/options.go new file mode 100644 index 000000000..dfdb23b0c --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/options.go @@ -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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/providerresourcetypes_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/providerresourcetypes_client.go new file mode 100644 index 000000000..a64c08f02 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/providerresourcetypes_client.go @@ -0,0 +1,107 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// ProviderResourceTypesClient contains the methods for the ProviderResourceTypes group. +// Don't use this type directly, use NewProviderResourceTypesClient() instead. +type ProviderResourceTypesClient struct { + internal *arm.Client + subscriptionID string +} + +// 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. +func NewProviderResourceTypesClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ProviderResourceTypesClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &ProviderResourceTypesClient{ + subscriptionID: subscriptionID, + 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProviderResourceTypesClientListResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProviderResourceTypesClientListResponse{}, err + } + resp, err := client.listHandleResponse(httpResp) + return resp, err +} + +// listCreateRequest creates the List request. +func (client *ProviderResourceTypesClient) listCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProviderResourceTypesClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/resourceTypes" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *ProviderResourceTypesClient) listHandleResponse(resp *http.Response) (ProviderResourceTypesClientListResponse, error) { + result := ProviderResourceTypesClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ProviderResourceTypeListResult); err != nil { + return ProviderResourceTypesClientListResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/providers_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/providers_client.go new file mode 100644 index 000000000..e1612d160 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/providers_client.go @@ -0,0 +1,511 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// ProvidersClient contains the methods for the Providers group. +// Don't use this type directly, use NewProvidersClient() instead. +type ProvidersClient struct { + internal *arm.Client + subscriptionID string +} + +// 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. +func NewProvidersClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ProvidersClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &ProvidersClient{ + subscriptionID: subscriptionID, + 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProvidersClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProvidersClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *ProvidersClient) getCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *ProvidersClient) getHandleResponse(resp *http.Response) (ProvidersClientGetResponse, error) { + result := ProvidersClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Provider); err != nil { + return ProvidersClientGetResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProvidersClientGetAtTenantScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProvidersClientGetAtTenantScopeResponse{}, err + } + resp, err := client.getAtTenantScopeHandleResponse(httpResp) + return resp, err +} + +// getAtTenantScopeCreateRequest creates the GetAtTenantScope request. +func (client *ProvidersClient) getAtTenantScopeCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientGetAtTenantScopeOptions) (*policy.Request, error) { + urlPath := "/providers/{resourceProviderNamespace}" + if resourceProviderNamespace == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtTenantScopeHandleResponse handles the GetAtTenantScope response. +func (client *ProvidersClient) getAtTenantScopeHandleResponse(resp *http.Response) (ProvidersClientGetAtTenantScopeResponse, error) { + result := ProvidersClientGetAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Provider); err != nil { + return ProvidersClientGetAtTenantScopeResponse{}, err + } + return result, nil +} + +// NewListPager - Gets all resource providers for a subscription. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *ProvidersClient) listCreateRequest(ctx context.Context, options *ProvidersClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *ProvidersClient) listHandleResponse(resp *http.Response) (ProvidersClientListResponse, error) { + result := ProvidersClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ProviderListResult); err != nil { + return ProvidersClientListResponse{}, err + } + return result, nil +} + +// NewListAtTenantScopePager - Gets all resource providers for the tenant. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Expand != nil { + reqQP.Set("$expand", *options.Expand) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listAtTenantScopeHandleResponse handles the ListAtTenantScope response. +func (client *ProvidersClient) listAtTenantScopeHandleResponse(resp *http.Response) (ProvidersClientListAtTenantScopeResponse, error) { + result := ProvidersClientListAtTenantScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ProviderListResult); err != nil { + return ProvidersClientListAtTenantScopeResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProvidersClientProviderPermissionsResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProvidersClientProviderPermissionsResponse{}, err + } + resp, err := client.providerPermissionsHandleResponse(httpResp) + return resp, err +} + +// providerPermissionsCreateRequest creates the ProviderPermissions request. +func (client *ProvidersClient) providerPermissionsCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientProviderPermissionsOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/providerPermissions" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// providerPermissionsHandleResponse handles the ProviderPermissions response. +func (client *ProvidersClient) providerPermissionsHandleResponse(resp *http.Response) (ProvidersClientProviderPermissionsResponse, error) { + result := ProvidersClientProviderPermissionsResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ProviderPermissionListResult); err != nil { + return ProvidersClientProviderPermissionsResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProvidersClientRegisterResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProvidersClientRegisterResponse{}, err + } + resp, err := client.registerHandleResponse(httpResp) + return resp, err +} + +// registerCreateRequest creates the Register request. +func (client *ProvidersClient) registerCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientRegisterOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if options != nil && options.Properties != nil { + if err := runtime.MarshalAsJSON(req, *options.Properties); err != nil { + return nil, err + } + return req, nil + } + return req, nil +} + +// registerHandleResponse handles the Register response. +func (client *ProvidersClient) registerHandleResponse(resp *http.Response) (ProvidersClientRegisterResponse, error) { + result := ProvidersClientRegisterResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Provider); err != nil { + return ProvidersClientRegisterResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProvidersClientRegisterAtManagementGroupScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProvidersClientRegisterAtManagementGroupScopeResponse{}, err + } + return ProvidersClientRegisterAtManagementGroupScopeResponse{}, nil +} + +// registerAtManagementGroupScopeCreateRequest creates the RegisterAtManagementGroupScope request. +func (client *ProvidersClient) registerAtManagementGroupScopeCreateRequest(ctx context.Context, resourceProviderNamespace string, groupID string, options *ProvidersClientRegisterAtManagementGroupScopeOptions) (*policy.Request, error) { + urlPath := "/providers/Microsoft.Management/managementGroups/{groupId}/providers/{resourceProviderNamespace}/register" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if groupID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ProvidersClientUnregisterResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ProvidersClientUnregisterResponse{}, err + } + resp, err := client.unregisterHandleResponse(httpResp) + return resp, err +} + +// unregisterCreateRequest creates the Unregister request. +func (client *ProvidersClient) unregisterCreateRequest(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientUnregisterOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/unregister" + if resourceProviderNamespace == "" { + return nil, errors.New("parameter resourceProviderNamespace cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// unregisterHandleResponse handles the Unregister response. +func (client *ProvidersClient) unregisterHandleResponse(resp *http.Response) (ProvidersClientUnregisterResponse, error) { + result := ProvidersClientUnregisterResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Provider); err != nil { + return ProvidersClientUnregisterResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/resourcegroups_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/resourcegroups_client.go new file mode 100644 index 000000000..b228d9f64 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/resourcegroups_client.go @@ -0,0 +1,495 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strconv" + "strings" +) + +// ResourceGroupsClient contains the methods for the ResourceGroups group. +// Don't use this type directly, use NewResourceGroupsClient() instead. +type ResourceGroupsClient struct { + internal *arm.Client + subscriptionID string +} + +// 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. +func NewResourceGroupsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ResourceGroupsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &ResourceGroupsClient{ + subscriptionID: subscriptionID, + 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ResourceGroupsClientCheckExistenceResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) { + err = runtime.NewResponseError(httpResp) + return ResourceGroupsClientCheckExistenceResponse{}, err + } + return ResourceGroupsClientCheckExistenceResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil +} + +// checkExistenceCreateRequest creates the CheckExistence request. +func (client *ResourceGroupsClient) checkExistenceCreateRequest(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientCheckExistenceOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ResourceGroupsClientCreateOrUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return ResourceGroupsClientCreateOrUpdateResponse{}, err + } + resp, err := client.createOrUpdateHandleResponse(httpResp) + return resp, err +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *ResourceGroupsClient) createOrUpdateCreateRequest(ctx context.Context, resourceGroupName string, parameters ResourceGroup, options *ResourceGroupsClientCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createOrUpdateHandleResponse handles the CreateOrUpdate response. +func (client *ResourceGroupsClient) createOrUpdateHandleResponse(resp *http.Response) (ResourceGroupsClientCreateOrUpdateResponse, error) { + result := ResourceGroupsClientCreateOrUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ResourceGroup); err != nil { + return ResourceGroupsClientCreateOrUpdateResponse{}, err + } + return result, nil +} + +// 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. +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 + } + poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ResourceGroupsClientDeleteResponse]{ + Tracer: client.internal.Tracer(), + }) + return poller, err + } else { + 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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *ResourceGroupsClient) deleteCreateRequest(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientBeginDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.ForceDeletionTypes != nil { + reqQP.Set("forceDeletionTypes", *options.ForceDeletionTypes) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// 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. +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 + } + 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(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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return nil, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) { + err = runtime.NewResponseError(httpResp) + return nil, err + } + return httpResp, nil +} + +// exportTemplateCreateRequest creates the ExportTemplate request. +func (client *ResourceGroupsClient) exportTemplateCreateRequest(ctx context.Context, resourceGroupName string, parameters ExportTemplateRequest, options *ResourceGroupsClientBeginExportTemplateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/exportTemplate" + if client.subscriptionID == "" { + return nil, errors.New("parameter client.subscriptionID cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID)) + if resourceGroupName == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ResourceGroupsClientGetResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ResourceGroupsClientGetResponse{}, err + } + resp, err := client.getHandleResponse(httpResp) + return resp, err +} + +// getCreateRequest creates the Get request. +func (client *ResourceGroupsClient) getCreateRequest(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientGetOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getHandleResponse handles the Get response. +func (client *ResourceGroupsClient) getHandleResponse(resp *http.Response) (ResourceGroupsClientGetResponse, error) { + result := ResourceGroupsClientGetResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ResourceGroup); err != nil { + return ResourceGroupsClientGetResponse{}, err + } + return result, nil +} + +// NewListPager - Gets all the resource groups for a subscription. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *ResourceGroupsClient) listCreateRequest(ctx context.Context, options *ResourceGroupsClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + if options != nil && options.Filter != nil { + reqQP.Set("$filter", *options.Filter) + } + if options != nil && options.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *ResourceGroupsClient) listHandleResponse(resp *http.Response) (ResourceGroupsClientListResponse, error) { + result := ResourceGroupsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ResourceGroupListResult); err != nil { + return ResourceGroupsClientListResponse{}, err + } + return result, nil +} + +// Update - Resource groups can be updated through a simple PATCH operation to a group address. The format of the request +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ResourceGroupsClientUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ResourceGroupsClientUpdateResponse{}, err + } + resp, err := client.updateHandleResponse(httpResp) + return resp, err +} + +// updateCreateRequest creates the Update request. +func (client *ResourceGroupsClient) updateCreateRequest(ctx context.Context, resourceGroupName string, parameters ResourceGroupPatchable, options *ResourceGroupsClientUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}" + if resourceGroupName == "" { + return nil, errors.New("parameter resourceGroupName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// updateHandleResponse handles the Update response. +func (client *ResourceGroupsClient) updateHandleResponse(resp *http.Response) (ResourceGroupsClientUpdateResponse, error) { + result := ResourceGroupsClientUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ResourceGroup); err != nil { + return ResourceGroupsClientUpdateResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/response_types.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/response_types.go new file mode 100644 index 000000000..fb04138cd --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/response_types.go @@ -0,0 +1,561 @@ +//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 + +// ClientCheckExistenceByIDResponse contains the response from method Client.CheckExistenceByID. +type ClientCheckExistenceByIDResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// ClientCheckExistenceResponse contains the response from method Client.CheckExistence. +type ClientCheckExistenceResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// ClientCreateOrUpdateByIDResponse contains the response from method Client.BeginCreateOrUpdateByID. +type ClientCreateOrUpdateByIDResponse struct { + // Resource information. + GenericResource +} + +// ClientCreateOrUpdateResponse contains the response from method Client.BeginCreateOrUpdate. +type ClientCreateOrUpdateResponse struct { + // Resource information. + GenericResource +} + +// ClientDeleteByIDResponse contains the response from method Client.BeginDeleteByID. +type ClientDeleteByIDResponse struct { + // placeholder for future response values +} + +// 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.NewListByResourceGroupPager. +type ClientListByResourceGroupResponse struct { + // List of resource groups. + ResourceListResult +} + +// ClientListResponse contains the response from method Client.NewListPager. +type ClientListResponse struct { + // List of resource groups. + ResourceListResult +} + +// ClientMoveResourcesResponse contains the response from method Client.BeginMoveResources. +type ClientMoveResourcesResponse struct { + // placeholder for future response values +} + +// ClientUpdateByIDResponse contains the response from method Client.BeginUpdateByID. +type ClientUpdateByIDResponse struct { + // Resource information. + GenericResource +} + +// ClientUpdateResponse contains the response from method Client.BeginUpdate. +type ClientUpdateResponse struct { + // Resource information. + GenericResource +} + +// 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.NewListAtManagementGroupScopePager. +type DeploymentOperationsClientListAtManagementGroupScopeResponse struct { + // List of deployment operations. + DeploymentOperationsListResult +} + +// DeploymentOperationsClientListAtScopeResponse contains the response from method DeploymentOperationsClient.NewListAtScopePager. +type DeploymentOperationsClientListAtScopeResponse struct { + // List of deployment operations. + DeploymentOperationsListResult +} + +// DeploymentOperationsClientListAtSubscriptionScopeResponse contains the response from method DeploymentOperationsClient.NewListAtSubscriptionScopePager. +type DeploymentOperationsClientListAtSubscriptionScopeResponse struct { + // List of deployment operations. + DeploymentOperationsListResult +} + +// DeploymentOperationsClientListAtTenantScopeResponse contains the response from method DeploymentOperationsClient.NewListAtTenantScopePager. +type DeploymentOperationsClientListAtTenantScopeResponse struct { + // List of deployment operations. + DeploymentOperationsListResult +} + +// 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 +} + +// DeploymentsClientCancelAtManagementGroupScopeResponse contains the response from method DeploymentsClient.CancelAtManagementGroupScope. +type DeploymentsClientCancelAtManagementGroupScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientCancelAtScopeResponse contains the response from method DeploymentsClient.CancelAtScope. +type DeploymentsClientCancelAtScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientCancelAtSubscriptionScopeResponse contains the response from method DeploymentsClient.CancelAtSubscriptionScope. +type DeploymentsClientCancelAtSubscriptionScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientCancelAtTenantScopeResponse contains the response from method DeploymentsClient.CancelAtTenantScope. +type DeploymentsClientCancelAtTenantScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientCancelResponse contains the response from method DeploymentsClient.Cancel. +type DeploymentsClientCancelResponse struct { + // placeholder for future response values +} + +// DeploymentsClientCheckExistenceAtManagementGroupScopeResponse contains the response from method DeploymentsClient.CheckExistenceAtManagementGroupScope. +type DeploymentsClientCheckExistenceAtManagementGroupScopeResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// DeploymentsClientCheckExistenceAtScopeResponse contains the response from method DeploymentsClient.CheckExistenceAtScope. +type DeploymentsClientCheckExistenceAtScopeResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// DeploymentsClientCheckExistenceAtSubscriptionScopeResponse contains the response from method DeploymentsClient.CheckExistenceAtSubscriptionScope. +type DeploymentsClientCheckExistenceAtSubscriptionScopeResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// DeploymentsClientCheckExistenceAtTenantScopeResponse contains the response from method DeploymentsClient.CheckExistenceAtTenantScope. +type DeploymentsClientCheckExistenceAtTenantScopeResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// DeploymentsClientCheckExistenceResponse contains the response from method DeploymentsClient.CheckExistence. +type DeploymentsClientCheckExistenceResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtManagementGroupScope. +type DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse struct { + // Deployment information. + DeploymentExtended +} + +// DeploymentsClientCreateOrUpdateAtScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtScope. +type DeploymentsClientCreateOrUpdateAtScopeResponse struct { + // Deployment information. + DeploymentExtended +} + +// DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtSubscriptionScope. +type DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse struct { + // Deployment information. + DeploymentExtended +} + +// DeploymentsClientCreateOrUpdateAtTenantScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtTenantScope. +type DeploymentsClientCreateOrUpdateAtTenantScopeResponse struct { + // Deployment information. + DeploymentExtended +} + +// DeploymentsClientCreateOrUpdateResponse contains the response from method DeploymentsClient.BeginCreateOrUpdate. +type DeploymentsClientCreateOrUpdateResponse struct { + // Deployment information. + DeploymentExtended +} + +// DeploymentsClientDeleteAtManagementGroupScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtManagementGroupScope. +type DeploymentsClientDeleteAtManagementGroupScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientDeleteAtScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtScope. +type DeploymentsClientDeleteAtScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientDeleteAtSubscriptionScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtSubscriptionScope. +type DeploymentsClientDeleteAtSubscriptionScopeResponse struct { + // placeholder for future response values +} + +// DeploymentsClientDeleteAtTenantScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtTenantScope. +type DeploymentsClientDeleteAtTenantScopeResponse struct { + // placeholder for future response values +} + +// 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.NewListAtManagementGroupScopePager. +type DeploymentsClientListAtManagementGroupScopeResponse struct { + // List of deployments. + DeploymentListResult +} + +// DeploymentsClientListAtScopeResponse contains the response from method DeploymentsClient.NewListAtScopePager. +type DeploymentsClientListAtScopeResponse struct { + // List of deployments. + DeploymentListResult +} + +// DeploymentsClientListAtSubscriptionScopeResponse contains the response from method DeploymentsClient.NewListAtSubscriptionScopePager. +type DeploymentsClientListAtSubscriptionScopeResponse struct { + // List of deployments. + DeploymentListResult +} + +// DeploymentsClientListAtTenantScopeResponse contains the response from method DeploymentsClient.NewListAtTenantScopePager. +type DeploymentsClientListAtTenantScopeResponse struct { + // List of deployments. + DeploymentListResult +} + +// DeploymentsClientListByResourceGroupResponse contains the response from method DeploymentsClient.NewListByResourceGroupPager. +type DeploymentsClientListByResourceGroupResponse struct { + // List of deployments. + DeploymentListResult +} + +// 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.BeginValidateAtScope. +type DeploymentsClientValidateAtScopeResponse struct { + // Information from validate template deployment response. + DeploymentValidateResult +} + +// 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.BeginValidateAtTenantScope. +type DeploymentsClientValidateAtTenantScopeResponse struct { + // Information from validate template deployment response. + DeploymentValidateResult +} + +// 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.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.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.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.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.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.NewListAtTenantScopePager. +type ProvidersClientListAtTenantScopeResponse struct { + // List of resource providers. + ProviderListResult +} + +// 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 +} + +// ProvidersClientRegisterAtManagementGroupScopeResponse contains the response from method ProvidersClient.RegisterAtManagementGroupScope. +type ProvidersClientRegisterAtManagementGroupScopeResponse struct { + // placeholder for future response values +} + +// 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 +} + +// ResourceGroupsClientCheckExistenceResponse contains the response from method ResourceGroupsClient.CheckExistence. +type ResourceGroupsClientCheckExistenceResponse struct { + // Success indicates if the operation succeeded or failed. + Success bool +} + +// ResourceGroupsClientCreateOrUpdateResponse contains the response from method ResourceGroupsClient.CreateOrUpdate. +type ResourceGroupsClientCreateOrUpdateResponse struct { + // Resource group information. + ResourceGroup +} + +// ResourceGroupsClientDeleteResponse contains the response from method ResourceGroupsClient.BeginDelete. +type ResourceGroupsClientDeleteResponse struct { + // placeholder for future response values +} + +// 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.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 +} + +// TagsClientDeleteAtScopeResponse contains the response from method TagsClient.DeleteAtScope. +type TagsClientDeleteAtScopeResponse struct { + // placeholder for future response values +} + +// TagsClientDeleteResponse contains the response from method TagsClient.Delete. +type TagsClientDeleteResponse struct { + // placeholder for future response values +} + +// TagsClientDeleteValueResponse contains the response from method TagsClient.DeleteValue. +type TagsClientDeleteValueResponse struct { + // placeholder for future response values +} + +// 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.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 +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/tags_client.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/tags_client.go new file mode 100644 index 000000000..b6d0fc249 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/tags_client.go @@ -0,0 +1,544 @@ +//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 ( + "context" + "errors" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// TagsClient contains the methods for the Tags group. +// Don't use this type directly, use NewTagsClient() instead. +type TagsClient struct { + internal *arm.Client + subscriptionID string +} + +// 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. +func NewTagsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*TagsClient, error) { + cl, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + client := &TagsClient{ + subscriptionID: subscriptionID, + internal: cl, + } + return client, nil +} + +// CreateOrUpdate - This operation allows adding a name to the list of predefined tag names for the given subscription. A +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientCreateOrUpdateResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return TagsClientCreateOrUpdateResponse{}, err + } + resp, err := client.createOrUpdateHandleResponse(httpResp) + return resp, err +} + +// createOrUpdateCreateRequest creates the CreateOrUpdate request. +func (client *TagsClient) createOrUpdateCreateRequest(ctx context.Context, tagName string, options *TagsClientCreateOrUpdateOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/tagNames/{tagName}" + if tagName == "" { + return nil, errors.New("parameter tagName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{tagName}", url.PathEscape(tagName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// createOrUpdateHandleResponse handles the CreateOrUpdate response. +func (client *TagsClient) createOrUpdateHandleResponse(resp *http.Response) (TagsClientCreateOrUpdateResponse, error) { + result := TagsClientCreateOrUpdateResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TagDetails); err != nil { + return TagsClientCreateOrUpdateResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientCreateOrUpdateAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return TagsClientCreateOrUpdateAtScopeResponse{}, err + } + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// createOrUpdateAtScopeHandleResponse handles the CreateOrUpdateAtScope response. +func (client *TagsClient) createOrUpdateAtScopeHandleResponse(resp *http.Response) (TagsClientCreateOrUpdateAtScopeResponse, error) { + result := TagsClientCreateOrUpdateAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TagsResource); err != nil { + return TagsClientCreateOrUpdateAtScopeResponse{}, err + } + return result, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientCreateOrUpdateValueResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) { + err = runtime.NewResponseError(httpResp) + return TagsClientCreateOrUpdateValueResponse{}, err + } + resp, err := client.createOrUpdateValueHandleResponse(httpResp) + return resp, err +} + +// createOrUpdateValueCreateRequest creates the CreateOrUpdateValue request. +func (client *TagsClient) createOrUpdateValueCreateRequest(ctx context.Context, tagName string, tagValue string, options *TagsClientCreateOrUpdateValueOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}" + if tagName == "" { + return nil, errors.New("parameter tagName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{tagName}", url.PathEscape(tagName)) + if tagValue == "" { + return nil, errors.New("parameter tagValue cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{tagValue}", url.PathEscape(tagValue)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// createOrUpdateValueHandleResponse handles the CreateOrUpdateValue response. +func (client *TagsClient) createOrUpdateValueHandleResponse(resp *http.Response) (TagsClientCreateOrUpdateValueResponse, error) { + result := TagsClientCreateOrUpdateValueResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TagValue); err != nil { + return TagsClientCreateOrUpdateValueResponse{}, err + } + return result, nil +} + +// Delete - This operation allows deleting a name from the list of predefined tag names for the given subscription. The name +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientDeleteResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return TagsClientDeleteResponse{}, err + } + return TagsClientDeleteResponse{}, nil +} + +// deleteCreateRequest creates the Delete request. +func (client *TagsClient) deleteCreateRequest(ctx context.Context, tagName string, options *TagsClientDeleteOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/tagNames/{tagName}" + if tagName == "" { + return nil, errors.New("parameter tagName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{tagName}", url.PathEscape(tagName)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientDeleteAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return TagsClientDeleteAtScopeResponse{}, err + } + return TagsClientDeleteAtScopeResponse{}, nil +} + +// deleteAtScopeCreateRequest creates the DeleteAtScope request. +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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// DeleteValue - This operation allows deleting a value from the list of predefined values for an existing predefined tag +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientDeleteValueResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) { + err = runtime.NewResponseError(httpResp) + return TagsClientDeleteValueResponse{}, err + } + return TagsClientDeleteValueResponse{}, nil +} + +// deleteValueCreateRequest creates the DeleteValue request. +func (client *TagsClient) deleteValueCreateRequest(ctx context.Context, tagName string, tagValue string, options *TagsClientDeleteValueOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}" + if tagName == "" { + return nil, errors.New("parameter tagName cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{tagName}", url.PathEscape(tagName)) + if tagValue == "" { + return nil, errors.New("parameter tagValue cannot be empty") + } + urlPath = strings.ReplaceAll(urlPath, "{tagValue}", url.PathEscape(tagValue)) + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientGetAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return TagsClientGetAtScopeResponse{}, err + } + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// getAtScopeHandleResponse handles the GetAtScope response. +func (client *TagsClient) getAtScopeHandleResponse(resp *http.Response) (TagsClientGetAtScopeResponse, error) { + result := TagsClientGetAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TagsResource); err != nil { + return TagsClientGetAtScopeResponse{}, err + } + return result, nil +} + +// 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. +// +// Generated from API version 2021-04-01 +// - 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) { + 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 + } + return client.listHandleResponse(resp) + }, + Tracer: client.internal.Tracer(), + }) +} + +// listCreateRequest creates the List request. +func (client *TagsClient) listCreateRequest(ctx context.Context, options *TagsClientListOptions) (*policy.Request, error) { + urlPath := "/subscriptions/{subscriptionId}/tagNames" + if client.subscriptionID == "" { + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, nil +} + +// listHandleResponse handles the List response. +func (client *TagsClient) listHandleResponse(resp *http.Response) (TagsClientListResponse, error) { + result := TagsClientListResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TagsListResult); err != nil { + return TagsClientListResponse{}, err + } + return result, nil +} + +// UpdateAtScope - This operation allows replacing, merging or selectively deleting tags on the specified resource or subscription. +// The specified entity can have a maximum of 50 tags at the end of the operation. The +// 'replace' option replaces the entire set of existing tags with a new set. The 'merge' option allows adding tags with new +// 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. +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 + } + httpResp, err := client.internal.Pipeline().Do(req) + if err != nil { + return TagsClientUpdateAtScopeResponse{}, err + } + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return TagsClientUpdateAtScopeResponse{}, err + } + 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.internal.Endpoint(), urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2021-04-01") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + if err := runtime.MarshalAsJSON(req, parameters); err != nil { + return nil, err + } + return req, nil +} + +// updateAtScopeHandleResponse handles the UpdateAtScope response. +func (client *TagsClient) updateAtScopeHandleResponse(resp *http.Response) (TagsClientUpdateAtScopeResponse, error) { + result := TagsClientUpdateAtScopeResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.TagsResource); err != nil { + return TagsClientUpdateAtScopeResponse{}, err + } + return result, nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/time_rfc3339.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/time_rfc3339.go new file mode 100644 index 000000000..5026e349b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/time_rfc3339.go @@ -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 ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" + "regexp" + "strings" + "time" +) + +// 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+)*"*$`) + +const ( + utcDateTimeJSON = `"2006-01-02T15:04:05.999999999"` + utcDateTime = "2006-01-02T15:04:05.999999999" + dateTimeJSON = `"` + time.RFC3339Nano + `"` +) + +type dateTimeRFC3339 time.Time + +func (t dateTimeRFC3339) MarshalJSON() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalJSON() +} + +func (t dateTimeRFC3339) MarshalText() ([]byte, error) { + tt := time.Time(t) + return tt.MarshalText() +} + +func (t *dateTimeRFC3339) UnmarshalJSON(data []byte) error { + layout := utcDateTimeJSON + if tzOffsetRegex.Match(data) { + layout = dateTimeJSON + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) UnmarshalText(data []byte) error { + layout := utcDateTime + if tzOffsetRegex.Match(data) { + layout = time.RFC3339Nano + } + return t.Parse(layout, string(data)) +} + +func (t *dateTimeRFC3339) Parse(layout, value string) error { + p, err := time.Parse(layout, strings.ToUpper(value)) + *t = dateTimeRFC3339(p) + return err +} + +func populateDateTimeRFC3339(m map[string]any, k string, t *time.Time) { + if t == nil { + return + } else if azcore.IsNullValue(t) { + m[k] = nil + return + } else if reflect.ValueOf(t).IsNil() { + return + } + m[k] = (*dateTimeRFC3339)(t) +} + +func unpopulateDateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error { + if data == nil || strings.EqualFold(string(data), "null") { + return nil + } + var aux dateTimeRFC3339 + if err := json.Unmarshal(data, &aux); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + *t = (*time.Time)(&aux) + return nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/LICENSE b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/LICENSE new file mode 100644 index 000000000..3d8b93bc7 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache/cache.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache/cache.go new file mode 100644 index 000000000..19210883b --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache/cache.go @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package cache allows third parties to implement external storage for caching token data +for distributed systems or multiple local applications access. + +The data stored and extracted will represent the entire cache. Therefore it is recommended +one msal instance per user. This data is considered opaque and there are no guarantees to +implementers on the format being passed. +*/ +package cache + +import "context" + +// Marshaler marshals data from an internal cache to bytes that can be stored. +type Marshaler interface { + Marshal() ([]byte, error) +} + +// Unmarshaler unmarshals data from a storage medium into the internal cache, overwriting it. +type Unmarshaler interface { + Unmarshal([]byte) error +} + +// Serializer can serialize the cache to binary or from binary into the cache. +type Serializer interface { + Marshaler + Unmarshaler +} + +// ExportHints are suggestions for storing data. +type ExportHints struct { + // PartitionKey is a suggested key for partitioning the cache + PartitionKey string +} + +// ReplaceHints are suggestions for loading data. +type ReplaceHints struct { + // PartitionKey is a suggested key for partitioning the cache + PartitionKey string +} + +// ExportReplace exports and replaces in-memory cache data. It doesn't support nil Context or +// define the outcome of passing one. A Context without a timeout must receive a default timeout +// specified by the implementor. Retries must be implemented inside the implementation. +type ExportReplace interface { + // Replace replaces the cache with what is in external storage. Implementors should honor + // Context cancellations and return context.Canceled or context.DeadlineExceeded in those cases. + Replace(ctx context.Context, cache Unmarshaler, hints ReplaceHints) error + // Export writes the binary representation of the cache (cache.Marshal()) to external storage. + // This is considered opaque. Context cancellations should be honored as in Replace. + Export(ctx context.Context, cache Marshaler, hints ExportHints) error +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential/confidential.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential/confidential.go new file mode 100644 index 000000000..549d68ab9 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential/confidential.go @@ -0,0 +1,783 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package confidential provides a client for authentication of "confidential" applications. +A "confidential" application is defined as an app that run on servers. They are considered +difficult to access and for that reason capable of keeping an application secret. +Confidential clients can hold configuration-time secrets. +*/ +package confidential + +import ( + "context" + "crypto" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "fmt" + "os" + "strings" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops" + "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/options" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared" +) + +/* +Design note: + +confidential.Client uses base.Client as an embedded type. base.Client statically assigns its attributes +during creation. As it doesn't have any pointers in it, anything borrowed from it, such as +Base.AuthParams is a copy that is free to be manipulated here. + +Duplicate Calls shared between public.Client and this package: +There is some duplicate call options provided here that are the same as in public.Client . This +is a design choices. Go proverb(https://www.youtube.com/watch?v=PAAkCSZUG1c&t=9m28s): +"a little copying is better than a little dependency". Yes, we could have another package with +shared options (fail). That divides like 2 options from all others which makes the user look +through more docs. We can have all clients in one package, but I think separate packages +here makes for better naming (public.Client vs client.PublicClient). So I chose a little +duplication. + +.Net People, Take note on X509: +This uses x509.Certificates and private keys. x509 does not store private keys. .Net +has a x509.Certificate2 abstraction that has private keys, but that just a strange invention. +As such I've put a PEM decoder into here. +*/ + +// TODO(msal): This should have example code for each method on client using Go's example doc framework. +// base usage details should be include in the package documentation. + +// AuthResult contains the results of one token acquisition operation. +// For details see https://aka.ms/msal-net-authenticationresult +type AuthResult = base.AuthResult + +type AuthenticationScheme = authority.AuthenticationScheme + +type Account = shared.Account + +type TokenSource = base.TokenSource + +const ( + TokenSourceIdentityProvider = base.TokenSourceIdentityProvider + TokenSourceCache = base.TokenSourceCache +) + +// CertFromPEM converts a PEM file (.pem or .key) for use with [NewCredFromCert]. The file +// must contain the public certificate and the private key. If a PEM block is encrypted and +// password is not an empty string, it attempts to decrypt the PEM blocks using the password. +// Multiple certs are due to certificate chaining for use cases like TLS that sign from root to leaf. +func CertFromPEM(pemData []byte, password string) ([]*x509.Certificate, crypto.PrivateKey, error) { + var certs []*x509.Certificate + var priv crypto.PrivateKey + for { + block, rest := pem.Decode(pemData) + if block == nil { + break + } + + //nolint:staticcheck // x509.IsEncryptedPEMBlock and x509.DecryptPEMBlock are deprecated. They are used here only to support a usecase. + if x509.IsEncryptedPEMBlock(block) { + b, err := x509.DecryptPEMBlock(block, []byte(password)) + if err != nil { + return nil, nil, fmt.Errorf("could not decrypt encrypted PEM block: %v", err) + } + block, _ = pem.Decode(b) + if block == nil { + return nil, nil, fmt.Errorf("encounter encrypted PEM block that did not decode") + } + } + + switch block.Type { + case "CERTIFICATE": + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, nil, fmt.Errorf("block labelled 'CERTIFICATE' could not be parsed by x509: %v", err) + } + certs = append(certs, cert) + case "PRIVATE KEY": + if priv != nil { + return nil, nil, errors.New("found multiple private key blocks") + } + + var err error + priv, err = x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, nil, fmt.Errorf("could not decode private key: %v", err) + } + case "RSA PRIVATE KEY": + if priv != nil { + return nil, nil, errors.New("found multiple private key blocks") + } + var err error + priv, err = x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, nil, fmt.Errorf("could not decode private key: %v", err) + } + } + pemData = rest + } + + if len(certs) == 0 { + return nil, nil, fmt.Errorf("no certificates found") + } + + if priv == nil { + return nil, nil, fmt.Errorf("no private key found") + } + + return certs, priv, nil +} + +// AssertionRequestOptions has required information for client assertion claims +type AssertionRequestOptions = exported.AssertionRequestOptions + +// Credential represents the credential used in confidential client flows. +type Credential struct { + secret string + + cert *x509.Certificate + key crypto.PrivateKey + x5c []string + + assertionCallback func(context.Context, AssertionRequestOptions) (string, error) + + tokenProvider func(context.Context, TokenProviderParameters) (TokenProviderResult, error) +} + +// toInternal returns the accesstokens.Credential that is used internally. The current structure of the +// code requires that client.go, requests.go and confidential.go share a credential type without +// having import recursion. That requires the type used between is in a shared package. Therefore +// we have this. +func (c Credential) toInternal() (*accesstokens.Credential, error) { + if c.secret != "" { + return &accesstokens.Credential{Secret: c.secret}, nil + } + if c.cert != nil { + if c.key == nil { + return nil, errors.New("missing private key for certificate") + } + return &accesstokens.Credential{Cert: c.cert, Key: c.key, X5c: c.x5c}, nil + } + if c.key != nil { + return nil, errors.New("missing certificate for private key") + } + if c.assertionCallback != nil { + return &accesstokens.Credential{AssertionCallback: c.assertionCallback}, nil + } + if c.tokenProvider != nil { + return &accesstokens.Credential{TokenProvider: c.tokenProvider}, nil + } + return nil, errors.New("invalid credential") +} + +// NewCredFromSecret creates a Credential from a secret. +func NewCredFromSecret(secret string) (Credential, error) { + if secret == "" { + return Credential{}, errors.New("secret can't be empty string") + } + return Credential{secret: secret}, nil +} + +// NewCredFromAssertionCallback creates a Credential that invokes a callback to get assertions +// authenticating the application. The callback must be thread safe. +func NewCredFromAssertionCallback(callback func(context.Context, AssertionRequestOptions) (string, error)) Credential { + return Credential{assertionCallback: callback} +} + +// NewCredFromCert creates a Credential from a certificate or chain of certificates and an RSA private key +// as returned by [CertFromPEM]. +func NewCredFromCert(certs []*x509.Certificate, key crypto.PrivateKey) (Credential, error) { + cred := Credential{key: key} + k, ok := key.(*rsa.PrivateKey) + if !ok { + return cred, errors.New("key must be an RSA key") + } + for _, cert := range certs { + if cert == nil { + // not returning an error here because certs may still contain a sufficient cert/key pair + continue + } + certKey, ok := cert.PublicKey.(*rsa.PublicKey) + if ok && k.E == certKey.E && k.N.Cmp(certKey.N) == 0 { + // We know this is the signing cert because its public key matches the given private key. + // This cert must be first in x5c. + cred.cert = cert + cred.x5c = append([]string{base64.StdEncoding.EncodeToString(cert.Raw)}, cred.x5c...) + } else { + cred.x5c = append(cred.x5c, base64.StdEncoding.EncodeToString(cert.Raw)) + } + } + if cred.cert == nil { + return cred, errors.New("key doesn't match any certificate") + } + return cred, nil +} + +// TokenProviderParameters is the authentication parameters passed to token providers +type TokenProviderParameters = exported.TokenProviderParameters + +// TokenProviderResult is the authentication result returned by custom token providers +type TokenProviderResult = exported.TokenProviderResult + +// NewCredFromTokenProvider creates a Credential from a function that provides access tokens. The function +// must be concurrency safe. This is intended only to allow the Azure SDK to cache MSI tokens. It isn't +// useful to applications in general because the token provider must implement all authentication logic. +func NewCredFromTokenProvider(provider func(context.Context, TokenProviderParameters) (TokenProviderResult, error)) Credential { + return Credential{tokenProvider: provider} +} + +// AutoDetectRegion instructs MSAL Go to auto detect region for Azure regional token service. +func AutoDetectRegion() string { + return "TryAutoDetect" +} + +// Client is a representation of authentication client for confidential applications as defined in the +// package doc. A new Client should be created PER SERVICE USER. +// For more information, visit https://docs.microsoft.com/azure/active-directory/develop/msal-client-applications +type Client struct { + base base.Client + cred *accesstokens.Credential +} + +// clientOptions are optional settings for New(). These options are set using various functions +// returning Option calls. +type clientOptions struct { + accessor cache.ExportReplace + authority, azureRegion string + capabilities []string + disableInstanceDiscovery, sendX5C bool + httpClient ops.HTTPClient +} + +// Option is an optional argument to New(). +type Option func(o *clientOptions) + +// WithCache provides an accessor that will read and write authentication data to an externally managed cache. +func WithCache(accessor cache.ExportReplace) Option { + return func(o *clientOptions) { + o.accessor = accessor + } +} + +// WithClientCapabilities allows configuring one or more client capabilities such as "CP1" +func WithClientCapabilities(capabilities []string) Option { + return func(o *clientOptions) { + // there's no danger of sharing the slice's underlying memory with the application because + // this slice is simply passed to base.WithClientCapabilities, which copies its data + o.capabilities = capabilities + } +} + +// WithHTTPClient allows for a custom HTTP client to be set. +func WithHTTPClient(httpClient ops.HTTPClient) Option { + return func(o *clientOptions) { + o.httpClient = httpClient + } +} + +// WithX5C specifies if x5c claim(public key of the certificate) should be sent to STS to enable Subject Name Issuer Authentication. +func WithX5C() Option { + return func(o *clientOptions) { + o.sendX5C = true + } +} + +// WithInstanceDiscovery set to false to disable authority validation (to support private cloud scenarios) +func WithInstanceDiscovery(enabled bool) Option { + return func(o *clientOptions) { + o.disableInstanceDiscovery = !enabled + } +} + +// WithAzureRegion sets the region(preferred) or Confidential.AutoDetectRegion() for auto detecting region. +// Region names as per https://azure.microsoft.com/en-ca/global-infrastructure/geographies/. +// See https://aka.ms/region-map for more details on region names. +// The region value should be short region name for the region where the service is deployed. +// For example "centralus" is short name for region Central US. +// Not all auth flows can use the regional token service. +// Service To Service (client credential flow) tokens can be obtained from the regional service. +// Requires configuration at the tenant level. +// Auto-detection works on a limited number of Azure artifacts (VMs, Azure functions). +// If auto-detection fails, the non-regional endpoint will be used. +// If an invalid region name is provided, the non-regional endpoint MIGHT be used or the token request MIGHT fail. +func WithAzureRegion(val string) Option { + return func(o *clientOptions) { + if val != "" { + o.azureRegion = val + } + } +} + +// New is the constructor for Client. authority is the URL of a token authority such as "https://login.microsoftonline.com/". +// If the Client will connect directly to AD FS, use "adfs" for the tenant. clientID is the application's client ID (also called its +// "application ID"). +func New(authority, clientID string, cred Credential, options ...Option) (Client, error) { + internalCred, err := cred.toInternal() + if err != nil { + return Client{}, err + } + autoEnabledRegion := os.Getenv("MSAL_FORCE_REGION") + opts := clientOptions{ + authority: authority, + // if the caller specified a token provider, it will handle all details of authentication, using Client only as a token cache + disableInstanceDiscovery: cred.tokenProvider != nil, + httpClient: shared.DefaultClient, + azureRegion: autoEnabledRegion, + } + for _, o := range options { + o(&opts) + } + if strings.EqualFold(opts.azureRegion, "DisableMsalForceRegion") { + opts.azureRegion = "" + } + + baseOpts := []base.Option{ + base.WithCacheAccessor(opts.accessor), + base.WithClientCapabilities(opts.capabilities), + base.WithInstanceDiscovery(!opts.disableInstanceDiscovery), + base.WithRegionDetection(opts.azureRegion), + base.WithX5C(opts.sendX5C), + } + base, err := base.New(clientID, opts.authority, oauth.New(opts.httpClient), baseOpts...) + if err != nil { + return Client{}, err + } + base.AuthParams.IsConfidentialClient = true + + return Client{base: base, cred: internalCred}, nil +} + +// authCodeURLOptions contains options for AuthCodeURL +type authCodeURLOptions struct { + claims, loginHint, tenantID, domainHint string +} + +// AuthCodeURLOption is implemented by options for AuthCodeURL +type AuthCodeURLOption interface { + authCodeURLOption() +} + +// AuthCodeURL creates a URL used to acquire an authorization code. Users need to call CreateAuthorizationCodeURLParameters and pass it in. +// +// Options: [WithClaims], [WithDomainHint], [WithLoginHint], [WithTenantID] +func (cca Client) AuthCodeURL(ctx context.Context, clientID, redirectURI string, scopes []string, opts ...AuthCodeURLOption) (string, error) { + o := authCodeURLOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return "", err + } + ap, err := cca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return "", err + } + ap.Claims = o.claims + ap.LoginHint = o.loginHint + ap.DomainHint = o.domainHint + return cca.base.AuthCodeURL(ctx, clientID, redirectURI, scopes, ap) +} + +// WithLoginHint pre-populates the login prompt with a username. +func WithLoginHint(username string) interface { + AuthCodeURLOption + options.CallOption +} { + return struct { + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *authCodeURLOptions: + t.loginHint = username + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// WithDomainHint adds the IdP domain as domain_hint query parameter in the auth url. +func WithDomainHint(domain string) interface { + AuthCodeURLOption + options.CallOption +} { + return struct { + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *authCodeURLOptions: + t.domainHint = domain + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// WithClaims sets additional claims to request for the token, such as those required by conditional access policies. +// Use this option when Azure AD returned a claims challenge for a prior request. The argument must be decoded. +// This option is valid for any token acquisition method. +func WithClaims(claims string) interface { + AcquireByAuthCodeOption + AcquireByCredentialOption + AcquireOnBehalfOfOption + AcquireByUsernamePasswordOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption +} { + return struct { + AcquireByAuthCodeOption + AcquireByCredentialOption + AcquireOnBehalfOfOption + AcquireByUsernamePasswordOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenByAuthCodeOptions: + t.claims = claims + case *acquireTokenByCredentialOptions: + t.claims = claims + case *acquireTokenOnBehalfOfOptions: + t.claims = claims + case *acquireTokenByUsernamePasswordOptions: + t.claims = claims + case *acquireTokenSilentOptions: + t.claims = claims + case *authCodeURLOptions: + t.claims = claims + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// 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 { + AcquireByAuthCodeOption + AcquireByCredentialOption + AcquireOnBehalfOfOption + AcquireByUsernamePasswordOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption +} { + return struct { + AcquireByAuthCodeOption + AcquireByCredentialOption + AcquireOnBehalfOfOption + AcquireByUsernamePasswordOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenByAuthCodeOptions: + t.tenantID = tenantID + case *acquireTokenByCredentialOptions: + t.tenantID = tenantID + case *acquireTokenOnBehalfOfOptions: + t.tenantID = tenantID + case *acquireTokenByUsernamePasswordOptions: + t.tenantID = tenantID + case *acquireTokenSilentOptions: + t.tenantID = tenantID + case *authCodeURLOptions: + t.tenantID = tenantID + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// acquireTokenSilentOptions are all the optional settings to an AcquireTokenSilent() call. +// These are set by using various AcquireTokenSilentOption functions. +type acquireTokenSilentOptions struct { + account Account + claims, tenantID string + authnScheme AuthenticationScheme +} + +// AcquireSilentOption is implemented by options for AcquireTokenSilent +type AcquireSilentOption interface { + acquireSilentOption() +} + +// WithSilentAccount uses the passed account during an AcquireTokenSilent() call. +func WithSilentAccount(account Account) interface { + AcquireSilentOption + options.CallOption +} { + return struct { + AcquireSilentOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenSilentOptions: + t.account = account + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// AcquireTokenSilent acquires a token from either the cache or using a refresh token. +// +// Options: [WithClaims], [WithSilentAccount], [WithTenantID] +func (cca Client) AcquireTokenSilent(ctx context.Context, scopes []string, opts ...AcquireSilentOption) (AuthResult, error) { + o := acquireTokenSilentOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + + if o.claims != "" { + return AuthResult{}, errors.New("call another AcquireToken method to request a new token having these claims") + } + + silentParameters := base.AcquireTokenSilentParameters{ + Scopes: scopes, + Account: o.account, + RequestType: accesstokens.ATConfidential, + Credential: cca.cred, + IsAppCache: o.account.IsZero(), + TenantID: o.tenantID, + AuthnScheme: o.authnScheme, + } + + return cca.base.AcquireTokenSilent(ctx, silentParameters) +} + +// acquireTokenByUsernamePasswordOptions contains optional configuration for AcquireTokenByUsernamePassword +type acquireTokenByUsernamePasswordOptions struct { + claims, tenantID string + authnScheme AuthenticationScheme +} + +// AcquireByUsernamePasswordOption is implemented by options for AcquireTokenByUsernamePassword +type AcquireByUsernamePasswordOption interface { + acquireByUsernamePasswordOption() +} + +// AcquireTokenByUsernamePassword acquires a security token from the authority, via Username/Password Authentication. +// NOTE: this flow is NOT recommended. +// +// Options: [WithClaims], [WithTenantID] +func (cca Client) AcquireTokenByUsernamePassword(ctx context.Context, scopes []string, username, password string, opts ...AcquireByUsernamePasswordOption) (AuthResult, error) { + o := acquireTokenByUsernamePasswordOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + authParams, err := cca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return AuthResult{}, err + } + authParams.Scopes = scopes + authParams.AuthorizationType = authority.ATUsernamePassword + authParams.Claims = o.claims + authParams.Username = username + authParams.Password = password + if o.authnScheme != nil { + authParams.AuthnScheme = o.authnScheme + } + + token, err := cca.base.Token.UsernamePassword(ctx, authParams) + if err != nil { + return AuthResult{}, err + } + return cca.base.AuthResultFromToken(ctx, authParams, token) +} + +// acquireTokenByAuthCodeOptions contains the optional parameters used to acquire an access token using the authorization code flow. +type acquireTokenByAuthCodeOptions struct { + challenge, claims, tenantID string +} + +// AcquireByAuthCodeOption is implemented by options for AcquireTokenByAuthCode +type AcquireByAuthCodeOption interface { + acquireByAuthCodeOption() +} + +// WithChallenge allows you to provide a challenge for the .AcquireTokenByAuthCode() call. +func WithChallenge(challenge string) interface { + AcquireByAuthCodeOption + options.CallOption +} { + return struct { + AcquireByAuthCodeOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenByAuthCodeOptions: + t.challenge = challenge + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// AcquireTokenByAuthCode is a request to acquire a security token from the authority, using an authorization code. +// The specified redirect URI must be the same URI that was used when the authorization code was requested. +// +// Options: [WithChallenge], [WithClaims], [WithTenantID] +func (cca Client) AcquireTokenByAuthCode(ctx context.Context, code string, redirectURI string, scopes []string, opts ...AcquireByAuthCodeOption) (AuthResult, error) { + o := acquireTokenByAuthCodeOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + + params := base.AcquireTokenAuthCodeParameters{ + Scopes: scopes, + Code: code, + Challenge: o.challenge, + Claims: o.claims, + AppType: accesstokens.ATConfidential, + Credential: cca.cred, // This setting differs from public.Client.AcquireTokenByAuthCode + RedirectURI: redirectURI, + TenantID: o.tenantID, + } + + return cca.base.AcquireTokenByAuthCode(ctx, params) +} + +// acquireTokenByCredentialOptions contains optional configuration for AcquireTokenByCredential +type acquireTokenByCredentialOptions struct { + claims, tenantID string + authnScheme AuthenticationScheme +} + +// AcquireByCredentialOption is implemented by options for AcquireTokenByCredential +type AcquireByCredentialOption interface { + acquireByCredOption() +} + +// AcquireTokenByCredential acquires a security token from the authority, using the client credentials grant. +// +// Options: [WithClaims], [WithTenantID] +func (cca Client) AcquireTokenByCredential(ctx context.Context, scopes []string, opts ...AcquireByCredentialOption) (AuthResult, error) { + o := acquireTokenByCredentialOptions{} + err := options.ApplyOptions(&o, opts) + if err != nil { + return AuthResult{}, err + } + authParams, err := cca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return AuthResult{}, err + } + 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 + } + return cca.base.AuthResultFromToken(ctx, authParams, token) +} + +// acquireTokenOnBehalfOfOptions contains optional configuration for AcquireTokenOnBehalfOf +type acquireTokenOnBehalfOfOptions struct { + claims, tenantID string +} + +// AcquireOnBehalfOfOption is implemented by options for AcquireTokenOnBehalfOf +type AcquireOnBehalfOfOption interface { + acquireOBOOption() +} + +// AcquireTokenOnBehalfOf acquires a security token for an app using middle tier apps access token. +// Refer https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow. +// +// Options: [WithClaims], [WithTenantID] +func (cca Client) AcquireTokenOnBehalfOf(ctx context.Context, userAssertion string, scopes []string, opts ...AcquireOnBehalfOfOption) (AuthResult, error) { + o := acquireTokenOnBehalfOfOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + params := base.AcquireTokenOnBehalfOfParameters{ + Scopes: scopes, + UserAssertion: userAssertion, + Claims: o.claims, + Credential: cca.cred, + TenantID: o.tenantID, + } + return cca.base.AcquireTokenOnBehalfOf(ctx, params) +} + +// Account gets the account in the token cache with the specified homeAccountID. +func (cca Client) Account(ctx context.Context, accountID string) (Account, error) { + return cca.base.Account(ctx, accountID) +} + +// RemoveAccount signs the account out and forgets account from token cache. +func (cca Client) RemoveAccount(ctx context.Context, account Account) error { + return cca.base.RemoveAccount(ctx, account) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors/error_design.md b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors/error_design.md new file mode 100644 index 000000000..7ef7862fe --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors/error_design.md @@ -0,0 +1,111 @@ +# MSAL Error Design + +Author: Abhidnya Patil(abhidnya.patil@microsoft.com) + +Contributors: + +- John Doak(jdoak@microsoft.com) +- Keegan Caruso(Keegan.Caruso@microsoft.com) +- Joel Hendrix(jhendrix@microsoft.com) + +## Background + +Errors in MSAL are intended for app developers to troubleshoot and not for displaying to end-users. + +### Go error handling vs other MSAL languages + +Most modern languages use exception based errors. Simply put, you "throw" an exception and it must be caught at some routine in the upper stack or it will eventually crash the program. + +Go doesn't use exceptions, instead it relies on multiple return values, one of which can be the builtin error interface type. It is up to the user to decide what to do. + +### Go custom error types + +Errors can be created in Go by simply using errors.New() or fmt.Errorf() to create an "error". + +Custom errors can be created in multiple ways. One of the more robust ways is simply to satisfy the error interface: + +```go +type MyCustomErr struct { + Msg string +} +func (m MyCustomErr) Error() string { // This implements "error" + return m.Msg +} +``` + +### MSAL Error Goals + +- Provide diagnostics to the user and for tickets that can be used to track down bugs or client misconfigurations +- Detect errors that are transitory and can be retried +- Allow the user to identify certain errors that the program can respond to, such a informing the user for the need to do an enrollment + +## Implementing Client Side Errors + +Client side errors indicate a misconfiguration or passing of bad arguments that is non-recoverable. Retrying isn't possible. + +These errors can simply be standard Go errors created by errors.New() or fmt.Errorf(). If down the line we need a custom error, we can introduce it, but for now the error messages just need to be clear on what the issue was. + +## Implementing Service Side Errors + +Service side errors occur when an external RPC responds either with an HTTP error code or returns a message that includes an error. + +These errors can be transitory (please slow down) or permanent (HTTP 404). To provide our diagnostic goals, we require the ability to differentiate these errors from other errors. + +The current implementation includes a specialized type that captures any error from the server: + +```go +// CallErr represents an HTTP call error. Has a Verbose() method that allows getting the +// http.Request and Response objects. Implements error. +type CallErr struct { + Req *http.Request + Resp *http.Response + Err error +} + +// Errors implements error.Error(). +func (e CallErr) Error() string { + return e.Err.Error() +} + +// Verbose prints a versbose error message with the request or response. +func (e CallErr) Verbose() string { + e.Resp.Request = nil // This brings in a bunch of TLS stuff we don't need + e.Resp.TLS = nil // Same + return fmt.Sprintf("%s:\nRequest:\n%s\nResponse:\n%s", e.Err, prettyConf.Sprint(e.Req), prettyConf.Sprint(e.Resp)) +} +``` + +A user will always receive the most concise error we provide. They can tell if it is a server side error using Go error package: + +```go +var callErr CallErr +if errors.As(err, &callErr) { + ... +} +``` + +We provide a Verbose() function that can retrieve the most verbose message from any error we provide: + +```go +fmt.Println(errors.Verbose(err)) +``` + +If further differentiation is required, we can add custom errors that use Go error wrapping on top of CallErr to achieve our diagnostic goals (such as detecting when to retry a call due to transient errors). + +CallErr is always thrown from the comm package (which handles all http requests) and looks similar to: + +```go +return nil, errors.CallErr{ + Req: req, + Resp: reply, + Err: fmt.Errorf("http call(%s)(%s) error: reply status code was %d:\n%s", req.URL.String(), req.Method, reply.StatusCode, ErrorResponse), //ErrorResponse is the json body extracted from the http response + } +``` + +## Future Decisions + +The ability to retry calls needs to have centralized responsibility. Either the user is doing it or the client is doing it. + +If the user should be responsible, our errors package will include a CanRetry() function that will inform the user if the error provided to them is retryable. This is based on the http error code and possibly the type of error that was returned. It would also include a sleep time if the server returned an amount of time to wait. + +Otherwise we will do this internally and retries will be left to us. diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors/errors.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors/errors.go new file mode 100644 index 000000000..b5cbb5721 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors/errors.go @@ -0,0 +1,98 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package errors + +import ( + "errors" + "fmt" + "io" + "net/http" + "reflect" + "strings" + + "github.com/kylelemons/godebug/pretty" +) + +var prettyConf = &pretty.Config{ + IncludeUnexported: false, + SkipZeroFields: true, + TrackCycles: true, + Formatter: map[reflect.Type]interface{}{ + reflect.TypeOf((*io.Reader)(nil)).Elem(): func(r io.Reader) string { + b, err := io.ReadAll(r) + if err != nil { + return "could not read io.Reader content" + } + return string(b) + }, + }, +} + +type verboser interface { + Verbose() string +} + +// Verbose prints the most verbose error that the error message has. +func Verbose(err error) string { + build := strings.Builder{} + for { + if err == nil { + break + } + if v, ok := err.(verboser); ok { + build.WriteString(v.Verbose()) + } else { + build.WriteString(err.Error()) + } + err = errors.Unwrap(err) + } + return build.String() +} + +// New is equivalent to errors.New(). +func New(text string) error { + return errors.New(text) +} + +// CallErr represents an HTTP call error. Has a Verbose() method that allows getting the +// http.Request and Response objects. Implements error. +type CallErr struct { + Req *http.Request + // Resp contains response body + Resp *http.Response + Err error +} + +type InvalidJsonErr struct { + Err error +} + +// Errors implements error.Error(). +func (e CallErr) Error() string { + return e.Err.Error() +} + +// Errors implements error.Error(). +func (e InvalidJsonErr) Error() string { + return e.Err.Error() +} + +// Verbose prints a versbose error message with the request or response. +func (e CallErr) Verbose() string { + e.Resp.Request = nil // This brings in a bunch of TLS crap we don't need + e.Resp.TLS = nil // Same + return fmt.Sprintf("%s:\nRequest:\n%s\nResponse:\n%s", e.Err, prettyConf.Sprint(e.Req), prettyConf.Sprint(e.Resp)) +} + +// Is reports whether any error in errors chain matches target. +func Is(err, target error) bool { + return errors.Is(err, target) +} + +// As finds the first error in errors chain that matches target, +// and if so, sets target to that error value and returns true. +// Otherwise, it returns false. +func As(err error, target interface{}) bool { + return errors.As(err, target) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/base.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/base.go new file mode 100644 index 000000000..61c1c4cec --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/base.go @@ -0,0 +1,534 @@ +// Package base contains a "Base" client that is used by the external public.Client and confidential.Client. +// Base holds shared attributes that must be available to both clients and methods that act as +// shared calls. +package base + +import ( + "context" + "fmt" + "net/url" + "reflect" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth" + "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" +) + +const ( + // AuthorityPublicCloud is the default AAD authority host + AuthorityPublicCloud = "https://login.microsoftonline.com/common" + scopeSeparator = " " +) + +// manager provides an internal cache. It is defined to allow faking the cache in tests. +// In production it's a *storage.Manager or *storage.PartitionedManager. +type manager interface { + cache.Serializer + Read(context.Context, authority.AuthParams) (storage.TokenResponse, error) + Write(authority.AuthParams, accesstokens.TokenResponse) (shared.Account, error) +} + +// accountManager is a manager that also caches accounts. In production it's a *storage.Manager. +type accountManager interface { + manager + AllAccounts() []shared.Account + Account(homeAccountID string) shared.Account + RemoveAccount(account shared.Account, clientID string) +} + +// AcquireTokenSilentParameters contains the parameters to acquire a token silently (from cache). +type AcquireTokenSilentParameters struct { + Scopes []string + Account shared.Account + RequestType accesstokens.AppType + Credential *accesstokens.Credential + IsAppCache bool + TenantID string + 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. +// To use PKCE, set the CodeChallengeParameter. +// Code challenges are used to secure authorization code grants; for more information, visit +// https://tools.ietf.org/html/rfc7636. +type AcquireTokenAuthCodeParameters struct { + Scopes []string + Code string + Challenge string + Claims string + RedirectURI string + AppType accesstokens.AppType + Credential *accesstokens.Credential + TenantID string +} + +type AcquireTokenOnBehalfOfParameters struct { + Scopes []string + Claims string + Credential *accesstokens.Credential + TenantID string + UserAssertion string +} + +// AuthResult contains the results of one token acquisition operation in PublicClientApplication +// or ConfidentialClientApplication. For details see https://aka.ms/msal-net-authenticationresult +type AuthResult struct { + Account shared.Account + IDToken accesstokens.IDToken + AccessToken string + ExpiresOn time.Time + GrantedScopes []string + DeclinedScopes []string + Metadata AuthResultMetadata +} + +// AuthResultMetadata which contains meta data for the AuthResult +type AuthResultMetadata struct { + RefreshOn time.Time + TokenSource TokenSource +} + +type TokenSource int + +// These are all the types of token flows. +const ( + TokenSourceIdentityProvider TokenSource = 0 + TokenSourceCache TokenSource = 1 +) + +// AuthResultFromStorage creates an AuthResult from a storage token response (which is generated from the cache). +func AuthResultFromStorage(storageTokenResponse storage.TokenResponse) (AuthResult, error) { + if err := storageTokenResponse.AccessToken.Validate(); err != nil { + return AuthResult{}, fmt.Errorf("problem with access token in StorageTokenResponse: %w", err) + } + account := storageTokenResponse.Account + accessToken := storageTokenResponse.AccessToken.Secret + grantedScopes := strings.Split(storageTokenResponse.AccessToken.Scopes, scopeSeparator) + + // Checking if there was an ID token in the cache; this will throw an error in the case of confidential client applications. + var idToken accesstokens.IDToken + if !storageTokenResponse.IDToken.IsZero() { + err := idToken.UnmarshalJSON([]byte(storageTokenResponse.IDToken.Secret)) + if err != nil { + return AuthResult{}, fmt.Errorf("problem decoding JWT token: %w", err) + } + } + return AuthResult{ + Account: account, + IDToken: idToken, + AccessToken: accessToken, + ExpiresOn: storageTokenResponse.AccessToken.ExpiresOn.T, + GrantedScopes: grantedScopes, + DeclinedScopes: nil, + Metadata: AuthResultMetadata{ + TokenSource: TokenSourceCache, + RefreshOn: storageTokenResponse.AccessToken.RefreshOn.T, + }, + }, nil +} + +// NewAuthResult creates an AuthResult. +func NewAuthResult(tokenResponse accesstokens.TokenResponse, account shared.Account) (AuthResult, error) { + if len(tokenResponse.DeclinedScopes) > 0 { + return AuthResult{}, fmt.Errorf("token response failed because declined scopes are present: %s", strings.Join(tokenResponse.DeclinedScopes, ",")) + } + return AuthResult{ + Account: account, + IDToken: tokenResponse.IDToken, + AccessToken: tokenResponse.AccessToken, + ExpiresOn: tokenResponse.ExpiresOn, + GrantedScopes: tokenResponse.GrantedScopes.Slice, + Metadata: AuthResultMetadata{ + TokenSource: TokenSourceIdentityProvider, + RefreshOn: tokenResponse.RefreshOn.T, + }, + }, nil +} + +// Client is a base client that provides access to common methods and primatives that +// can be used by multiple clients. +type Client struct { + Token *oauth.Client + manager accountManager // *storage.Manager or fakeManager in tests + // pmanager is a partitioned cache for OBO authentication. *storage.PartitionedManager or fakeManager in tests + pmanager manager + + AuthParams authority.AuthParams // DO NOT EVER MAKE THIS A POINTER! See "Note" in New(). + cacheAccessor cache.ExportReplace + cacheAccessorMu *sync.RWMutex + canRefresh map[string]*atomic.Value + canRefreshMu *sync.Mutex +} + +// Option is an optional argument to the New constructor. +type Option func(c *Client) error + +// WithCacheAccessor allows you to set some type of cache for storing authentication tokens. +func WithCacheAccessor(ca cache.ExportReplace) Option { + return func(c *Client) error { + if ca != nil { + c.cacheAccessor = ca + } + return nil + } +} + +// WithClientCapabilities allows configuring one or more client capabilities such as "CP1" +func WithClientCapabilities(capabilities []string) Option { + return func(c *Client) error { + var err error + if len(capabilities) > 0 { + cc, err := authority.NewClientCapabilities(capabilities) + if err == nil { + c.AuthParams.Capabilities = cc + } + } + return err + } +} + +// WithKnownAuthorityHosts specifies hosts Client shouldn't validate or request metadata for because they're known to the user +func WithKnownAuthorityHosts(hosts []string) Option { + return func(c *Client) error { + cp := make([]string, len(hosts)) + copy(cp, hosts) + c.AuthParams.KnownAuthorityHosts = cp + return nil + } +} + +// WithX5C specifies if x5c claim(public key of the certificate) should be sent to STS to enable Subject Name Issuer Authentication. +func WithX5C(sendX5C bool) Option { + return func(c *Client) error { + c.AuthParams.SendX5C = sendX5C + return nil + } +} + +func WithRegionDetection(region string) Option { + return func(c *Client) error { + c.AuthParams.AuthorityInfo.Region = region + return nil + } +} + +func WithInstanceDiscovery(instanceDiscoveryEnabled bool) Option { + return func(c *Client) error { + c.AuthParams.AuthorityInfo.ValidateAuthority = instanceDiscoveryEnabled + c.AuthParams.AuthorityInfo.InstanceDiscoveryDisabled = !instanceDiscoveryEnabled + return nil + } +} + +// New is the constructor for Base. +func New(clientID string, authorityURI string, token *oauth.Client, options ...Option) (Client, error) { + //By default, validateAuthority is set to true and instanceDiscoveryDisabled is set to false + authInfo, err := authority.NewInfoFromAuthorityURI(authorityURI, true, false) + if err != nil { + return Client{}, err + } + authParams := authority.NewAuthParams(clientID, authInfo) + client := Client{ // Note: Hey, don't even THINK about making Base into *Base. See "design notes" in public.go and confidential.go + Token: token, + AuthParams: authParams, + cacheAccessorMu: &sync.RWMutex{}, + manager: storage.New(token), + pmanager: storage.NewPartitionedManager(token), + canRefresh: make(map[string]*atomic.Value), + canRefreshMu: &sync.Mutex{}, + } + for _, o := range options { + if err = o(&client); err != nil { + break + } + } + return client, err + +} + +// AuthCodeURL creates a URL used to acquire an authorization code. +func (b Client) AuthCodeURL(ctx context.Context, clientID, redirectURI string, scopes []string, authParams authority.AuthParams) (string, error) { + endpoints, err := b.Token.ResolveEndpoints(ctx, authParams.AuthorityInfo, "") + if err != nil { + return "", err + } + + baseURL, err := url.Parse(endpoints.AuthorizationEndpoint) + if err != nil { + return "", err + } + + claims, err := authParams.MergeCapabilitiesAndClaims() + if err != nil { + return "", err + } + + v := url.Values{} + v.Add("client_id", clientID) + v.Add("response_type", "code") + v.Add("redirect_uri", redirectURI) + v.Add("scope", strings.Join(scopes, scopeSeparator)) + if authParams.State != "" { + v.Add("state", authParams.State) + } + if claims != "" { + v.Add("claims", claims) + } + if authParams.CodeChallenge != "" { + v.Add("code_challenge", authParams.CodeChallenge) + } + if authParams.CodeChallengeMethod != "" { + v.Add("code_challenge_method", authParams.CodeChallengeMethod) + } + if authParams.LoginHint != "" { + v.Add("login_hint", authParams.LoginHint) + } + if authParams.Prompt != "" { + v.Add("prompt", authParams.Prompt) + } + if authParams.DomainHint != "" { + v.Add("domain_hint", authParams.DomainHint) + } + // There were left over from an implementation that didn't use any of these. We may + // need to add them later, but as of now aren't needed. + /* + if p.ResponseMode != "" { + urlParams.Add("response_mode", p.ResponseMode) + } + */ + baseURL.RawQuery = v.Encode() + return baseURL.String(), nil +} + +func (b Client) AcquireTokenSilent(ctx context.Context, silent AcquireTokenSilentParameters) (AuthResult, error) { + ar := AuthResult{} + // when tenant == "", the caller didn't specify a tenant and WithTenant will choose the client's configured tenant + tenant := silent.TenantID + authParams, err := b.AuthParams.WithTenant(tenant) + if err != nil { + return ar, err + } + authParams.Scopes = silent.Scopes + authParams.HomeAccountID = silent.Account.HomeAccountID + 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 { + authParams.AuthorizationType = authority.ATRefreshToken + m = b.manager + } + if b.cacheAccessor != nil { + key := authParams.CacheKey(silent.IsAppCache) + b.cacheAccessorMu.RLock() + err = b.cacheAccessor.Replace(ctx, m, cache.ReplaceHints{PartitionKey: key}) + b.cacheAccessorMu.RUnlock() + } + if err != nil { + return ar, err + } + storageTokenResponse, err := m.Read(ctx, authParams) + if err != nil { + return ar, err + } + + // ignore cached access tokens when given claims + if silent.Claims == "" { + ar, err = AuthResultFromStorage(storageTokenResponse) + if err == nil { + if rt := storageTokenResponse.AccessToken.RefreshOn.T; !rt.IsZero() && Now().After(rt) { + b.canRefreshMu.Lock() + refreshValue, ok := b.canRefresh[tenant] + if !ok { + refreshValue = &atomic.Value{} + refreshValue.Store(false) + b.canRefresh[tenant] = refreshValue + } + b.canRefreshMu.Unlock() + if refreshValue.CompareAndSwap(false, true) { + defer refreshValue.Store(false) + // Added a check to see if the token is still same because there is a chance + // that the token is already refreshed by another thread. + // If the token is not same, we don't need to refresh it. + // Which means it refreshed. + if str, err := m.Read(ctx, authParams); err == nil && str.AccessToken.Secret == ar.AccessToken { + if tr, er := b.Token.Credential(ctx, authParams, silent.Credential); er == nil { + return b.AuthResultFromToken(ctx, authParams, tr) + } + } + } + } + ar.AccessToken, err = authParams.AuthnScheme.FormatAccessToken(ar.AccessToken) + return ar, err + } + } + + // redeem a cached refresh token, if available + if reflect.ValueOf(storageTokenResponse.RefreshToken).IsZero() { + return ar, errors.New("no token found") + } + var cc *accesstokens.Credential + if silent.RequestType == accesstokens.ATConfidential { + cc = silent.Credential + } + token, err := b.Token.Refresh(ctx, silent.RequestType, authParams, cc, storageTokenResponse.RefreshToken) + if err != nil { + return ar, err + } + return b.AuthResultFromToken(ctx, authParams, token) +} + +func (b Client) AcquireTokenByAuthCode(ctx context.Context, authCodeParams AcquireTokenAuthCodeParameters) (AuthResult, error) { + authParams, err := b.AuthParams.WithTenant(authCodeParams.TenantID) + if err != nil { + return AuthResult{}, err + } + authParams.Claims = authCodeParams.Claims + authParams.Scopes = authCodeParams.Scopes + authParams.Redirecturi = authCodeParams.RedirectURI + authParams.AuthorizationType = authority.ATAuthCode + + var cc *accesstokens.Credential + if authCodeParams.AppType == accesstokens.ATConfidential { + cc = authCodeParams.Credential + authParams.IsConfidentialClient = true + } + + req, err := accesstokens.NewCodeChallengeRequest(authParams, authCodeParams.AppType, cc, authCodeParams.Code, authCodeParams.Challenge) + if err != nil { + return AuthResult{}, err + } + + token, err := b.Token.AuthCode(ctx, req) + if err != nil { + return AuthResult{}, err + } + + return b.AuthResultFromToken(ctx, authParams, token) +} + +// AcquireTokenOnBehalfOf acquires a security token for an app using middle tier apps access token. +func (b Client) AcquireTokenOnBehalfOf(ctx context.Context, onBehalfOfParams AcquireTokenOnBehalfOfParameters) (AuthResult, error) { + var ar AuthResult + silentParameters := AcquireTokenSilentParameters{ + Scopes: onBehalfOfParams.Scopes, + RequestType: accesstokens.ATConfidential, + Credential: onBehalfOfParams.Credential, + UserAssertion: onBehalfOfParams.UserAssertion, + AuthorizationType: authority.ATOnBehalfOf, + TenantID: onBehalfOfParams.TenantID, + Claims: onBehalfOfParams.Claims, + } + ar, err := b.AcquireTokenSilent(ctx, silentParameters) + if err == nil { + return ar, err + } + authParams, err := b.AuthParams.WithTenant(onBehalfOfParams.TenantID) + if err != nil { + return AuthResult{}, err + } + authParams.AuthorizationType = authority.ATOnBehalfOf + authParams.Claims = onBehalfOfParams.Claims + authParams.Scopes = onBehalfOfParams.Scopes + authParams.UserAssertion = onBehalfOfParams.UserAssertion + token, err := b.Token.OnBehalfOf(ctx, authParams, onBehalfOfParams.Credential) + if err == nil { + ar, err = b.AuthResultFromToken(ctx, authParams, token) + } + return ar, err +} + +func (b Client) AuthResultFromToken(ctx context.Context, authParams authority.AuthParams, token accesstokens.TokenResponse) (AuthResult, error) { + var m manager = b.manager + if authParams.AuthorizationType == authority.ATOnBehalfOf { + m = b.pmanager + } + key := token.CacheKey(authParams) + if b.cacheAccessor != nil { + b.cacheAccessorMu.Lock() + defer b.cacheAccessorMu.Unlock() + err := b.cacheAccessor.Replace(ctx, m, cache.ReplaceHints{PartitionKey: key}) + if err != nil { + return AuthResult{}, err + } + } + account, err := m.Write(authParams, token) + if err != nil { + return AuthResult{}, err + } + ar, err := NewAuthResult(token, account) + 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 +} + +// This function wraps time.Now() and is used for refreshing the application +// was created to test the function against refreshin +var Now = time.Now + +func (b Client) AllAccounts(ctx context.Context) ([]shared.Account, error) { + if b.cacheAccessor != nil { + b.cacheAccessorMu.RLock() + defer b.cacheAccessorMu.RUnlock() + key := b.AuthParams.CacheKey(false) + err := b.cacheAccessor.Replace(ctx, b.manager, cache.ReplaceHints{PartitionKey: key}) + if err != nil { + return nil, err + } + } + return b.manager.AllAccounts(), nil +} + +func (b Client) Account(ctx context.Context, homeAccountID string) (shared.Account, error) { + if b.cacheAccessor != nil { + b.cacheAccessorMu.RLock() + defer b.cacheAccessorMu.RUnlock() + authParams := b.AuthParams // This is a copy, as we don't have a pointer receiver and .AuthParams is not a pointer. + authParams.AuthorizationType = authority.AccountByID + authParams.HomeAccountID = homeAccountID + key := b.AuthParams.CacheKey(false) + err := b.cacheAccessor.Replace(ctx, b.manager, cache.ReplaceHints{PartitionKey: key}) + if err != nil { + return shared.Account{}, err + } + } + return b.manager.Account(homeAccountID), nil +} + +// RemoveAccount removes all the ATs, RTs and IDTs from the cache associated with this account. +func (b Client) RemoveAccount(ctx context.Context, account shared.Account) error { + if b.cacheAccessor == nil { + b.manager.RemoveAccount(account, b.AuthParams.ClientID) + return nil + } + b.cacheAccessorMu.Lock() + defer b.cacheAccessorMu.Unlock() + key := b.AuthParams.CacheKey(false) + err := b.cacheAccessor.Replace(ctx, b.manager, cache.ReplaceHints{PartitionKey: key}) + if err != nil { + return err + } + b.manager.RemoveAccount(account, b.AuthParams.ClientID) + return b.cacheAccessor.Export(ctx, b.manager, cache.ExportHints{PartitionKey: key}) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/items.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/items.go new file mode 100644 index 000000000..7379e2233 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/items.go @@ -0,0 +1,216 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package storage + +import ( + "errors" + "fmt" + "reflect" + "strings" + "time" + + 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" +) + +// Contract is the JSON structure that is written to any storage medium when serializing +// the internal cache. This design is shared between MSAL versions in many languages. +// This cannot be changed without design that includes other SDKs. +type Contract struct { + AccessTokens map[string]AccessToken `json:"AccessToken,omitempty"` + RefreshTokens map[string]accesstokens.RefreshToken `json:"RefreshToken,omitempty"` + IDTokens map[string]IDToken `json:"IdToken,omitempty"` + Accounts map[string]shared.Account `json:"Account,omitempty"` + AppMetaData map[string]AppMetaData `json:"AppMetadata,omitempty"` + + AdditionalFields map[string]interface{} +} + +// Contract is the JSON structure that is written to any storage medium when serializing +// the internal cache. This design is shared between MSAL versions in many languages. +// This cannot be changed without design that includes other SDKs. +type InMemoryContract struct { + AccessTokensPartition map[string]map[string]AccessToken + RefreshTokensPartition map[string]map[string]accesstokens.RefreshToken + IDTokensPartition map[string]map[string]IDToken + AccountsPartition map[string]map[string]shared.Account + AppMetaData map[string]AppMetaData +} + +// NewContract is the constructor for Contract. +func NewInMemoryContract() *InMemoryContract { + return &InMemoryContract{ + AccessTokensPartition: map[string]map[string]AccessToken{}, + RefreshTokensPartition: map[string]map[string]accesstokens.RefreshToken{}, + IDTokensPartition: map[string]map[string]IDToken{}, + AccountsPartition: map[string]map[string]shared.Account{}, + AppMetaData: map[string]AppMetaData{}, + } +} + +// NewContract is the constructor for Contract. +func NewContract() *Contract { + return &Contract{ + AccessTokens: map[string]AccessToken{}, + RefreshTokens: map[string]accesstokens.RefreshToken{}, + IDTokens: map[string]IDToken{}, + Accounts: map[string]shared.Account{}, + AppMetaData: map[string]AppMetaData{}, + AdditionalFields: map[string]interface{}{}, + } +} + +// AccessToken is the JSON representation of a MSAL access token for encoding to storage. +type AccessToken struct { + HomeAccountID string `json:"home_account_id,omitempty"` + Environment string `json:"environment,omitempty"` + Realm string `json:"realm,omitempty"` + CredentialType string `json:"credential_type,omitempty"` + ClientID string `json:"client_id,omitempty"` + Secret string `json:"secret,omitempty"` + Scopes string `json:"target,omitempty"` + RefreshOn internalTime.Unix `json:"refresh_on,omitempty"` + ExpiresOn internalTime.Unix `json:"expires_on,omitempty"` + 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, refreshOn, expiresOn, extendedExpiresOn time.Time, scopes, token, tokenType, authnSchemeKeyID string) AccessToken { + return AccessToken{ + HomeAccountID: homeID, + Environment: env, + Realm: realm, + CredentialType: "AccessToken", + ClientID: clientID, + Secret: token, + Scopes: scopes, + CachedAt: internalTime.Unix{T: cachedAt.UTC()}, + RefreshOn: internalTime.Unix{T: refreshOn.UTC()}, + ExpiresOn: internalTime.Unix{T: expiresOn.UTC()}, + ExtendedExpiresOn: internalTime.Unix{T: extendedExpiresOn.UTC()}, + TokenType: tokenType, + AuthnSchemeKeyID: authnSchemeKeyID, + } +} + +// Key outputs the key that can be used to uniquely look up this entry in a map. +func (a AccessToken) Key() string { + ks := []string{a.HomeAccountID, a.Environment, a.CredentialType, a.ClientID, a.Realm, a.Scopes} + key := strings.Join( + ks, + 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) +} + +// FakeValidate enables tests to fake access token validation +var FakeValidate func(AccessToken) error + +// Validate validates that this AccessToken can be used. +func (a AccessToken) Validate() error { + if FakeValidate != nil { + return FakeValidate(a) + } + if a.CachedAt.T.After(time.Now()) { + return errors.New("access token isn't valid, it was cached at a future time") + } + if a.ExpiresOn.T.Before(time.Now().Add(5 * time.Minute)) { + return fmt.Errorf("access token is expired") + } + if a.CachedAt.T.IsZero() { + return fmt.Errorf("access token does not have CachedAt set") + } + return nil +} + +// IDToken is the JSON representation of an MSAL id token for encoding to storage. +type IDToken struct { + HomeAccountID string `json:"home_account_id,omitempty"` + Environment string `json:"environment,omitempty"` + Realm string `json:"realm,omitempty"` + CredentialType string `json:"credential_type,omitempty"` + ClientID string `json:"client_id,omitempty"` + Secret string `json:"secret,omitempty"` + UserAssertionHash string `json:"user_assertion_hash,omitempty"` + AdditionalFields map[string]interface{} +} + +// IsZero determines if IDToken is the zero value. +func (i IDToken) IsZero() bool { + v := reflect.ValueOf(i) + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + if !field.IsZero() { + switch field.Kind() { + case reflect.Map, reflect.Slice: + if field.Len() == 0 { + continue + } + } + return false + } + } + return true +} + +// NewIDToken is the constructor for IDToken. +func NewIDToken(homeID, env, realm, clientID, idToken string) IDToken { + return IDToken{ + HomeAccountID: homeID, + Environment: env, + Realm: realm, + CredentialType: "IDToken", + ClientID: clientID, + Secret: idToken, + } +} + +// Key outputs the key that can be used to uniquely look up this entry in a map. +func (id IDToken) Key() string { + key := strings.Join( + []string{id.HomeAccountID, id.Environment, id.CredentialType, id.ClientID, id.Realm}, + shared.CacheKeySeparator, + ) + return strings.ToLower(key) +} + +// AppMetaData is the JSON representation of application metadata for encoding to storage. +type AppMetaData struct { + FamilyID string `json:"family_id,omitempty"` + ClientID string `json:"client_id,omitempty"` + Environment string `json:"environment,omitempty"` + + AdditionalFields map[string]interface{} +} + +// NewAppMetaData is the constructor for AppMetaData. +func NewAppMetaData(familyID, clientID, environment string) AppMetaData { + return AppMetaData{ + FamilyID: familyID, + ClientID: clientID, + Environment: environment, + } +} + +// Key outputs the key that can be used to uniquely look up this entry in a map. +func (a AppMetaData) Key() string { + key := strings.Join( + []string{"AppMetaData", a.Environment, a.ClientID}, + shared.CacheKeySeparator, + ) + return strings.ToLower(key) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/partitioned_storage.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/partitioned_storage.go new file mode 100644 index 000000000..ff07d4b5a --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/partitioned_storage.go @@ -0,0 +1,443 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package storage + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + "time" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth" + "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" +) + +// PartitionedManager is a partitioned in-memory cache of access tokens, accounts and meta data. +type PartitionedManager struct { + contract *InMemoryContract + contractMu sync.RWMutex + requests aadInstanceDiscoveryer // *oauth.Token + + aadCacheMu sync.RWMutex + aadCache map[string]authority.InstanceDiscoveryMetadata +} + +// NewPartitionedManager is the constructor for PartitionedManager. +func NewPartitionedManager(requests *oauth.Client) *PartitionedManager { + m := &PartitionedManager{requests: requests, aadCache: make(map[string]authority.InstanceDiscoveryMetadata)} + m.contract = NewInMemoryContract() + return m +} + +// Read reads a storage token from the cache if it exists. +func (m *PartitionedManager) Read(ctx context.Context, authParameters authority.AuthParams) (TokenResponse, error) { + tr := TokenResponse{} + 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} + if !authParameters.AuthorityInfo.InstanceDiscoveryDisabled { + metadata, err := m.getMetadataEntry(ctx, authParameters.AuthorityInfo) + if err != nil { + return TokenResponse{}, err + } + aliases = metadata.Aliases + } + + userAssertionHash := authParameters.AssertionHash() + partitionKeyFromRequest := userAssertionHash + + // 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, tokenType, authnSchemeKeyID) + if err == nil { + tr.AccessToken = accessToken + } + idToken, err := m.readIDToken(aliases, realm, clientID, userAssertionHash, getPartitionKeyIDTokenRead(accessToken)) + if err == nil { + tr.IDToken = idToken + } + + if appMetadata, err := m.readAppMetaData(aliases, clientID); err == nil { + // we need the family ID to identify the correct refresh token, if any + familyID := appMetadata.FamilyID + refreshToken, err := m.readRefreshToken(aliases, familyID, clientID, userAssertionHash, partitionKeyFromRequest) + if err == nil { + tr.RefreshToken = refreshToken + } + } + + account, err := m.readAccount(aliases, realm, userAssertionHash, idToken.HomeAccountID) + if err == nil { + tr.Account = account + } + return tr, nil +} + +// Write writes a token response to the cache and returns the account information the token is stored with. +func (m *PartitionedManager) Write(authParameters authority.AuthParams, tokenResponse accesstokens.TokenResponse) (shared.Account, error) { + authParameters.HomeAccountID = tokenResponse.HomeAccountID() + homeAccountID := authParameters.HomeAccountID + environment := authParameters.AuthorityInfo.Host + realm := authParameters.AuthorityInfo.Tenant + clientID := authParameters.ClientID + 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 { + refreshToken := accesstokens.NewRefreshToken(homeAccountID, environment, clientID, tokenResponse.RefreshToken, tokenResponse.FamilyID) + if authParameters.AuthorizationType == authority.ATOnBehalfOf { + refreshToken.UserAssertionHash = userAssertionHash + } + if err := m.writeRefreshToken(refreshToken, getPartitionKeyRefreshToken(refreshToken)); err != nil { + return account, err + } + } + + if len(tokenResponse.AccessToken) > 0 { + accessToken := NewAccessToken( + homeAccountID, + environment, + realm, + clientID, + cachedAt, + tokenResponse.RefreshOn.T, + tokenResponse.ExpiresOn, + tokenResponse.ExtExpiresOn.T, + target, + tokenResponse.AccessToken, + tokenResponse.TokenType, + authnSchemeKeyID, + ) + if authParameters.AuthorizationType == authority.ATOnBehalfOf { + accessToken.UserAssertionHash = userAssertionHash // get Hash method on this + } + + // Since we have a valid access token, cache it before moving on. + if err := accessToken.Validate(); err == nil { + if err := m.writeAccessToken(accessToken, getPartitionKeyAccessToken(accessToken)); err != nil { + return account, err + } + } else { + return shared.Account{}, err + } + } + + idTokenJwt := tokenResponse.IDToken + if !idTokenJwt.IsZero() { + idToken := NewIDToken(homeAccountID, environment, realm, clientID, idTokenJwt.RawToken) + if authParameters.AuthorizationType == authority.ATOnBehalfOf { + idToken.UserAssertionHash = userAssertionHash + } + if err := m.writeIDToken(idToken, getPartitionKeyIDToken(idToken)); err != nil { + return shared.Account{}, err + } + + localAccountID := idTokenJwt.LocalAccountID() + authorityType := authParameters.AuthorityInfo.AuthorityType + + preferredUsername := idTokenJwt.UPN + if idTokenJwt.PreferredUsername != "" { + preferredUsername = idTokenJwt.PreferredUsername + } + + account = shared.NewAccount( + homeAccountID, + environment, + realm, + localAccountID, + authorityType, + preferredUsername, + ) + if authParameters.AuthorizationType == authority.ATOnBehalfOf { + account.UserAssertionHash = userAssertionHash + } + if err := m.writeAccount(account, getPartitionKeyAccount(account)); err != nil { + return shared.Account{}, err + } + } + + AppMetaData := NewAppMetaData(tokenResponse.FamilyID, clientID, environment) + + if err := m.writeAppMetaData(AppMetaData); err != nil { + return shared.Account{}, err + } + return account, nil +} + +func (m *PartitionedManager) getMetadataEntry(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryMetadata, error) { + md, err := m.aadMetadataFromCache(ctx, authorityInfo) + if err != nil { + // not in the cache, retrieve it + md, err = m.aadMetadata(ctx, authorityInfo) + } + return md, err +} + +func (m *PartitionedManager) aadMetadataFromCache(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryMetadata, error) { + m.aadCacheMu.RLock() + defer m.aadCacheMu.RUnlock() + metadata, ok := m.aadCache[authorityInfo.Host] + if ok { + return metadata, nil + } + return metadata, errors.New("not found") +} + +func (m *PartitionedManager) aadMetadata(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryMetadata, error) { + discoveryResponse, err := m.requests.AADInstanceDiscovery(ctx, authorityInfo) + if err != nil { + return authority.InstanceDiscoveryMetadata{}, err + } + + m.aadCacheMu.Lock() + defer m.aadCacheMu.Unlock() + + for _, metadataEntry := range discoveryResponse.Metadata { + for _, aliasedAuthority := range metadataEntry.Aliases { + m.aadCache[aliasedAuthority] = metadataEntry + } + } + if _, ok := m.aadCache[authorityInfo.Host]; !ok { + m.aadCache[authorityInfo.Host] = authority.InstanceDiscoveryMetadata{ + PreferredNetwork: authorityInfo.Host, + PreferredCache: authorityInfo.Host, + } + } + return m.aadCache[authorityInfo.Host], nil +} + +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 { + // 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 accessTokens { + if at.Realm == realm && at.ClientID == clientID && at.UserAssertionHash == userAssertionHash { + if at.TokenType == tokenType && at.AuthnSchemeKeyID == authnSchemeKeyID { + if checkAlias(at.Environment, envAliases) { + if isMatchingScopes(scopes, at.Scopes) { + return at, nil + } + } + } + } + } + } + return AccessToken{}, fmt.Errorf("access token not found") +} + +func (m *PartitionedManager) writeAccessToken(accessToken AccessToken, partitionKey string) error { + m.contractMu.Lock() + defer m.contractMu.Unlock() + key := accessToken.Key() + if m.contract.AccessTokensPartition[partitionKey] == nil { + m.contract.AccessTokensPartition[partitionKey] = make(map[string]AccessToken) + } + m.contract.AccessTokensPartition[partitionKey][key] = accessToken + return nil +} + +func matchFamilyRefreshTokenObo(rt accesstokens.RefreshToken, userAssertionHash string, envAliases []string) bool { + return rt.UserAssertionHash == userAssertionHash && checkAlias(rt.Environment, envAliases) && rt.FamilyID != "" +} + +func matchClientIDRefreshTokenObo(rt accesstokens.RefreshToken, userAssertionHash string, envAliases []string, clientID string) bool { + return rt.UserAssertionHash == userAssertionHash && checkAlias(rt.Environment, envAliases) && rt.ClientID == clientID +} + +func (m *PartitionedManager) readRefreshToken(envAliases []string, familyID, clientID, userAssertionHash, partitionKey string) (accesstokens.RefreshToken, error) { + byFamily := func(rt accesstokens.RefreshToken) bool { + return matchFamilyRefreshTokenObo(rt, userAssertionHash, envAliases) + } + byClient := func(rt accesstokens.RefreshToken) bool { + return matchClientIDRefreshTokenObo(rt, userAssertionHash, envAliases, clientID) + } + + var matchers []func(rt accesstokens.RefreshToken) bool + if familyID == "" { + matchers = []func(rt accesstokens.RefreshToken) bool{ + byClient, byFamily, + } + } else { + matchers = []func(rt accesstokens.RefreshToken) bool{ + byFamily, byClient, + } + } + + // TODO(keegan): All the tests here pass, but Bogdan says this is + // more complicated. I'm opening an issue for this to have him + // review the tests and suggest tests that would break this so + // we can re-write against good tests. His comments as follow: + // The algorithm is a bit more complex than this, I assume there are some tests covering everything. I would keep the order as is. + // The algorithm is: + // If application is NOT part of the family, search by client_ID + // 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.RefreshTokensPartition[partitionKey] { + if matcher(rt) { + return rt, nil + } + } + } + + return accesstokens.RefreshToken{}, fmt.Errorf("refresh token not found") +} + +func (m *PartitionedManager) writeRefreshToken(refreshToken accesstokens.RefreshToken, partitionKey string) error { + m.contractMu.Lock() + defer m.contractMu.Unlock() + key := refreshToken.Key() + if m.contract.AccessTokensPartition[partitionKey] == nil { + m.contract.RefreshTokensPartition[partitionKey] = make(map[string]accesstokens.RefreshToken) + } + m.contract.RefreshTokensPartition[partitionKey][key] = refreshToken + return nil +} + +func (m *PartitionedManager) readIDToken(envAliases []string, realm, clientID, userAssertionHash, partitionKey string) (IDToken, error) { + m.contractMu.RLock() + defer m.contractMu.RUnlock() + for _, idt := range m.contract.IDTokensPartition[partitionKey] { + if idt.Realm == realm && idt.ClientID == clientID && idt.UserAssertionHash == userAssertionHash { + if checkAlias(idt.Environment, envAliases) { + return idt, nil + } + } + } + return IDToken{}, fmt.Errorf("token not found") +} + +func (m *PartitionedManager) writeIDToken(idToken IDToken, partitionKey string) error { + key := idToken.Key() + m.contractMu.Lock() + defer m.contractMu.Unlock() + if m.contract.IDTokensPartition[partitionKey] == nil { + m.contract.IDTokensPartition[partitionKey] = make(map[string]IDToken) + } + m.contract.IDTokensPartition[partitionKey][key] = idToken + return nil +} + +func (m *PartitionedManager) readAccount(envAliases []string, realm, UserAssertionHash, partitionKey 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. + // We can't change that. The other is because the keys are made using a specific "env", but here we are allowing + // 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.AccountsPartition[partitionKey] { + if checkAlias(acc.Environment, envAliases) && acc.UserAssertionHash == UserAssertionHash && acc.Realm == realm { + return acc, nil + } + } + return shared.Account{}, fmt.Errorf("account not found") +} + +func (m *PartitionedManager) writeAccount(account shared.Account, partitionKey string) error { + key := account.Key() + m.contractMu.Lock() + defer m.contractMu.Unlock() + if m.contract.AccountsPartition[partitionKey] == nil { + m.contract.AccountsPartition[partitionKey] = make(map[string]shared.Account) + } + m.contract.AccountsPartition[partitionKey][key] = account + return nil +} + +func (m *PartitionedManager) readAppMetaData(envAliases []string, clientID string) (AppMetaData, error) { + m.contractMu.RLock() + defer m.contractMu.RUnlock() + + for _, app := range m.contract.AppMetaData { + if checkAlias(app.Environment, envAliases) && app.ClientID == clientID { + return app, nil + } + } + return AppMetaData{}, fmt.Errorf("not found") +} + +func (m *PartitionedManager) writeAppMetaData(AppMetaData AppMetaData) error { + key := AppMetaData.Key() + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract.AppMetaData[key] = AppMetaData + return nil +} + +// update updates the internal cache object. This is for use in tests, other uses are not +// supported. +func (m *PartitionedManager) update(cache *InMemoryContract) { + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract = cache +} + +// Marshal implements cache.Marshaler. +func (m *PartitionedManager) Marshal() ([]byte, error) { + return json.Marshal(m.contract) +} + +// Unmarshal implements cache.Unmarshaler. +func (m *PartitionedManager) Unmarshal(b []byte) error { + m.contractMu.Lock() + defer m.contractMu.Unlock() + + contract := NewInMemoryContract() + + err := json.Unmarshal(b, contract) + if err != nil { + return err + } + + m.contract = contract + + return nil +} + +func getPartitionKeyAccessToken(item AccessToken) string { + if item.UserAssertionHash != "" { + return item.UserAssertionHash + } + return item.HomeAccountID +} + +func getPartitionKeyRefreshToken(item accesstokens.RefreshToken) string { + if item.UserAssertionHash != "" { + return item.UserAssertionHash + } + return item.HomeAccountID +} + +func getPartitionKeyIDToken(item IDToken) string { + return item.HomeAccountID +} + +func getPartitionKeyAccount(item shared.Account) string { + return item.HomeAccountID +} + +func getPartitionKeyIDTokenRead(item AccessToken) string { + return item.HomeAccountID +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/storage.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/storage.go new file mode 100644 index 000000000..84a234967 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage/storage.go @@ -0,0 +1,589 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package storage holds all cached token information for MSAL. This storage can be +// augmented with third-party extensions to provide persistent storage. In that case, +// reads and writes in upper packages will call Marshal() to take the entire in-memory +// representation and write it to storage and Unmarshal() to update the entire in-memory +// storage with what was in the persistent storage. The persistent storage can only be +// accessed in this way because multiple MSAL clients written in multiple languages can +// access the same storage and must adhere to the same method that was defined +// previously. +package storage + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + "time" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth" + "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" +) + +// aadInstanceDiscoveryer allows faking in tests. +// It is implemented in production by ops/authority.Client +type aadInstanceDiscoveryer interface { + AADInstanceDiscovery(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryResponse, error) +} + +// TokenResponse mimics a token response that was pulled from the cache. +type TokenResponse struct { + RefreshToken accesstokens.RefreshToken + IDToken IDToken // *Credential + AccessToken AccessToken + Account shared.Account +} + +// Manager is an in-memory cache of access tokens, accounts and meta data. This data is +// updated on read/write calls. Unmarshal() replaces all data stored here with whatever +// was given to it on each call. +type Manager struct { + contract *Contract + contractMu sync.RWMutex + requests aadInstanceDiscoveryer // *oauth.Token + + aadCacheMu sync.RWMutex + aadCache map[string]authority.InstanceDiscoveryMetadata +} + +// New is the constructor for Manager. +func New(requests *oauth.Client) *Manager { + m := &Manager{requests: requests, aadCache: make(map[string]authority.InstanceDiscoveryMetadata)} + m.contract = NewContract() + return m +} + +func checkAlias(alias string, aliases []string) bool { + for _, v := range aliases { + if alias == v { + return true + } + } + return false +} + +func isMatchingScopes(scopesOne []string, scopesTwo string) bool { + newScopesTwo := strings.Split(scopesTwo, scopeSeparator) + scopeCounter := 0 + for _, scope := range scopesOne { + for _, otherScope := range newScopesTwo { + if strings.EqualFold(scope, otherScope) { + scopeCounter++ + continue + } + } + } + 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{} + homeAccountID := authParameters.HomeAccountID + 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} + if !authParameters.AuthorityInfo.InstanceDiscoveryDisabled { + metadata, err := m.getMetadataEntry(ctx, authParameters.AuthorityInfo) + if err != nil { + return TokenResponse{}, err + } + aliases = metadata.Aliases + } + + accessToken := m.readAccessToken(homeAccountID, aliases, realm, clientID, scopes, tokenType, authnSchemeKeyID) + tr.AccessToken = accessToken + + if homeAccountID == "" { + // caller didn't specify a user, so there's no reason to search for an ID or refresh token + return tr, nil + } + // 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. + idToken, err := m.readIDToken(homeAccountID, aliases, realm, clientID) + if err == nil { + tr.IDToken = idToken + } + + if appMetadata, err := m.readAppMetaData(aliases, clientID); err == nil { + // we need the family ID to identify the correct refresh token, if any + familyID := appMetadata.FamilyID + refreshToken, err := m.readRefreshToken(homeAccountID, aliases, familyID, clientID) + if err == nil { + tr.RefreshToken = refreshToken + } + } + + account, err := m.readAccount(homeAccountID, aliases, realm) + if err == nil { + tr.Account = account + } + return tr, nil +} + +const scopeSeparator = " " + +// Write writes a token response to the cache and returns the account information the token is stored with. +func (m *Manager) Write(authParameters authority.AuthParams, tokenResponse accesstokens.TokenResponse) (shared.Account, error) { + homeAccountID := tokenResponse.HomeAccountID() + environment := authParameters.AuthorityInfo.Host + realm := authParameters.AuthorityInfo.Tenant + clientID := authParameters.ClientID + + target := strings.Join(tokenResponse.GrantedScopes.Slice, scopeSeparator) + cachedAt := time.Now() + authnSchemeKeyID := authParameters.AuthnScheme.KeyID() + + var account shared.Account + + if len(tokenResponse.RefreshToken) > 0 { + refreshToken := accesstokens.NewRefreshToken(homeAccountID, environment, clientID, tokenResponse.RefreshToken, tokenResponse.FamilyID) + if err := m.writeRefreshToken(refreshToken); err != nil { + return account, err + } + } + + if len(tokenResponse.AccessToken) > 0 { + accessToken := NewAccessToken( + homeAccountID, + environment, + realm, + clientID, + cachedAt, + tokenResponse.RefreshOn.T, + tokenResponse.ExpiresOn, + tokenResponse.ExtExpiresOn.T, + target, + tokenResponse.AccessToken, + tokenResponse.TokenType, + authnSchemeKeyID, + ) + + // Since we have a valid access token, cache it before moving on. + if err := accessToken.Validate(); err == nil { + if err := m.writeAccessToken(accessToken); err != nil { + return account, err + } + } + } + + idTokenJwt := tokenResponse.IDToken + if !idTokenJwt.IsZero() { + idToken := NewIDToken(homeAccountID, environment, realm, clientID, idTokenJwt.RawToken) + if err := m.writeIDToken(idToken); err != nil { + return shared.Account{}, err + } + + localAccountID := idTokenJwt.LocalAccountID() + authorityType := authParameters.AuthorityInfo.AuthorityType + + preferredUsername := idTokenJwt.UPN + if idTokenJwt.PreferredUsername != "" { + preferredUsername = idTokenJwt.PreferredUsername + } + + account = shared.NewAccount( + homeAccountID, + environment, + realm, + localAccountID, + authorityType, + preferredUsername, + ) + if err := m.writeAccount(account); err != nil { + return shared.Account{}, err + } + } + + AppMetaData := NewAppMetaData(tokenResponse.FamilyID, clientID, environment) + + if err := m.writeAppMetaData(AppMetaData); err != nil { + return shared.Account{}, err + } + return account, nil +} + +func (m *Manager) getMetadataEntry(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryMetadata, error) { + md, err := m.aadMetadataFromCache(ctx, authorityInfo) + if err != nil { + // not in the cache, retrieve it + md, err = m.aadMetadata(ctx, authorityInfo) + } + return md, err +} + +func (m *Manager) aadMetadataFromCache(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryMetadata, error) { + m.aadCacheMu.RLock() + defer m.aadCacheMu.RUnlock() + metadata, ok := m.aadCache[authorityInfo.Host] + if ok { + return metadata, nil + } + return metadata, errors.New("not found") +} + +func (m *Manager) aadMetadata(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryMetadata, error) { + if m.requests == nil { + return authority.InstanceDiscoveryMetadata{}, fmt.Errorf("httpclient in oauth instance for fetching metadata is nil") + } + m.aadCacheMu.Lock() + defer m.aadCacheMu.Unlock() + discoveryResponse, err := m.requests.AADInstanceDiscovery(ctx, authorityInfo) + if err != nil { + return authority.InstanceDiscoveryMetadata{}, err + } + + for _, metadataEntry := range discoveryResponse.Metadata { + for _, aliasedAuthority := range metadataEntry.Aliases { + m.aadCache[aliasedAuthority] = metadataEntry + } + } + if _, ok := m.aadCache[authorityInfo.Host]; !ok { + m.aadCache[authorityInfo.Host] = authority.InstanceDiscoveryMetadata{ + PreferredNetwork: authorityInfo.Host, + PreferredCache: authorityInfo.Host, + } + } + return m.aadCache[authorityInfo.Host], nil +} + +func (m *Manager) readAccessToken(homeID string, envAliases []string, realm, clientID string, scopes []string, tokenType, authnSchemeKeyID string) AccessToken { + m.contractMu.RLock() + // 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 k, at := range m.contract.AccessTokens { + if at.HomeAccountID == homeID && at.Realm == realm && at.ClientID == clientID { + 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{} +} + +func (m *Manager) writeAccessToken(accessToken AccessToken) error { + m.contractMu.Lock() + defer m.contractMu.Unlock() + key := accessToken.Key() + m.contract.AccessTokens[key] = accessToken + return nil +} + +func (m *Manager) readRefreshToken(homeID string, envAliases []string, familyID, clientID string) (accesstokens.RefreshToken, error) { + byFamily := func(rt accesstokens.RefreshToken) bool { + return matchFamilyRefreshToken(rt, homeID, envAliases) + } + byClient := func(rt accesstokens.RefreshToken) bool { + return matchClientIDRefreshToken(rt, homeID, envAliases, clientID) + } + + var matchers []func(rt accesstokens.RefreshToken) bool + if familyID == "" { + matchers = []func(rt accesstokens.RefreshToken) bool{ + byClient, byFamily, + } + } else { + matchers = []func(rt accesstokens.RefreshToken) bool{ + byFamily, byClient, + } + } + + // TODO(keegan): All the tests here pass, but Bogdan says this is + // more complicated. I'm opening an issue for this to have him + // review the tests and suggest tests that would break this so + // we can re-write against good tests. His comments as follow: + // The algorithm is a bit more complex than this, I assume there are some tests covering everything. I would keep the order as is. + // The algorithm is: + // If application is NOT part of the family, search by client_ID + // 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() + for _, matcher := range matchers { + 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") +} + +func matchFamilyRefreshToken(rt accesstokens.RefreshToken, homeID string, envAliases []string) bool { + return rt.HomeAccountID == homeID && checkAlias(rt.Environment, envAliases) && rt.FamilyID != "" +} + +func matchClientIDRefreshToken(rt accesstokens.RefreshToken, homeID string, envAliases []string, clientID string) bool { + return rt.HomeAccountID == homeID && checkAlias(rt.Environment, envAliases) && rt.ClientID == clientID +} + +func (m *Manager) writeRefreshToken(refreshToken accesstokens.RefreshToken) error { + key := refreshToken.Key() + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract.RefreshTokens[key] = refreshToken + return nil +} + +func (m *Manager) readIDToken(homeID string, envAliases []string, realm, clientID string) (IDToken, error) { + m.contractMu.RLock() + 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") +} + +func (m *Manager) writeIDToken(idToken IDToken) error { + key := idToken.Key() + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract.IDTokens[key] = idToken + return nil +} + +func (m *Manager) AllAccounts() []shared.Account { + m.contractMu.RLock() + defer m.contractMu.RUnlock() + + var accounts []shared.Account + for _, v := range m.contract.Accounts { + accounts = append(accounts, v) + } + + return accounts +} + +func (m *Manager) Account(homeAccountID string) shared.Account { + m.contractMu.RLock() + defer m.contractMu.RUnlock() + + for _, v := range m.contract.Accounts { + if v.HomeAccountID == homeAccountID { + return v + } + } + + return shared.Account{} +} + +func (m *Manager) readAccount(homeAccountID string, envAliases []string, realm string) (shared.Account, error) { + m.contractMu.RLock() + + // 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. + // We can't change that. The other is because the keys are made using a specific "env", but here we are allowing + // 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 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") +} + +func (m *Manager) writeAccount(account shared.Account) error { + key := account.Key() + + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract.Accounts[key] = account + return nil +} + +func (m *Manager) readAppMetaData(envAliases []string, clientID string) (AppMetaData, error) { + m.contractMu.RLock() + 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") +} + +func (m *Manager) writeAppMetaData(AppMetaData AppMetaData) error { + key := AppMetaData.Key() + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract.AppMetaData[key] = AppMetaData + return nil +} + +// RemoveAccount removes all the associated ATs, RTs and IDTs from the cache associated with this account. +func (m *Manager) RemoveAccount(account shared.Account, clientID string) { + m.removeRefreshTokens(account.HomeAccountID, account.Environment, clientID) + m.removeAccessTokens(account.HomeAccountID, account.Environment) + m.removeIDTokens(account.HomeAccountID, account.Environment) + m.removeAccounts(account.HomeAccountID, account.Environment) +} + +func (m *Manager) removeRefreshTokens(homeID string, env string, clientID string) { + m.contractMu.Lock() + defer m.contractMu.Unlock() + for key, rt := range m.contract.RefreshTokens { + // Check for RTs associated with the account. + if rt.HomeAccountID == homeID && rt.Environment == env { + // Do RT's app ownership check as a precaution, in case family apps + // and 3rd-party apps share same token cache, although they should not. + if rt.ClientID == clientID || rt.FamilyID != "" { + delete(m.contract.RefreshTokens, key) + } + } + } +} + +func (m *Manager) removeAccessTokens(homeID string, env string) { + m.contractMu.Lock() + defer m.contractMu.Unlock() + for key, at := range m.contract.AccessTokens { + // Remove AT's associated with the account + if at.HomeAccountID == homeID && at.Environment == env { + // # To avoid the complexity of locating sibling family app's AT, we skip AT's app ownership check. + // It means ATs for other apps will also be removed, it is OK because: + // non-family apps are not supposed to share token cache to begin with; + // Even if it happens, we keep other app's RT already, so SSO still works. + delete(m.contract.AccessTokens, key) + } + } +} + +func (m *Manager) removeIDTokens(homeID string, env string) { + m.contractMu.Lock() + defer m.contractMu.Unlock() + for key, idt := range m.contract.IDTokens { + // Remove ID tokens associated with the account. + if idt.HomeAccountID == homeID && idt.Environment == env { + delete(m.contract.IDTokens, key) + } + } +} + +func (m *Manager) removeAccounts(homeID string, env string) { + m.contractMu.Lock() + defer m.contractMu.Unlock() + for key, acc := range m.contract.Accounts { + // Remove the specified account. + if acc.HomeAccountID == homeID && acc.Environment == env { + delete(m.contract.Accounts, key) + } + } +} + +// update updates the internal cache object. This is for use in tests, other uses are not +// supported. +func (m *Manager) update(cache *Contract) { + m.contractMu.Lock() + defer m.contractMu.Unlock() + m.contract = cache +} + +// Marshal implements cache.Marshaler. +func (m *Manager) Marshal() ([]byte, error) { + m.contractMu.RLock() + defer m.contractMu.RUnlock() + return json.Marshal(m.contract) +} + +// Unmarshal implements cache.Unmarshaler. +func (m *Manager) Unmarshal(b []byte) error { + m.contractMu.Lock() + defer m.contractMu.Unlock() + + contract := NewContract() + + err := json.Unmarshal(b, contract) + if err != nil { + return err + } + + m.contract = contract + + return nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported/exported.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported/exported.go new file mode 100644 index 000000000..de1bf381f --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported/exported.go @@ -0,0 +1,36 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// package exported contains internal types that are re-exported from a public package +package exported + +// AssertionRequestOptions has information required to generate a client assertion +type AssertionRequestOptions struct { + // ClientID identifies the application for which an assertion is requested. Used as the assertion's "iss" and "sub" claims. + ClientID string + + // TokenEndpoint is the intended token endpoint. Used as the assertion's "aud" claim. + TokenEndpoint string +} + +// TokenProviderParameters is the authentication parameters passed to token providers +type TokenProviderParameters struct { + // Claims contains any additional claims requested for the token + Claims string + // CorrelationID of the authentication request + CorrelationID string + // Scopes requested for the token + Scopes []string + // TenantID identifies the tenant in which to authenticate + TenantID string +} + +// TokenProviderResult is the authentication result returned by custom token providers +type TokenProviderResult struct { + // AccessToken is the requested token + AccessToken string + // ExpiresInSeconds is the lifetime of the token in seconds + ExpiresInSeconds int + // RefreshInSeconds indicates the suggested time to refresh the token, if any + RefreshInSeconds int +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/design.md b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/design.md new file mode 100644 index 000000000..09edb01b7 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/design.md @@ -0,0 +1,140 @@ +# JSON Package Design +Author: John Doak(jdoak@microsoft.com) + +## Why? + +This project needs a special type of marshal/unmarshal not directly supported +by the encoding/json package. + +The need revolves around a few key wants/needs: +- unmarshal and marshal structs representing JSON messages +- fields in the messgage not in the struct must be maintained when unmarshalled +- those same fields must be marshalled back when encoded again + +The initial version used map[string]interface{} to put in the keys that +were known and then any other keys were put into a field called AdditionalFields. + +This has a few negatives: +- Dual marshaling/unmarshalling is required +- Adding a struct field requires manually adding a key by name to be encoded/decoded from the map (which is a loosely coupled construct), which can lead to bugs that aren't detected or have bad side effects +- Tests can become quickly disconnected if those keys aren't put +in tests as well. So you think you have support working, but you +don't. Existing tests were found that didn't test the marshalling output. +- There is no enforcement that if AdditionalFields is required on one struct, it should be on all containers +that don't have custom marshal/unmarshal. + +This package aims to support our needs by providing custom Marshal()/Unmarshal() functions. + +This prevents all the negatives in the initial solution listed above. However, it does add its own negative: +- Custom encoding/decoding via reflection is messy (as can be seen in encoding/json itself) + +Go proverb: Reflection is never clear +Suggested reading: https://blog.golang.org/laws-of-reflection + +## Important design decisions + +- We don't want to understand all JSON decoding rules +- We don't want to deal with all the quoting, commas, etc on decode +- Need support for json.Marshaler/Unmarshaler, so we can support types like time.Time +- If struct does not implement json.Unmarshaler, it must have AdditionalFields defined +- We only support root level objects that are \*struct or struct + +To faciliate these goals, we will utilize the json.Encoder and json.Decoder. +They provide streaming processing (efficient) and return errors on bad JSON. + +Support for json.Marshaler/Unmarshaler allows for us to use non-basic types +that must be specially encoded/decoded (like time.Time objects). + +We don't support types that can't customer unmarshal or have AdditionalFields +in order to prevent future devs from forgetting that important field and +generating bad return values. + +Support for root level objects of \*struct or struct simply acknowledges the +fact that this is designed only for the purposes listed in the Introduction. +Outside that (like encoding a lone number) should be done with the +regular json package (as it will not have additional fields). + +We don't support a few things on json supported reference types and structs: +- \*map: no need for pointers to maps +- \*slice: no need for pointers to slices +- any further pointers on struct after \*struct + +There should never be a need for this in Go. + +## Design + +## State Machines + +This uses state machine designs that based upon the Rob Pike talk on +lexers and parsers: https://www.youtube.com/watch?v=HxaD_trXwRE + +This is the most common pattern for state machines in Go and +the model to follow closesly when dealing with streaming +processing of textual data. + +Our state machines are based on the type: +```go +type stateFn func() (stateFn, error) +``` + +The state machine itself is simply a struct that has methods that +satisfy stateFn. + +Our state machines have a few standard calls +- run(): runs the state machine +- start(): always the first stateFn to be called + +All state machines have the following logic: +* run() is called +* start() is called and returns the next stateFn or error +* stateFn is called + - If returned stateFn(next state) is non-nil, call it + - If error is non-nil, run() returns the error + - If stateFn == nil and err == nil, run() return err == nil + +## Supporting types + +Marshalling/Unmarshalling must support(within top level struct): +- struct +- \*struct +- []struct +- []\*struct +- []map[string]structContainer +- [][]structContainer + +**Term note:** structContainer == type that has a struct or \*struct inside it + +We specifically do not support []interface or map[string]interface +where the interface value would hold some value with a struct in it. + +Those will still marshal/unmarshal, but without support for +AdditionalFields. + +## Marshalling + +The marshalling design will be based around a statemachine design. + +The basic logic is as follows: + +* If struct has custom marshaller, call it and return +* If struct has field "AdditionalFields", it must be a map[string]interface{} +* If struct does not have "AdditionalFields", give an error +* Get struct tag detailing json names to go names, create mapping +* For each public field name + - Write field name out + - If field value is a struct, recursively call our state machine + - Otherwise, use the json.Encoder to write out the value + +## Unmarshalling + +The unmarshalling desin is also based around a statemachine design. The +basic logic is as follows: + +* If struct has custom marhaller, call it +* If struct has field "AdditionalFields", it must be a map[string]interface{} +* Get struct tag detailing json names to go names, create mapping +* For each key found + - If key exists, + - If value is basic type, extract value into struct field using Decoder + - If value is struct type, recursively call statemachine + - If key doesn't exist, add it to AdditionalFields if it exists using Decoder diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/json.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/json.go new file mode 100644 index 000000000..2134e57c9 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/json.go @@ -0,0 +1,166 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package json provide functions for marshalling an unmarshalling types to JSON. These functions are meant to +// be utilized inside of structs that implement json.Unmarshaler and json.Marshaler interfaces. +// This package provides the additional functionality of writing fields that are not in the struct when marshalling +// to a field called AdditionalFields if that field exists and is a map[string]interface{}. +// When marshalling, if the struct has all the same prerequisites, it will uses the keys in AdditionalFields as +// extra fields. This package uses encoding/json underneath. +package json + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "strings" +) + +const addField = "AdditionalFields" + +var ( + leftBrace = []byte("{")[0] + rightBrace = []byte("}")[0] + comma = []byte(",")[0] + leftParen = []byte("[")[0] + rightParen = []byte("]")[0] +) + +var mapStrInterType = reflect.TypeOf(map[string]interface{}{}) + +// stateFn defines a state machine function. This will be used in all state +// machines in this package. +type stateFn func() (stateFn, error) + +// Marshal is used to marshal a type into its JSON representation. It +// wraps the stdlib calls in order to marshal a struct or *struct so +// that a field called "AdditionalFields" of type map[string]interface{} +// with "-" used inside struct tag `json:"-"` can be marshalled as if +// they were fields within the struct. +func Marshal(i interface{}) ([]byte, error) { + buff := bytes.Buffer{} + enc := json.NewEncoder(&buff) + enc.SetEscapeHTML(false) + enc.SetIndent("", "") + + v := reflect.ValueOf(i) + if v.Kind() != reflect.Ptr && v.CanAddr() { + v = v.Addr() + } + err := marshalStruct(v, &buff, enc) + if err != nil { + return nil, err + } + return buff.Bytes(), nil +} + +// Unmarshal unmarshals a []byte representing JSON into i, which must be a *struct. In addition, if the struct has +// a field called AdditionalFields of type map[string]interface{}, JSON data representing fields not in the struct +// will be written as key/value pairs to AdditionalFields. +func Unmarshal(b []byte, i interface{}) error { + if len(b) == 0 { + return nil + } + + jdec := json.NewDecoder(bytes.NewBuffer(b)) + jdec.UseNumber() + return unmarshalStruct(jdec, i) +} + +// MarshalRaw marshals i into a json.RawMessage. If I cannot be marshalled, +// this will panic. This is exposed to help test AdditionalField values +// which are stored as json.RawMessage. +func MarshalRaw(i interface{}) json.RawMessage { + b, err := json.Marshal(i) + if err != nil { + panic(err) + } + return json.RawMessage(b) +} + +// isDelim simply tests to see if a json.Token is a delimeter. +func isDelim(got json.Token) bool { + switch got.(type) { + case json.Delim: + return true + } + return false +} + +// delimIs tests got to see if it is want. +func delimIs(got json.Token, want rune) bool { + switch v := got.(type) { + case json.Delim: + if v == json.Delim(want) { + return true + } + } + return false +} + +// hasMarshalJSON will determine if the value or a pointer to this value has +// the MarshalJSON method. +func hasMarshalJSON(v reflect.Value) bool { + ok := false + if _, ok = v.Interface().(json.Marshaler); !ok { + var i any + if v.Kind() == reflect.Ptr { + i = v.Elem().Interface() + } else if v.CanAddr() { + i = v.Addr().Interface() + } + _, ok = i.(json.Marshaler) + } + return ok +} + +// callMarshalJSON will call MarshalJSON() method on the value or a pointer to this value. +// This will panic if the method is not defined. +func callMarshalJSON(v reflect.Value) ([]byte, error) { + if marsh, ok := v.Interface().(json.Marshaler); ok { + return marsh.MarshalJSON() + } + + if v.Kind() == reflect.Ptr { + if marsh, ok := v.Elem().Interface().(json.Marshaler); ok { + return marsh.MarshalJSON() + } + } else { + if v.CanAddr() { + if marsh, ok := v.Addr().Interface().(json.Marshaler); ok { + return marsh.MarshalJSON() + } + } + } + + panic(fmt.Sprintf("callMarshalJSON called on type %T that does not have MarshalJSON defined", v.Interface())) +} + +// hasUnmarshalJSON will determine if the value or a pointer to this value has +// the UnmarshalJSON method. +func hasUnmarshalJSON(v reflect.Value) bool { + // You can't unmarshal on a non-pointer type. + if v.Kind() != reflect.Ptr { + if !v.CanAddr() { + return false + } + v = v.Addr() + } + + _, ok := v.Interface().(json.Unmarshaler) + return ok +} + +// hasOmitEmpty indicates if the field has instructed us to not output +// the field if omitempty is set on the tag. tag is the string +// returned by reflect.StructField.Tag().Get(). +func hasOmitEmpty(tag string) bool { + sl := strings.Split(tag, ",") + for _, str := range sl { + if str == "omitempty" { + return true + } + } + return false +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/mapslice.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/mapslice.go new file mode 100644 index 000000000..cef442f25 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/mapslice.go @@ -0,0 +1,333 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package json + +import ( + "encoding/json" + "fmt" + "reflect" +) + +// unmarshalMap unmarshal's a map. +func unmarshalMap(dec *json.Decoder, m reflect.Value) error { + if m.Kind() != reflect.Ptr || m.Elem().Kind() != reflect.Map { + panic("unmarshalMap called on non-*map value") + } + mapValueType := m.Elem().Type().Elem() + walk := mapWalk{dec: dec, m: m, valueType: mapValueType} + if err := walk.run(); err != nil { + return err + } + return nil +} + +type mapWalk struct { + dec *json.Decoder + key string + m reflect.Value + valueType reflect.Type +} + +// run runs our decoder state machine. +func (m *mapWalk) run() error { + var state = m.start + var err error + for { + state, err = state() + if err != nil { + return err + } + if state == nil { + return nil + } + } +} + +func (m *mapWalk) start() (stateFn, error) { + // maps can have custom unmarshaler's. + if hasUnmarshalJSON(m.m) { + err := m.dec.Decode(m.m.Interface()) + if err != nil { + return nil, err + } + return nil, nil + } + + // We only want to use this if the map value is: + // *struct/struct/map/slice + // otherwise use standard decode + t, _ := m.valueBaseType() + switch t.Kind() { + case reflect.Struct, reflect.Map, reflect.Slice: + delim, err := m.dec.Token() + if err != nil { + return nil, err + } + // This indicates the value was set to JSON null. + if delim == nil { + return nil, nil + } + if !delimIs(delim, '{') { + return nil, fmt.Errorf("Unmarshal expected opening {, received %v", delim) + } + return m.next, nil + case reflect.Ptr: + return nil, fmt.Errorf("do not support maps with values of '**type' or '*reference") + } + + // This is a basic map type, so just use Decode(). + if err := m.dec.Decode(m.m.Interface()); err != nil { + return nil, err + } + + return nil, nil +} + +func (m *mapWalk) next() (stateFn, error) { + if m.dec.More() { + key, err := m.dec.Token() + if err != nil { + return nil, err + } + m.key = key.(string) + return m.storeValue, nil + } + // No more entries, so remove final }. + _, err := m.dec.Token() + if err != nil { + return nil, err + } + return nil, nil +} + +func (m *mapWalk) storeValue() (stateFn, error) { + v := m.valueType + for { + switch v.Kind() { + case reflect.Ptr: + v = v.Elem() + continue + case reflect.Struct: + return m.storeStruct, nil + case reflect.Map: + return m.storeMap, nil + case reflect.Slice: + return m.storeSlice, nil + } + return nil, fmt.Errorf("bug: mapWalk.storeValue() called on unsupported type: %v", v.Kind()) + } +} + +func (m *mapWalk) storeStruct() (stateFn, error) { + v := newValue(m.valueType) + if err := unmarshalStruct(m.dec, v.Interface()); err != nil { + return nil, err + } + + if m.valueType.Kind() == reflect.Ptr { + m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v) + return m.next, nil + } + m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v.Elem()) + + return m.next, nil +} + +func (m *mapWalk) storeMap() (stateFn, error) { + v := reflect.MakeMap(m.valueType) + ptr := newValue(v.Type()) + ptr.Elem().Set(v) + if err := unmarshalMap(m.dec, ptr); err != nil { + return nil, err + } + + m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v) + + return m.next, nil +} + +func (m *mapWalk) storeSlice() (stateFn, error) { + v := newValue(m.valueType) + if err := unmarshalSlice(m.dec, v); err != nil { + return nil, err + } + + m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v.Elem()) + + return m.next, nil +} + +// valueType returns the underlying Type. So a *struct would yield +// struct, etc... +func (m *mapWalk) valueBaseType() (reflect.Type, bool) { + ptr := false + v := m.valueType + if v.Kind() == reflect.Ptr { + ptr = true + v = v.Elem() + } + return v, ptr +} + +// unmarshalSlice unmarshal's the next value, which must be a slice, into +// ptrSlice, which must be a pointer to a slice. newValue() can be use to +// create the slice. +func unmarshalSlice(dec *json.Decoder, ptrSlice reflect.Value) error { + if ptrSlice.Kind() != reflect.Ptr || ptrSlice.Elem().Kind() != reflect.Slice { + panic("unmarshalSlice called on non-*[]slice value") + } + sliceValueType := ptrSlice.Elem().Type().Elem() + walk := sliceWalk{ + dec: dec, + s: ptrSlice, + valueType: sliceValueType, + } + if err := walk.run(); err != nil { + return err + } + + return nil +} + +type sliceWalk struct { + dec *json.Decoder + s reflect.Value // *[]slice + valueType reflect.Type +} + +// run runs our decoder state machine. +func (s *sliceWalk) run() error { + var state = s.start + var err error + for { + state, err = state() + if err != nil { + return err + } + if state == nil { + return nil + } + } +} + +func (s *sliceWalk) start() (stateFn, error) { + // slices can have custom unmarshaler's. + if hasUnmarshalJSON(s.s) { + err := s.dec.Decode(s.s.Interface()) + if err != nil { + return nil, err + } + return nil, nil + } + + // We only want to use this if the slice value is: + // []*struct/[]struct/[]map/[]slice + // otherwise use standard decode + t := s.valueBaseType() + + switch t.Kind() { + case reflect.Ptr: + return nil, fmt.Errorf("cannot unmarshal into a ** or *") + case reflect.Struct, reflect.Map, reflect.Slice: + delim, err := s.dec.Token() + if err != nil { + return nil, err + } + // This indicates the value was set to nil. + if delim == nil { + return nil, nil + } + if !delimIs(delim, '[') { + return nil, fmt.Errorf("Unmarshal expected opening [, received %v", delim) + } + return s.next, nil + } + + if err := s.dec.Decode(s.s.Interface()); err != nil { + return nil, err + } + return nil, nil +} + +func (s *sliceWalk) next() (stateFn, error) { + if s.dec.More() { + return s.storeValue, nil + } + // Nothing left in the slice, remove closing ] + _, err := s.dec.Token() + return nil, err +} + +func (s *sliceWalk) storeValue() (stateFn, error) { + t := s.valueBaseType() + switch t.Kind() { + case reflect.Ptr: + return nil, fmt.Errorf("do not support 'pointer to pointer' or 'pointer to reference' types") + case reflect.Struct: + return s.storeStruct, nil + case reflect.Map: + return s.storeMap, nil + case reflect.Slice: + return s.storeSlice, nil + } + return nil, fmt.Errorf("bug: sliceWalk.storeValue() called on unsupported type: %v", t.Kind()) +} + +func (s *sliceWalk) storeStruct() (stateFn, error) { + v := newValue(s.valueType) + if err := unmarshalStruct(s.dec, v.Interface()); err != nil { + return nil, err + } + + if s.valueType.Kind() == reflect.Ptr { + s.s.Elem().Set(reflect.Append(s.s.Elem(), v)) + return s.next, nil + } + + s.s.Elem().Set(reflect.Append(s.s.Elem(), v.Elem())) + return s.next, nil +} + +func (s *sliceWalk) storeMap() (stateFn, error) { + v := reflect.MakeMap(s.valueType) + ptr := newValue(v.Type()) + ptr.Elem().Set(v) + + if err := unmarshalMap(s.dec, ptr); err != nil { + return nil, err + } + + s.s.Elem().Set(reflect.Append(s.s.Elem(), v)) + + return s.next, nil +} + +func (s *sliceWalk) storeSlice() (stateFn, error) { + v := newValue(s.valueType) + if err := unmarshalSlice(s.dec, v); err != nil { + return nil, err + } + + s.s.Elem().Set(reflect.Append(s.s.Elem(), v.Elem())) + + return s.next, nil +} + +// valueType returns the underlying Type. So a *struct would yield +// struct, etc... +func (s *sliceWalk) valueBaseType() reflect.Type { + v := s.valueType + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + return v +} + +// newValue() returns a new *type that represents type passed. +func newValue(valueType reflect.Type) reflect.Value { + if valueType.Kind() == reflect.Ptr { + return reflect.New(valueType.Elem()) + } + return reflect.New(valueType) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/marshal.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/marshal.go new file mode 100644 index 000000000..df5dc6e11 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/marshal.go @@ -0,0 +1,346 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package json + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "unicode" +) + +// marshalStruct takes in i, which must be a *struct or struct and marshals its content +// as JSON into buff (sometimes with writes to buff directly, sometimes via enc). +// This call is recursive for all fields of *struct or struct type. +func marshalStruct(v reflect.Value, buff *bytes.Buffer, enc *json.Encoder) error { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + // We only care about custom Marshalling a struct. + if v.Kind() != reflect.Struct { + return fmt.Errorf("bug: marshal() received a non *struct or struct, received type %T", v.Interface()) + } + + if hasMarshalJSON(v) { + b, err := callMarshalJSON(v) + if err != nil { + return err + } + buff.Write(b) + return nil + } + + t := v.Type() + + // If it has an AdditionalFields field make sure its the right type. + f := v.FieldByName(addField) + if f.Kind() != reflect.Invalid { + if f.Kind() != reflect.Map { + return fmt.Errorf("type %T has field 'AdditionalFields' that is not a map[string]interface{}", v.Interface()) + } + if !f.Type().AssignableTo(mapStrInterType) { + return fmt.Errorf("type %T has field 'AdditionalFields' that is not a map[string]interface{}", v.Interface()) + } + } + + translator, err := findFields(v) + if err != nil { + return err + } + + buff.WriteByte(leftBrace) + for x := 0; x < v.NumField(); x++ { + field := v.Field(x) + + // We don't access private fields. + if unicode.IsLower(rune(t.Field(x).Name[0])) { + continue + } + + if t.Field(x).Name == addField { + if v.Field(x).Len() > 0 { + if err := writeAddFields(field.Interface(), buff, enc); err != nil { + return err + } + buff.WriteByte(comma) + } + continue + } + + // If they have omitempty set, we don't write out the field if + // it is the zero value. + if hasOmitEmpty(t.Field(x).Tag.Get("json")) { + if v.Field(x).IsZero() { + continue + } + } + + // Write out the field name part. + jsonName := translator.jsonName(t.Field(x).Name) + buff.WriteString(fmt.Sprintf("%q:", jsonName)) + + if field.Kind() == reflect.Ptr { + field = field.Elem() + } + + if err := marshalStructField(field, buff, enc); err != nil { + return err + } + } + + buff.Truncate(buff.Len() - 1) // Remove final comma + buff.WriteByte(rightBrace) + + return nil +} + +func marshalStructField(field reflect.Value, buff *bytes.Buffer, enc *json.Encoder) error { + // Determine if we need a trailing comma. + defer buff.WriteByte(comma) + + switch field.Kind() { + // If it was a *struct or struct, we need to recursively all marshal(). + case reflect.Struct: + if field.CanAddr() { + field = field.Addr() + } + return marshalStruct(field, buff, enc) + case reflect.Map: + return marshalMap(field, buff, enc) + case reflect.Slice: + return marshalSlice(field, buff, enc) + } + + // It is just a basic type, so encode it. + if err := enc.Encode(field.Interface()); err != nil { + return err + } + buff.Truncate(buff.Len() - 1) // Remove Encode() added \n + + return nil +} + +func marshalMap(v reflect.Value, buff *bytes.Buffer, enc *json.Encoder) error { + if v.Kind() != reflect.Map { + return fmt.Errorf("bug: marshalMap() called on %T", v.Interface()) + } + if v.Len() == 0 { + buff.WriteByte(leftBrace) + buff.WriteByte(rightBrace) + return nil + } + encoder := mapEncode{m: v, buff: buff, enc: enc} + return encoder.run() +} + +type mapEncode struct { + m reflect.Value + buff *bytes.Buffer + enc *json.Encoder + + valueBaseType reflect.Type +} + +// run runs our encoder state machine. +func (m *mapEncode) run() error { + var state = m.start + var err error + for { + state, err = state() + if err != nil { + return err + } + if state == nil { + return nil + } + } +} + +func (m *mapEncode) start() (stateFn, error) { + if hasMarshalJSON(m.m) { + b, err := callMarshalJSON(m.m) + if err != nil { + return nil, err + } + m.buff.Write(b) + return nil, nil + } + + valueBaseType := m.m.Type().Elem() + if valueBaseType.Kind() == reflect.Ptr { + valueBaseType = valueBaseType.Elem() + } + m.valueBaseType = valueBaseType + + switch valueBaseType.Kind() { + case reflect.Ptr: + return nil, fmt.Errorf("Marshal does not support ** or *") + case reflect.Struct, reflect.Map, reflect.Slice: + return m.encode, nil + } + + // If the map value doesn't have a struct/map/slice, just Encode() it. + if err := m.enc.Encode(m.m.Interface()); err != nil { + return nil, err + } + m.buff.Truncate(m.buff.Len() - 1) // Remove Encode() added \n + return nil, nil +} + +func (m *mapEncode) encode() (stateFn, error) { + m.buff.WriteByte(leftBrace) + + iter := m.m.MapRange() + for iter.Next() { + // Write the key. + k := iter.Key() + m.buff.WriteString(fmt.Sprintf("%q:", k.String())) + + v := iter.Value() + switch m.valueBaseType.Kind() { + case reflect.Struct: + if v.CanAddr() { + v = v.Addr() + } + if err := marshalStruct(v, m.buff, m.enc); err != nil { + return nil, err + } + case reflect.Map: + if err := marshalMap(v, m.buff, m.enc); err != nil { + return nil, err + } + case reflect.Slice: + if err := marshalSlice(v, m.buff, m.enc); err != nil { + return nil, err + } + default: + panic(fmt.Sprintf("critical bug: mapEncode.encode() called with value base type: %v", m.valueBaseType.Kind())) + } + m.buff.WriteByte(comma) + } + m.buff.Truncate(m.buff.Len() - 1) // Remove final comma + m.buff.WriteByte(rightBrace) + + return nil, nil +} + +func marshalSlice(v reflect.Value, buff *bytes.Buffer, enc *json.Encoder) error { + if v.Kind() != reflect.Slice { + return fmt.Errorf("bug: marshalSlice() called on %T", v.Interface()) + } + if v.Len() == 0 { + buff.WriteByte(leftParen) + buff.WriteByte(rightParen) + return nil + } + encoder := sliceEncode{s: v, buff: buff, enc: enc} + return encoder.run() +} + +type sliceEncode struct { + s reflect.Value + buff *bytes.Buffer + enc *json.Encoder + + valueBaseType reflect.Type +} + +// run runs our encoder state machine. +func (s *sliceEncode) run() error { + var state = s.start + var err error + for { + state, err = state() + if err != nil { + return err + } + if state == nil { + return nil + } + } +} + +func (s *sliceEncode) start() (stateFn, error) { + if hasMarshalJSON(s.s) { + b, err := callMarshalJSON(s.s) + if err != nil { + return nil, err + } + s.buff.Write(b) + return nil, nil + } + + valueBaseType := s.s.Type().Elem() + if valueBaseType.Kind() == reflect.Ptr { + valueBaseType = valueBaseType.Elem() + } + s.valueBaseType = valueBaseType + + switch valueBaseType.Kind() { + case reflect.Ptr: + return nil, fmt.Errorf("Marshal does not support ** or *") + case reflect.Struct, reflect.Map, reflect.Slice: + return s.encode, nil + } + + // If the map value doesn't have a struct/map/slice, just Encode() it. + if err := s.enc.Encode(s.s.Interface()); err != nil { + return nil, err + } + s.buff.Truncate(s.buff.Len() - 1) // Remove Encode added \n + + return nil, nil +} + +func (s *sliceEncode) encode() (stateFn, error) { + s.buff.WriteByte(leftParen) + for i := 0; i < s.s.Len(); i++ { + v := s.s.Index(i) + switch s.valueBaseType.Kind() { + case reflect.Struct: + if v.CanAddr() { + v = v.Addr() + } + if err := marshalStruct(v, s.buff, s.enc); err != nil { + return nil, err + } + case reflect.Map: + if err := marshalMap(v, s.buff, s.enc); err != nil { + return nil, err + } + case reflect.Slice: + if err := marshalSlice(v, s.buff, s.enc); err != nil { + return nil, err + } + default: + panic(fmt.Sprintf("critical bug: mapEncode.encode() called with value base type: %v", s.valueBaseType.Kind())) + } + s.buff.WriteByte(comma) + } + s.buff.Truncate(s.buff.Len() - 1) // Remove final comma + s.buff.WriteByte(rightParen) + return nil, nil +} + +// writeAddFields writes the AdditionalFields struct field out to JSON as field +// values. i must be a map[string]interface{} or this will panic. +func writeAddFields(i interface{}, buff *bytes.Buffer, enc *json.Encoder) error { + m := i.(map[string]interface{}) + + x := 0 + for k, v := range m { + buff.WriteString(fmt.Sprintf("%q:", k)) + if err := enc.Encode(v); err != nil { + return err + } + buff.Truncate(buff.Len() - 1) // Remove Encode() added \n + + if x+1 != len(m) { + buff.WriteByte(comma) + } + x++ + } + return nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/struct.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/struct.go new file mode 100644 index 000000000..07751544a --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/struct.go @@ -0,0 +1,290 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package json + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" +) + +func unmarshalStruct(jdec *json.Decoder, i interface{}) error { + v := reflect.ValueOf(i) + if v.Kind() != reflect.Ptr { + return fmt.Errorf("Unmarshal() received type %T, which is not a *struct", i) + } + v = v.Elem() + if v.Kind() != reflect.Struct { + return fmt.Errorf("Unmarshal() received type %T, which is not a *struct", i) + } + + if hasUnmarshalJSON(v) { + // Indicates that this type has a custom Unmarshaler. + return jdec.Decode(v.Addr().Interface()) + } + + f := v.FieldByName(addField) + if f.Kind() == reflect.Invalid { + return fmt.Errorf("Unmarshal(%T) only supports structs that have the field AdditionalFields or implements json.Unmarshaler", i) + } + + if f.Kind() != reflect.Map || !f.Type().AssignableTo(mapStrInterType) { + return fmt.Errorf("type %T has field 'AdditionalFields' that is not a map[string]interface{}", i) + } + + dec := newDecoder(jdec, v) + return dec.run() +} + +type decoder struct { + dec *json.Decoder + value reflect.Value // This will be a reflect.Struct + translator translateFields + key string +} + +func newDecoder(dec *json.Decoder, value reflect.Value) *decoder { + return &decoder{value: value, dec: dec} +} + +// run runs our decoder state machine. +func (d *decoder) run() error { + var state = d.start + var err error + for { + state, err = state() + if err != nil { + return err + } + if state == nil { + return nil + } + } +} + +// start looks for our opening delimeter '{' and then transitions to looping through our fields. +func (d *decoder) start() (stateFn, error) { + var err error + d.translator, err = findFields(d.value) + if err != nil { + return nil, err + } + + delim, err := d.dec.Token() + if err != nil { + return nil, err + } + if !delimIs(delim, '{') { + return nil, fmt.Errorf("Unmarshal expected opening {, received %v", delim) + } + + return d.next, nil +} + +// next gets the next struct field name from the raw json or stops the machine if we get our closing }. +func (d *decoder) next() (stateFn, error) { + if !d.dec.More() { + // Remove the closing }. + if _, err := d.dec.Token(); err != nil { + return nil, err + } + return nil, nil + } + + key, err := d.dec.Token() + if err != nil { + return nil, err + } + + d.key = key.(string) + return d.storeValue, nil +} + +// storeValue takes the next value and stores it our struct. If the field can't be found +// in the struct, it pushes the operation to storeAdditional(). +func (d *decoder) storeValue() (stateFn, error) { + goName := d.translator.goName(d.key) + if goName == "" { + goName = d.key + } + + // We don't have the field in the struct, so it goes in AdditionalFields. + f := d.value.FieldByName(goName) + if f.Kind() == reflect.Invalid { + return d.storeAdditional, nil + } + + // Indicates that this type has a custom Unmarshaler. + if hasUnmarshalJSON(f) { + err := d.dec.Decode(f.Addr().Interface()) + if err != nil { + return nil, err + } + return d.next, nil + } + + t, isPtr, err := fieldBaseType(d.value, goName) + if err != nil { + return nil, fmt.Errorf("type(%s) had field(%s) %w", d.value.Type().Name(), goName, err) + } + + switch t.Kind() { + // We need to recursively call ourselves on any *struct or struct. + case reflect.Struct: + if isPtr { + if f.IsNil() { + f.Set(reflect.New(t)) + } + } else { + f = f.Addr() + } + if err := unmarshalStruct(d.dec, f.Interface()); err != nil { + return nil, err + } + return d.next, nil + case reflect.Map: + v := reflect.MakeMap(f.Type()) + ptr := newValue(f.Type()) + ptr.Elem().Set(v) + if err := unmarshalMap(d.dec, ptr); err != nil { + return nil, err + } + f.Set(ptr.Elem()) + return d.next, nil + case reflect.Slice: + v := reflect.MakeSlice(f.Type(), 0, 0) + ptr := newValue(f.Type()) + ptr.Elem().Set(v) + if err := unmarshalSlice(d.dec, ptr); err != nil { + return nil, err + } + f.Set(ptr.Elem()) + return d.next, nil + } + + if !isPtr { + f = f.Addr() + } + + // For values that are pointers, we need them to be non-nil in order + // to decode into them. + if f.IsNil() { + f.Set(reflect.New(t)) + } + + if err := d.dec.Decode(f.Interface()); err != nil { + return nil, err + } + + return d.next, nil +} + +// storeAdditional pushes the key/value into our .AdditionalFields map. +func (d *decoder) storeAdditional() (stateFn, error) { + rw := json.RawMessage{} + if err := d.dec.Decode(&rw); err != nil { + return nil, err + } + field := d.value.FieldByName(addField) + if field.IsNil() { + field.Set(reflect.MakeMap(field.Type())) + } + field.SetMapIndex(reflect.ValueOf(d.key), reflect.ValueOf(rw)) + return d.next, nil +} + +func fieldBaseType(v reflect.Value, fieldName string) (t reflect.Type, isPtr bool, err error) { + sf, ok := v.Type().FieldByName(fieldName) + if !ok { + return nil, false, fmt.Errorf("bug: fieldBaseType() lookup of field(%s) on type(%s): do not have field", fieldName, v.Type().Name()) + } + t = sf.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + isPtr = true + } + if t.Kind() == reflect.Ptr { + return nil, isPtr, fmt.Errorf("received pointer to pointer type, not supported") + } + return t, isPtr, nil +} + +type translateField struct { + jsonName string + goName string +} + +// translateFields is a list of translateFields with a handy lookup method. +type translateFields []translateField + +// goName loops through a list of fields looking for one contaning the jsonName and +// returning the goName. If not found, returns the empty string. +// Note: not a map because at this size slices are faster even in tight loops. +func (t translateFields) goName(jsonName string) string { + for _, entry := range t { + if entry.jsonName == jsonName { + return entry.goName + } + } + return "" +} + +// jsonName loops through a list of fields looking for one contaning the goName and +// returning the jsonName. If not found, returns the empty string. +// Note: not a map because at this size slices are faster even in tight loops. +func (t translateFields) jsonName(goName string) string { + for _, entry := range t { + if entry.goName == goName { + return entry.jsonName + } + } + return "" +} + +var umarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + +// findFields parses a struct and writes the field tags for lookup. It will return an error +// if any field has a type of *struct or struct that does not implement json.Marshaler. +func findFields(v reflect.Value) (translateFields, error) { + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if v.Kind() != reflect.Struct { + return nil, fmt.Errorf("findFields received a %s type, expected *struct or struct", v.Type().Name()) + } + tfs := make([]translateField, 0, v.NumField()) + for i := 0; i < v.NumField(); i++ { + tf := translateField{ + goName: v.Type().Field(i).Name, + jsonName: parseTag(v.Type().Field(i).Tag.Get("json")), + } + switch tf.jsonName { + case "", "-": + tf.jsonName = tf.goName + } + tfs = append(tfs, tf) + + f := v.Field(i) + if f.Kind() == reflect.Ptr { + f = f.Elem() + } + if f.Kind() == reflect.Struct { + if f.Type().Implements(umarshalerType) { + return nil, fmt.Errorf("struct type %q which has field %q which "+ + "doesn't implement json.Unmarshaler", v.Type().Name(), v.Type().Field(i).Name) + } + } + } + return tfs, nil +} + +// parseTag just returns the first entry in the tag. tag is the string +// returned by reflect.StructField.Tag().Get(). +func parseTag(tag string) string { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx] + } + return tag +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time/time.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time/time.go new file mode 100644 index 000000000..a1c99621e --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time/time.go @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package time provides for custom types to translate time from JSON and other formats +// into time.Time objects. +package time + +import ( + "fmt" + "strconv" + "strings" + "time" +) + +// Unix provides a type that can marshal and unmarshal a string representation +// of the unix epoch into a time.Time object. +type Unix struct { + T time.Time +} + +// MarshalJSON implements encoding/json.MarshalJSON(). +func (u Unix) MarshalJSON() ([]byte, error) { + if u.T.IsZero() { + return []byte(""), nil + } + return []byte(fmt.Sprintf("%q", strconv.FormatInt(u.T.Unix(), 10))), nil +} + +// UnmarshalJSON implements encoding/json.UnmarshalJSON(). +func (u *Unix) UnmarshalJSON(b []byte) error { + i, err := strconv.Atoi(strings.Trim(string(b), `"`)) + if err != nil { + return fmt.Errorf("unix time(%s) could not be converted from string to int: %w", string(b), err) + } + u.T = time.Unix(int64(i), 0) + return nil +} + +// DurationTime provides a type that can marshal and unmarshal a string representation +// of a duration from now into a time.Time object. +// Note: I'm not sure this is the best way to do this. What happens is we get a field +// called "expires_in" that represents the seconds from now that this expires. We +// turn that into a time we call .ExpiresOn. But maybe we should be recording +// when the token was received at .TokenRecieved and .ExpiresIn should remain as a duration. +// Then we could have a method called ExpiresOn(). Honestly, the whole thing is +// bad because the server doesn't return a concrete time. I think this is +// cleaner, but its not great either. +type DurationTime struct { + T time.Time +} + +// MarshalJSON implements encoding/json.MarshalJSON(). +func (d DurationTime) MarshalJSON() ([]byte, error) { + if d.T.IsZero() { + return []byte(""), nil + } + + dt := time.Until(d.T) + return []byte(fmt.Sprintf("%d", int64(dt*time.Second))), nil +} + +// UnmarshalJSON implements encoding/json.UnmarshalJSON(). +func (d *DurationTime) UnmarshalJSON(b []byte) error { + i, err := strconv.Atoi(strings.Trim(string(b), `"`)) + if err != nil { + return fmt.Errorf("unix time(%s) could not be converted from string to int: %w", string(b), err) + } + d.T = time.Now().Add(time.Duration(i) * time.Second) + return nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go new file mode 100644 index 000000000..c6baf2094 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local/server.go @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package local contains a local HTTP server used with interactive authentication. +package local + +import ( + "context" + "fmt" + "html" + "net" + "net/http" + "strconv" + "strings" + "time" +) + +var okPage = []byte(` + + + + + Authentication Complete + + +

      Authentication complete. You can return to the application. Feel free to close this browser tab.

      + + +`) + +const failPage = ` + + + + + Authentication Failed + + +

      Authentication failed. You can return to the application. Feel free to close this browser tab.

      +

      Error details: error %s error_description: %s

      + + +` + +// Result is the result from the redirect. +type Result struct { + // Code is the code sent by the authority server. + Code string + // Err is set if there was an error. + Err error +} + +// Server is an HTTP server. +type Server struct { + // Addr is the address the server is listening on. + Addr string + resultCh chan Result + s *http.Server + reqState string +} + +// New creates a local HTTP server and starts it. +func New(reqState string, port int) (*Server, error) { + var l net.Listener + var err error + var portStr string + if port > 0 { + // use port provided by caller + l, err = net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) + portStr = strconv.FormatInt(int64(port), 10) + } else { + // find a free port + for i := 0; i < 10; i++ { + l, err = net.Listen("tcp", "localhost:0") + if err != nil { + continue + } + addr := l.Addr().String() + portStr = addr[strings.LastIndex(addr, ":")+1:] + break + } + } + if err != nil { + return nil, err + } + + serv := &Server{ + Addr: fmt.Sprintf("http://localhost:%s", portStr), + s: &http.Server{Addr: "localhost:0", ReadHeaderTimeout: time.Second}, + reqState: reqState, + resultCh: make(chan Result, 1), + } + serv.s.Handler = http.HandlerFunc(serv.handler) + + if err := serv.start(l); err != nil { + return nil, err + } + + return serv, nil +} + +func (s *Server) start(l net.Listener) error { + go func() { + err := s.s.Serve(l) + if err != nil { + select { + case s.resultCh <- Result{Err: err}: + default: + } + } + }() + + return nil +} + +// Result gets the result of the redirect operation. Once a single result is returned, the server +// is shutdown. ctx deadline will be honored. +func (s *Server) Result(ctx context.Context) Result { + select { + case <-ctx.Done(): + return Result{Err: ctx.Err()} + case r := <-s.resultCh: + return r + } +} + +// Shutdown shuts down the server. +func (s *Server) Shutdown() { + // Note: You might get clever and think you can do this in handler() as a defer, you can't. + _ = s.s.Shutdown(context.Background()) +} + +func (s *Server) putResult(r Result) { + select { + case s.resultCh <- r: + default: + } +} + +func (s *Server) handler(w http.ResponseWriter, r *http.Request) { + q := r.URL.Query() + + headerErr := q.Get("error") + if headerErr != "" { + desc := html.EscapeString(q.Get("error_description")) + escapedHeaderErr := html.EscapeString(headerErr) + // Note: It is a little weird we handle some errors by not going to the failPage. If they all should, + // change this to s.error() and make s.error() write the failPage instead of an error code. + _, _ = w.Write([]byte(fmt.Sprintf(failPage, escapedHeaderErr, desc))) + s.putResult(Result{Err: fmt.Errorf("%s", desc)}) + + return + } + + respState := q.Get("state") + switch respState { + case s.reqState: + case "": + s.error(w, http.StatusInternalServerError, "server didn't send OAuth state") + return + default: + s.error(w, http.StatusInternalServerError, "mismatched OAuth state, req(%s), resp(%s)", s.reqState, respState) + return + } + + code := q.Get("code") + if code == "" { + s.error(w, http.StatusInternalServerError, "authorization code missing in query string") + return + } + + _, _ = w.Write(okPage) + s.putResult(Result{Code: code}) +} + +func (s *Server) error(w http.ResponseWriter, code int, str string, i ...interface{}) { + err := fmt.Errorf(str, i...) + http.Error(w, err.Error(), code) + s.putResult(Result{Err: err}) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/oauth.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/oauth.go new file mode 100644 index 000000000..738a29eb9 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/oauth.go @@ -0,0 +1,359 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package oauth + +import ( + "context" + "encoding/json" + "fmt" + "io" + "time" + + "github.com/google/uuid" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported" + 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" + "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/oauth/ops/wstrust" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs" +) + +// ResolveEndpointer contains the methods for resolving authority endpoints. +type ResolveEndpointer interface { + ResolveEndpoints(ctx context.Context, authorityInfo authority.Info, userPrincipalName string) (authority.Endpoints, error) +} + +// AccessTokens contains the methods for fetching tokens from different sources. +type AccessTokens interface { + DeviceCodeResult(ctx context.Context, authParameters authority.AuthParams) (accesstokens.DeviceCodeResult, error) + FromUsernamePassword(ctx context.Context, authParameters authority.AuthParams) (accesstokens.TokenResponse, error) + FromAuthCode(ctx context.Context, req accesstokens.AuthCodeRequest) (accesstokens.TokenResponse, error) + FromRefreshToken(ctx context.Context, appType accesstokens.AppType, authParams authority.AuthParams, cc *accesstokens.Credential, refreshToken string) (accesstokens.TokenResponse, error) + FromClientSecret(ctx context.Context, authParameters authority.AuthParams, clientSecret string) (accesstokens.TokenResponse, error) + FromAssertion(ctx context.Context, authParameters authority.AuthParams, assertion string) (accesstokens.TokenResponse, error) + FromUserAssertionClientSecret(ctx context.Context, authParameters authority.AuthParams, userAssertion string, clientSecret string) (accesstokens.TokenResponse, error) + FromUserAssertionClientCertificate(ctx context.Context, authParameters authority.AuthParams, userAssertion string, assertion string) (accesstokens.TokenResponse, error) + FromDeviceCodeResult(ctx context.Context, authParameters authority.AuthParams, deviceCodeResult accesstokens.DeviceCodeResult) (accesstokens.TokenResponse, error) + FromSamlGrant(ctx context.Context, authParameters authority.AuthParams, samlGrant wstrust.SamlTokenInfo) (accesstokens.TokenResponse, error) +} + +// FetchAuthority will be implemented by authority.Authority. +type FetchAuthority interface { + UserRealm(context.Context, authority.AuthParams) (authority.UserRealm, error) + AADInstanceDiscovery(context.Context, authority.Info) (authority.InstanceDiscoveryResponse, error) +} + +// FetchWSTrust contains the methods for interacting with WSTrust endpoints. +type FetchWSTrust interface { + Mex(ctx context.Context, federationMetadataURL string) (defs.MexDocument, error) + SAMLTokenInfo(ctx context.Context, authParameters authority.AuthParams, cloudAudienceURN string, endpoint defs.Endpoint) (wstrust.SamlTokenInfo, error) +} + +// Client provides tokens for various types of token requests. +type Client struct { + Resolver ResolveEndpointer + AccessTokens AccessTokens + Authority FetchAuthority + WSTrust FetchWSTrust +} + +// New is the constructor for Token. +func New(httpClient ops.HTTPClient) *Client { + r := ops.New(httpClient) + return &Client{ + Resolver: newAuthorityEndpoint(r), + AccessTokens: r.AccessTokens(), + Authority: r.Authority(), + WSTrust: r.WSTrust(), + } +} + +// ResolveEndpoints gets the authorization and token endpoints and creates an AuthorityEndpoints instance. +func (t *Client) ResolveEndpoints(ctx context.Context, authorityInfo authority.Info, userPrincipalName string) (authority.Endpoints, error) { + return t.Resolver.ResolveEndpoints(ctx, authorityInfo, userPrincipalName) +} + +// AADInstanceDiscovery attempts to discover a tenant endpoint (used in OIDC auth with an authorization endpoint). +// This is done by AAD which allows for aliasing of tenants (windows.sts.net is the same as login.windows.com). +func (t *Client) AADInstanceDiscovery(ctx context.Context, authorityInfo authority.Info) (authority.InstanceDiscoveryResponse, error) { + return t.Authority.AADInstanceDiscovery(ctx, authorityInfo) +} + +// AuthCode returns a token based on an authorization code. +func (t *Client) AuthCode(ctx context.Context, req accesstokens.AuthCodeRequest) (accesstokens.TokenResponse, error) { + if err := scopeError(req.AuthParams); err != nil { + return accesstokens.TokenResponse{}, err + } + if err := t.resolveEndpoint(ctx, &req.AuthParams, ""); err != nil { + return accesstokens.TokenResponse{}, err + } + + tResp, err := t.AccessTokens.FromAuthCode(ctx, req) + if err != nil { + return accesstokens.TokenResponse{}, fmt.Errorf("could not retrieve token from auth code: %w", err) + } + return tResp, nil +} + +// Credential acquires a token from the authority using a client credentials grant. +func (t *Client) Credential(ctx context.Context, authParams authority.AuthParams, cred *accesstokens.Credential) (accesstokens.TokenResponse, error) { + if cred.TokenProvider != nil { + now := time.Now() + scopes := make([]string, len(authParams.Scopes)) + copy(scopes, authParams.Scopes) + params := exported.TokenProviderParameters{ + Claims: authParams.Claims, + CorrelationID: uuid.New().String(), + Scopes: scopes, + TenantID: authParams.AuthorityInfo.Tenant, + } + pr, err := cred.TokenProvider(ctx, params) + if err != nil { + if len(scopes) == 0 { + err = fmt.Errorf("token request had an empty authority.AuthParams.Scopes, which may cause the following error: %w", err) + return accesstokens.TokenResponse{}, err + } + return accesstokens.TokenResponse{}, err + } + tr := accesstokens.TokenResponse{ + TokenType: authParams.AuthnScheme.AccessTokenType(), + AccessToken: pr.AccessToken, + ExpiresOn: now.Add(time.Duration(pr.ExpiresInSeconds) * time.Second), + GrantedScopes: accesstokens.Scopes{Slice: authParams.Scopes}, + } + if pr.RefreshInSeconds > 0 { + tr.RefreshOn = internalTime.DurationTime{ + T: now.Add(time.Duration(pr.RefreshInSeconds) * time.Second), + } + } + return tr, nil + } + + if err := t.resolveEndpoint(ctx, &authParams, ""); err != nil { + return accesstokens.TokenResponse{}, err + } + + if cred.Secret != "" { + return t.AccessTokens.FromClientSecret(ctx, authParams, cred.Secret) + } + jwt, err := cred.JWT(ctx, authParams) + if err != nil { + return accesstokens.TokenResponse{}, err + } + return t.AccessTokens.FromAssertion(ctx, authParams, jwt) +} + +// Credential acquires a token from the authority using a client credentials grant. +func (t *Client) OnBehalfOf(ctx context.Context, authParams authority.AuthParams, cred *accesstokens.Credential) (accesstokens.TokenResponse, error) { + if err := scopeError(authParams); err != nil { + return accesstokens.TokenResponse{}, err + } + if err := t.resolveEndpoint(ctx, &authParams, ""); err != nil { + return accesstokens.TokenResponse{}, err + } + + if cred.Secret != "" { + return t.AccessTokens.FromUserAssertionClientSecret(ctx, authParams, authParams.UserAssertion, cred.Secret) + } + jwt, err := cred.JWT(ctx, authParams) + if err != nil { + return accesstokens.TokenResponse{}, err + } + tr, err := t.AccessTokens.FromUserAssertionClientCertificate(ctx, authParams, authParams.UserAssertion, jwt) + if err != nil { + return accesstokens.TokenResponse{}, err + } + return tr, nil +} + +func (t *Client) Refresh(ctx context.Context, reqType accesstokens.AppType, authParams authority.AuthParams, cc *accesstokens.Credential, refreshToken accesstokens.RefreshToken) (accesstokens.TokenResponse, error) { + if err := scopeError(authParams); err != nil { + return accesstokens.TokenResponse{}, err + } + if err := t.resolveEndpoint(ctx, &authParams, ""); err != nil { + return accesstokens.TokenResponse{}, err + } + + tr, err := t.AccessTokens.FromRefreshToken(ctx, reqType, authParams, cc, refreshToken.Secret) + if err != nil { + return accesstokens.TokenResponse{}, err + } + return tr, nil +} + +// UsernamePassword retrieves a token where a username and password is used. However, if this is +// a user realm of "Federated", this uses SAML tokens. If "Managed", uses normal username/password. +func (t *Client) UsernamePassword(ctx context.Context, authParams authority.AuthParams) (accesstokens.TokenResponse, error) { + if err := scopeError(authParams); err != nil { + return accesstokens.TokenResponse{}, err + } + + if authParams.AuthorityInfo.AuthorityType == authority.ADFS { + if err := t.resolveEndpoint(ctx, &authParams, authParams.Username); err != nil { + return accesstokens.TokenResponse{}, err + } + return t.AccessTokens.FromUsernamePassword(ctx, authParams) + } + if err := t.resolveEndpoint(ctx, &authParams, ""); err != nil { + return accesstokens.TokenResponse{}, err + } + + userRealm, err := t.Authority.UserRealm(ctx, authParams) + if err != nil { + return accesstokens.TokenResponse{}, fmt.Errorf("problem getting user realm from authority: %w", err) + } + + switch userRealm.AccountType { + case authority.Federated: + mexDoc, err := t.WSTrust.Mex(ctx, userRealm.FederationMetadataURL) + if err != nil { + err = fmt.Errorf("problem getting mex doc from federated url(%s): %w", userRealm.FederationMetadataURL, err) + return accesstokens.TokenResponse{}, err + } + + saml, err := t.WSTrust.SAMLTokenInfo(ctx, authParams, userRealm.CloudAudienceURN, mexDoc.UsernamePasswordEndpoint) + if err != nil { + err = fmt.Errorf("problem getting SAML token info: %w", err) + return accesstokens.TokenResponse{}, err + } + tr, err := t.AccessTokens.FromSamlGrant(ctx, authParams, saml) + if err != nil { + return accesstokens.TokenResponse{}, err + } + return tr, nil + case authority.Managed: + if len(authParams.Scopes) == 0 { + err = fmt.Errorf("token request had an empty authority.AuthParams.Scopes, which may cause the following error: %w", err) + return accesstokens.TokenResponse{}, err + } + return t.AccessTokens.FromUsernamePassword(ctx, authParams) + } + return accesstokens.TokenResponse{}, errors.New("unknown account type") +} + +// DeviceCode is the result of a call to Token.DeviceCode(). +type DeviceCode struct { + // Result is the device code result from the first call in the device code flow. This allows + // the caller to retrieve the displayed code that is used to authorize on the second device. + Result accesstokens.DeviceCodeResult + authParams authority.AuthParams + + accessTokens AccessTokens +} + +// Token returns a token AFTER the user uses the user code on the second device. This will block +// until either: (1) the code is input by the user and the service releases a token, (2) the token +// expires, (3) the Context passed to .DeviceCode() is cancelled or expires, (4) some other service +// error occurs. +func (d DeviceCode) Token(ctx context.Context) (accesstokens.TokenResponse, error) { + if d.accessTokens == nil { + return accesstokens.TokenResponse{}, fmt.Errorf("DeviceCode was either created outside its package or the creating method had an error. DeviceCode is not valid") + } + + var cancel context.CancelFunc + if deadline, ok := ctx.Deadline(); !ok || d.Result.ExpiresOn.Before(deadline) { + ctx, cancel = context.WithDeadline(ctx, d.Result.ExpiresOn) + } else { + ctx, cancel = context.WithCancel(ctx) + } + defer cancel() + + var interval = 50 * time.Millisecond + timer := time.NewTimer(interval) + defer timer.Stop() + + for { + timer.Reset(interval) + select { + case <-ctx.Done(): + return accesstokens.TokenResponse{}, ctx.Err() + case <-timer.C: + interval += interval * 2 + if interval > 5*time.Second { + interval = 5 * time.Second + } + } + + token, err := d.accessTokens.FromDeviceCodeResult(ctx, d.authParams, d.Result) + if err != nil && isWaitDeviceCodeErr(err) { + continue + } + return token, err // This handles if it was a non-wait error or success + } +} + +type deviceCodeError struct { + Error string `json:"error"` +} + +func isWaitDeviceCodeErr(err error) bool { + var c errors.CallErr + if !errors.As(err, &c) { + return false + } + if c.Resp.StatusCode != 400 { + return false + } + var dCErr deviceCodeError + defer c.Resp.Body.Close() + body, err := io.ReadAll(c.Resp.Body) + if err != nil { + return false + } + err = json.Unmarshal(body, &dCErr) + if err != nil { + return false + } + if dCErr.Error == "authorization_pending" || dCErr.Error == "slow_down" { + return true + } + return false +} + +// DeviceCode returns a DeviceCode object that can be used to get the code that must be entered on the second +// device and optionally the token once the code has been entered on the second device. +func (t *Client) DeviceCode(ctx context.Context, authParams authority.AuthParams) (DeviceCode, error) { + if err := scopeError(authParams); err != nil { + return DeviceCode{}, err + } + + if err := t.resolveEndpoint(ctx, &authParams, ""); err != nil { + return DeviceCode{}, err + } + + dcr, err := t.AccessTokens.DeviceCodeResult(ctx, authParams) + if err != nil { + return DeviceCode{}, err + } + + return DeviceCode{Result: dcr, authParams: authParams, accessTokens: t.AccessTokens}, nil +} + +func (t *Client) resolveEndpoint(ctx context.Context, authParams *authority.AuthParams, userPrincipalName string) error { + endpoints, err := t.Resolver.ResolveEndpoints(ctx, authParams.AuthorityInfo, userPrincipalName) + if err != nil { + return fmt.Errorf("unable to resolve an endpoint: %w", err) + } + authParams.Endpoints = endpoints + return nil +} + +// scopeError takes an authority.AuthParams and returns an error +// if len(AuthParams.Scope) == 0. +func scopeError(a authority.AuthParams) error { + // TODO(someone): we could look deeper at the message to determine if + // it's a scope error, but this is a good start. + /* + {error":"invalid_scope","error_description":"AADSTS1002012: The provided value for scope + openid offline_access profile is not valid. Client credential flows must have a scope value + with /.default suffixed to the resource identifier (application ID URI)...} + */ + if len(a.Scopes) == 0 { + return fmt.Errorf("token request had an empty authority.AuthParams.Scopes, which is invalid") + } + return nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/accesstokens.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/accesstokens.go new file mode 100644 index 000000000..d738c7591 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/accesstokens.go @@ -0,0 +1,468 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package accesstokens exposes a REST client for querying backend systems to get various types of +access tokens (oauth) for use in authentication. + +These calls are of type "application/x-www-form-urlencoded". This means we use url.Values to +represent arguments and then encode them into the POST body message. We receive JSON in +return for the requests. The request definition is defined in https://tools.ietf.org/html/rfc7521#section-4.2 . +*/ +package accesstokens + +import ( + "context" + "crypto" + + /* #nosec */ + "crypto/sha1" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/json" + "fmt" + "net/url" + "strconv" + "strings" + "time" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust" + "github.com/golang-jwt/jwt/v5" + "github.com/google/uuid" +) + +const ( + grantType = "grant_type" + deviceCode = "device_code" + clientID = "client_id" + clientInfo = "client_info" + clientInfoVal = "1" + username = "username" + password = "password" +) + +//go:generate stringer -type=AppType + +// AppType is whether the authorization code flow is for a public or confidential client. +type AppType int8 + +const ( + // ATUnknown is the zero value when the type hasn't been set. + ATUnknown AppType = iota + // ATPublic indicates this if for the Public.Client. + ATPublic + // ATConfidential indicates this if for the Confidential.Client. + ATConfidential +) + +type urlFormCaller interface { + URLFormCall(ctx context.Context, endpoint string, qv url.Values, resp interface{}) error +} + +// DeviceCodeResponse represents the HTTP response received from the device code endpoint +type DeviceCodeResponse struct { + authority.OAuthResponseBase + + UserCode string `json:"user_code"` + DeviceCode string `json:"device_code"` + VerificationURL string `json:"verification_uri"` + ExpiresIn int `json:"expires_in"` + Interval int `json:"interval"` + Message string `json:"message"` + + AdditionalFields map[string]interface{} +} + +// Convert converts the DeviceCodeResponse to a DeviceCodeResult +func (dcr DeviceCodeResponse) Convert(clientID string, scopes []string) DeviceCodeResult { + expiresOn := time.Now().UTC().Add(time.Duration(dcr.ExpiresIn) * time.Second) + return NewDeviceCodeResult(dcr.UserCode, dcr.DeviceCode, dcr.VerificationURL, expiresOn, dcr.Interval, dcr.Message, clientID, scopes) +} + +// Credential represents the credential used in confidential client flows. This can be either +// a Secret or Cert/Key. +type Credential struct { + // Secret contains the credential secret if we are doing auth by secret. + Secret string + + // Cert is the public certificate, if we're authenticating by certificate. + Cert *x509.Certificate + // Key is the private key for signing, if we're authenticating by certificate. + Key crypto.PrivateKey + // X5c is the JWT assertion's x5c header value, required for SN/I authentication. + X5c []string + + // AssertionCallback is a function provided by the application, if we're authenticating by assertion. + AssertionCallback func(context.Context, exported.AssertionRequestOptions) (string, error) + + // TokenProvider is a function provided by the application that implements custom authentication + // logic for a confidential client + TokenProvider func(context.Context, exported.TokenProviderParameters) (exported.TokenProviderResult, error) +} + +// JWT gets the jwt assertion when the credential is not using a secret. +func (c *Credential) JWT(ctx context.Context, authParams authority.AuthParams) (string, error) { + if c.AssertionCallback != nil { + options := exported.AssertionRequestOptions{ + ClientID: authParams.ClientID, + TokenEndpoint: authParams.Endpoints.TokenEndpoint, + } + return c.AssertionCallback(ctx, options) + } + claims := jwt.MapClaims{ + "aud": authParams.Endpoints.TokenEndpoint, + "exp": json.Number(strconv.FormatInt(time.Now().Add(10*time.Minute).Unix(), 10)), + "iss": authParams.ClientID, + "jti": uuid.New().String(), + "nbf": json.Number(strconv.FormatInt(time.Now().Unix(), 10)), + "sub": authParams.ClientID, + } + + isADFSorDSTS := authParams.AuthorityInfo.AuthorityType == authority.ADFS || + authParams.AuthorityInfo.AuthorityType == authority.DSTS + + var signingMethod jwt.SigningMethod = jwt.SigningMethodPS256 + thumbprintKey := "x5t#S256" + + if isADFSorDSTS { + signingMethod = jwt.SigningMethodRS256 + thumbprintKey = "x5t" + } + + token := jwt.NewWithClaims(signingMethod, claims) + token.Header = map[string]interface{}{ + "alg": signingMethod.Alg(), + "typ": "JWT", + thumbprintKey: base64.StdEncoding.EncodeToString(thumbprint(c.Cert, signingMethod.Alg())), + } + + if authParams.SendX5C { + token.Header["x5c"] = c.X5c + } + + assertion, err := token.SignedString(c.Key) + if err != nil { + return "", fmt.Errorf("unable to sign JWT token: %w", err) + } + + return assertion, nil +} + +// thumbprint runs the asn1.Der bytes through sha1 for use in the x5t parameter of JWT. +// https://tools.ietf.org/html/rfc7517#section-4.8 +func thumbprint(cert *x509.Certificate, alg string) []byte { + switch alg { + case jwt.SigningMethodRS256.Name: // identity providers like ADFS don't support SHA256 assertions, so need to support this + hash := sha1.Sum(cert.Raw) /* #nosec */ + return hash[:] + default: + hash := sha256.Sum256(cert.Raw) + return hash[:] + } +} + +// Client represents the REST calls to get tokens from token generator backends. +type Client struct { + // Comm provides the HTTP transport client. + Comm urlFormCaller + + testing bool +} + +// FromUsernamePassword uses a username and password to get an access token. +func (c Client) FromUsernamePassword(ctx context.Context, authParameters authority.AuthParams) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.Password) + qv.Set(username, authParameters.Username) + qv.Set(password, authParameters.Password) + qv.Set(clientID, authParameters.ClientID) + qv.Set(clientInfo, clientInfoVal) + addScopeQueryParam(qv, authParameters) + + return c.doTokenResp(ctx, authParameters, qv) +} + +// AuthCodeRequest stores the values required to request a token from the authority using an authorization code +type AuthCodeRequest struct { + AuthParams authority.AuthParams + Code string + CodeChallenge string + Credential *Credential + AppType AppType +} + +// NewCodeChallengeRequest returns an AuthCodeRequest that uses a code challenge.. +func NewCodeChallengeRequest(params authority.AuthParams, appType AppType, cc *Credential, code, challenge string) (AuthCodeRequest, error) { + if appType == ATUnknown { + return AuthCodeRequest{}, fmt.Errorf("bug: NewCodeChallengeRequest() called with AppType == ATUnknown") + } + return AuthCodeRequest{ + AuthParams: params, + AppType: appType, + Code: code, + CodeChallenge: challenge, + Credential: cc, + }, nil +} + +// FromAuthCode uses an authorization code to retrieve an access token. +func (c Client) FromAuthCode(ctx context.Context, req AuthCodeRequest) (TokenResponse, error) { + var qv url.Values + + switch req.AppType { + case ATUnknown: + return TokenResponse{}, fmt.Errorf("bug: Token.AuthCode() received request with AppType == ATUnknown") + case ATConfidential: + var err error + if req.Credential == nil { + return TokenResponse{}, fmt.Errorf("AuthCodeRequest had nil Credential for Confidential app") + } + qv, err = prepURLVals(ctx, req.Credential, req.AuthParams) + if err != nil { + return TokenResponse{}, err + } + case ATPublic: + qv = url.Values{} + default: + return TokenResponse{}, fmt.Errorf("bug: Token.AuthCode() received request with AppType == %v, which we do not recongnize", req.AppType) + } + + qv.Set(grantType, grant.AuthCode) + qv.Set("code", req.Code) + qv.Set("code_verifier", req.CodeChallenge) + qv.Set("redirect_uri", req.AuthParams.Redirecturi) + qv.Set(clientID, req.AuthParams.ClientID) + qv.Set(clientInfo, clientInfoVal) + addScopeQueryParam(qv, req.AuthParams) + if err := addClaims(qv, req.AuthParams); err != nil { + return TokenResponse{}, err + } + + return c.doTokenResp(ctx, req.AuthParams, qv) +} + +// FromRefreshToken uses a refresh token (for refreshing credentials) to get a new access token. +func (c Client) FromRefreshToken(ctx context.Context, appType AppType, authParams authority.AuthParams, cc *Credential, refreshToken string) (TokenResponse, error) { + qv := url.Values{} + if appType == ATConfidential { + var err error + qv, err = prepURLVals(ctx, cc, authParams) + if err != nil { + return TokenResponse{}, err + } + } + if err := addClaims(qv, authParams); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.RefreshToken) + qv.Set(clientID, authParams.ClientID) + qv.Set(clientInfo, clientInfoVal) + qv.Set("refresh_token", refreshToken) + addScopeQueryParam(qv, authParams) + + return c.doTokenResp(ctx, authParams, qv) +} + +// FromClientSecret uses a client's secret (aka password) to get a new token. +func (c Client) FromClientSecret(ctx context.Context, authParameters authority.AuthParams, clientSecret string) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.ClientCredential) + qv.Set("client_secret", clientSecret) + qv.Set(clientID, authParameters.ClientID) + addScopeQueryParam(qv, authParameters) + + return c.doTokenResp(ctx, authParameters, qv) +} + +func (c Client) FromAssertion(ctx context.Context, authParameters authority.AuthParams, assertion string) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.ClientCredential) + qv.Set("client_assertion_type", grant.ClientAssertion) + qv.Set("client_assertion", assertion) + qv.Set(clientID, authParameters.ClientID) + qv.Set(clientInfo, clientInfoVal) + addScopeQueryParam(qv, authParameters) + + return c.doTokenResp(ctx, authParameters, qv) +} + +func (c Client) FromUserAssertionClientSecret(ctx context.Context, authParameters authority.AuthParams, userAssertion string, clientSecret string) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.JWT) + qv.Set(clientID, authParameters.ClientID) + qv.Set("client_secret", clientSecret) + qv.Set("assertion", userAssertion) + qv.Set(clientInfo, clientInfoVal) + qv.Set("requested_token_use", "on_behalf_of") + addScopeQueryParam(qv, authParameters) + + return c.doTokenResp(ctx, authParameters, qv) +} + +func (c Client) FromUserAssertionClientCertificate(ctx context.Context, authParameters authority.AuthParams, userAssertion string, assertion string) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.JWT) + qv.Set("client_assertion_type", grant.ClientAssertion) + qv.Set("client_assertion", assertion) + qv.Set(clientID, authParameters.ClientID) + qv.Set("assertion", userAssertion) + qv.Set(clientInfo, clientInfoVal) + qv.Set("requested_token_use", "on_behalf_of") + addScopeQueryParam(qv, authParameters) + + return c.doTokenResp(ctx, authParameters, qv) +} + +func (c Client) DeviceCodeResult(ctx context.Context, authParameters authority.AuthParams) (DeviceCodeResult, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return DeviceCodeResult{}, err + } + qv.Set(clientID, authParameters.ClientID) + addScopeQueryParam(qv, authParameters) + + endpoint := strings.Replace(authParameters.Endpoints.TokenEndpoint, "token", "devicecode", -1) + + resp := DeviceCodeResponse{} + err := c.Comm.URLFormCall(ctx, endpoint, qv, &resp) + if err != nil { + return DeviceCodeResult{}, err + } + + return resp.Convert(authParameters.ClientID, authParameters.Scopes), nil +} + +func (c Client) FromDeviceCodeResult(ctx context.Context, authParameters authority.AuthParams, deviceCodeResult DeviceCodeResult) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(grantType, grant.DeviceCode) + qv.Set(deviceCode, deviceCodeResult.DeviceCode) + qv.Set(clientID, authParameters.ClientID) + qv.Set(clientInfo, clientInfoVal) + addScopeQueryParam(qv, authParameters) + + return c.doTokenResp(ctx, authParameters, qv) +} + +func (c Client) FromSamlGrant(ctx context.Context, authParameters authority.AuthParams, samlGrant wstrust.SamlTokenInfo) (TokenResponse, error) { + qv := url.Values{} + if err := addClaims(qv, authParameters); err != nil { + return TokenResponse{}, err + } + qv.Set(username, authParameters.Username) + qv.Set(password, authParameters.Password) + qv.Set(clientID, authParameters.ClientID) + qv.Set(clientInfo, clientInfoVal) + qv.Set("assertion", base64.StdEncoding.WithPadding(base64.StdPadding).EncodeToString([]byte(samlGrant.Assertion))) + addScopeQueryParam(qv, authParameters) + + switch samlGrant.AssertionType { + case grant.SAMLV1: + qv.Set(grantType, grant.SAMLV1) + case grant.SAMLV2: + qv.Set(grantType, grant.SAMLV2) + default: + return TokenResponse{}, fmt.Errorf("GetAccessTokenFromSamlGrant returned unknown SAML assertion type: %q", samlGrant.AssertionType) + } + + return c.doTokenResp(ctx, authParameters, qv) +} + +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 + } + resp.ComputeScope(authParams) + if c.testing { + return resp, nil + } + return resp, resp.Validate() +} + +// prepURLVals returns an url.Values that sets various key/values if we are doing secrets +// or JWT assertions. +func prepURLVals(ctx context.Context, cc *Credential, authParams authority.AuthParams) (url.Values, error) { + params := url.Values{} + if cc.Secret != "" { + params.Set("client_secret", cc.Secret) + return params, nil + } + + jwt, err := cc.JWT(ctx, authParams) + if err != nil { + return nil, err + } + params.Set("client_assertion", jwt) + params.Set("client_assertion_type", grant.ClientAssertion) + return params, nil +} + +// openid required to get an id token +// offline_access required to get a refresh token +// profile required to get the client_info field back +var detectDefaultScopes = map[string]bool{ + "openid": true, + "offline_access": true, + "profile": true, +} + +var defaultScopes = []string{"openid", "offline_access", "profile"} + +func AppendDefaultScopes(authParameters authority.AuthParams) []string { + scopes := make([]string, 0, len(authParameters.Scopes)+len(defaultScopes)) + for _, scope := range authParameters.Scopes { + s := strings.TrimSpace(scope) + if s == "" { + continue + } + if detectDefaultScopes[scope] { + continue + } + scopes = append(scopes, scope) + } + scopes = append(scopes, defaultScopes...) + return scopes +} + +// addClaims adds client capabilities and claims from AuthParams to the given url.Values +func addClaims(v url.Values, ap authority.AuthParams) error { + claims, err := ap.MergeCapabilitiesAndClaims() + if err == nil && claims != "" { + v.Set("claims", claims) + } + return err +} + +func addScopeQueryParam(queryParams url.Values, authParameters authority.AuthParams) { + scopes := AppendDefaultScopes(authParameters) + queryParams.Set("scope", strings.Join(scopes, " ")) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/apptype_string.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/apptype_string.go new file mode 100644 index 000000000..3bec4a67c --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/apptype_string.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -type=AppType"; DO NOT EDIT. + +package accesstokens + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ATUnknown-0] + _ = x[ATPublic-1] + _ = x[ATConfidential-2] +} + +const _AppType_name = "ATUnknownATPublicATConfidential" + +var _AppType_index = [...]uint8{0, 9, 17, 31} + +func (i AppType) String() string { + if i < 0 || i >= AppType(len(_AppType_index)-1) { + return "AppType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _AppType_name[_AppType_index[i]:_AppType_index[i+1]] +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/tokens.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/tokens.go new file mode 100644 index 000000000..32dde7b76 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens/tokens.go @@ -0,0 +1,401 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package accesstokens + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "time" + + 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/authority" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared" +) + +// IDToken consists of all the information used to validate a user. +// https://docs.microsoft.com/azure/active-directory/develop/id-tokens . +type IDToken struct { + PreferredUsername string `json:"preferred_username,omitempty"` + GivenName string `json:"given_name,omitempty"` + FamilyName string `json:"family_name,omitempty"` + MiddleName string `json:"middle_name,omitempty"` + Name string `json:"name,omitempty"` + Oid string `json:"oid,omitempty"` + TenantID string `json:"tid,omitempty"` + Subject string `json:"sub,omitempty"` + UPN string `json:"upn,omitempty"` + Email string `json:"email,omitempty"` + AlternativeID string `json:"alternative_id,omitempty"` + Issuer string `json:"iss,omitempty"` + Audience string `json:"aud,omitempty"` + ExpirationTime int64 `json:"exp,omitempty"` + IssuedAt int64 `json:"iat,omitempty"` + NotBefore int64 `json:"nbf,omitempty"` + RawToken string + + AdditionalFields map[string]interface{} +} + +var null = []byte("null") + +// UnmarshalJSON implements json.Unmarshaler. +func (i *IDToken) UnmarshalJSON(b []byte) error { + if bytes.Equal(null, b) { + return nil + } + + // Because we have a custom unmarshaler, you + // cannot directly call json.Unmarshal here. If you do, it will call this function + // recursively until reach our recursion limit. We have to create a new type + // that doesn't have this method in order to use json.Unmarshal. + type idToken2 IDToken + + jwt := strings.Trim(string(b), `"`) + jwtArr := strings.Split(jwt, ".") + if len(jwtArr) < 2 { + return errors.New("IDToken returned from server is invalid") + } + + jwtPart := jwtArr[1] + jwtDecoded, err := decodeJWT(jwtPart) + if err != nil { + return fmt.Errorf("unable to unmarshal IDToken, problem decoding JWT: %w", err) + } + + token := idToken2{} + err = json.Unmarshal(jwtDecoded, &token) + if err != nil { + return fmt.Errorf("unable to unmarshal IDToken: %w", err) + } + token.RawToken = jwt + + *i = IDToken(token) + return nil +} + +// IsZero indicates if the IDToken is the zero value. +func (i IDToken) IsZero() bool { + v := reflect.ValueOf(i) + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + if !field.IsZero() { + switch field.Kind() { + case reflect.Map, reflect.Slice: + if field.Len() == 0 { + continue + } + } + return false + } + } + return true +} + +// LocalAccountID extracts an account's local account ID from an ID token. +func (i IDToken) LocalAccountID() string { + if i.Oid != "" { + return i.Oid + } + return i.Subject +} + +// jwtDecoder is provided to allow tests to provide their own. +var jwtDecoder = decodeJWT + +// ClientInfo is used to create a Home Account ID for an account. +type ClientInfo struct { + UID string `json:"uid"` + UTID string `json:"utid"` + + AdditionalFields map[string]interface{} +} + +// UnmarshalJSON implements json.Unmarshaler.s +func (c *ClientInfo) UnmarshalJSON(b []byte) error { + s := strings.Trim(string(b), `"`) + // Client info may be empty in some flows, e.g. certificate exchange. + if len(s) == 0 { + return nil + } + + // Because we have a custom unmarshaler, you + // cannot directly call json.Unmarshal here. If you do, it will call this function + // recursively until reach our recursion limit. We have to create a new type + // that doesn't have this method in order to use json.Unmarshal. + type clientInfo2 ClientInfo + + raw, err := jwtDecoder(s) + if err != nil { + return fmt.Errorf("TokenResponse client_info field had JWT decode error: %w", err) + } + + var c2 clientInfo2 + + err = json.Unmarshal(raw, &c2) + if err != nil { + return fmt.Errorf("was unable to unmarshal decoded JWT in TokenRespone to ClientInfo: %w", err) + } + + *c = ClientInfo(c2) + return nil +} + +// Scopes represents scopes in a TokenResponse. +type Scopes struct { + Slice []string +} + +// UnmarshalJSON implements json.Unmarshal. +func (s *Scopes) UnmarshalJSON(b []byte) error { + str := strings.Trim(string(b), `"`) + if len(str) == 0 { + return nil + } + sl := strings.Split(str, " ") + s.Slice = sl + return nil +} + +// TokenResponse is the information that is returned from a token endpoint during a token acquisition flow. +type TokenResponse struct { + authority.OAuthResponseBase + + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + TokenType string `json:"token_type"` + + FamilyID string `json:"foci"` + IDToken IDToken `json:"id_token"` + ClientInfo ClientInfo `json:"client_info"` + RefreshOn internalTime.DurationTime `json:"refresh_in,omitempty"` + ExpiresOn time.Time `json:"-"` + ExtExpiresOn internalTime.DurationTime `json:"ext_expires_in"` + GrantedScopes Scopes `json:"scope"` + DeclinedScopes []string // This is derived + + AdditionalFields map[string]interface{} + scopesComputed bool +} + +func (tr *TokenResponse) UnmarshalJSON(data []byte) error { + type Alias TokenResponse + aux := &struct { + ExpiresIn internalTime.DurationTime `json:"expires_in,omitempty"` + ExpiresOn any `json:"expires_on,omitempty"` + *Alias + }{ + Alias: (*Alias)(tr), + } + + // Unmarshal the JSON data into the aux struct + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + // Function to parse different date formats + // This is a workaround for the issue described here: + // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/4963 + parseExpiresOn := func(expiresOn string) (time.Time, error) { + var formats = []string{ + "01/02/2006 15:04:05", // MM/dd/yyyy HH:mm:ss + "2006-01-02 15:04:05", // yyyy-MM-dd HH:mm:ss + time.RFC3339Nano, // ISO 8601 (with nanosecond precision) + } + + for _, format := range formats { + if t, err := time.Parse(format, expiresOn); err == nil { + return t, nil + } + } + return time.Time{}, fmt.Errorf("invalid ExpiresOn format: %s", expiresOn) + } + + if expiresOnStr, ok := aux.ExpiresOn.(string); ok { + if ts, err := strconv.ParseInt(expiresOnStr, 10, 64); err == nil { + tr.ExpiresOn = time.Unix(ts, 0) + return nil + } + if expiresOnStr != "" { + if t, err := parseExpiresOn(expiresOnStr); err != nil { + return err + } else { + tr.ExpiresOn = t + return nil + } + } + } + + // Check if ExpiresOn is a number (Unix timestamp or ISO 8601) + if expiresOnNum, ok := aux.ExpiresOn.(float64); ok { + tr.ExpiresOn = time.Unix(int64(expiresOnNum), 0) + return nil + } + + if !aux.ExpiresIn.T.IsZero() { + tr.ExpiresOn = aux.ExpiresIn.T + return nil + } + return errors.New("expires_in and expires_on are both missing or invalid") +} + +// ComputeScope computes the final scopes based on what was granted by the server and +// what our AuthParams were from the authority server. Per OAuth spec, if no scopes are returned, the response should be treated as if all scopes were granted +// This behavior can be observed in client assertion flows, but can happen at any time, this check ensures we treat +// those special responses properly Link to spec: https://tools.ietf.org/html/rfc6749#section-3.3 +func (tr *TokenResponse) ComputeScope(authParams authority.AuthParams) { + if len(tr.GrantedScopes.Slice) == 0 { + tr.GrantedScopes = Scopes{Slice: authParams.Scopes} + } else { + tr.DeclinedScopes = findDeclinedScopes(authParams.Scopes, tr.GrantedScopes.Slice) + } + tr.scopesComputed = true +} + +// HomeAccountID uniquely identifies the authenticated account, if any. It's "" when the token is an app token. +func (tr *TokenResponse) HomeAccountID() string { + id := tr.IDToken.Subject + if uid := tr.ClientInfo.UID; uid != "" { + utid := tr.ClientInfo.UTID + if utid == "" { + utid = uid + } + id = fmt.Sprintf("%s.%s", uid, utid) + } + return id +} + +// Validate validates the TokenResponse has basic valid values. It must be called +// after ComputeScopes() is called. +func (tr *TokenResponse) Validate() error { + if tr.Error != "" { + return fmt.Errorf("%s: %s", tr.Error, tr.ErrorDescription) + } + + if tr.AccessToken == "" { + return errors.New("response is missing access_token") + } + + if !tr.scopesComputed { + return fmt.Errorf("TokenResponse hasn't had ScopesComputed() called") + } + return nil +} + +func (tr *TokenResponse) CacheKey(authParams authority.AuthParams) string { + if authParams.AuthorizationType == authority.ATOnBehalfOf { + return authParams.AssertionHash() + } + if authParams.AuthorizationType == authority.ATClientCredentials { + return authParams.AppKey() + } + if authParams.IsConfidentialClient || authParams.AuthorizationType == authority.ATRefreshToken { + return tr.HomeAccountID() + } + return "" +} + +func findDeclinedScopes(requestedScopes []string, grantedScopes []string) []string { + declined := []string{} + grantedMap := map[string]bool{} + for _, s := range grantedScopes { + grantedMap[strings.ToLower(s)] = true + } + // Comparing the requested scopes with the granted scopes to see if there are any scopes that have been declined. + for _, r := range requestedScopes { + if !grantedMap[strings.ToLower(r)] { + declined = append(declined, r) + } + } + return declined +} + +// decodeJWT decodes a JWT and converts it to a byte array representing a JSON object +// JWT has headers and payload base64url encoded without padding +// https://tools.ietf.org/html/rfc7519#section-3 and +// https://tools.ietf.org/html/rfc7515#section-2 +func decodeJWT(data string) ([]byte, error) { + // https://tools.ietf.org/html/rfc7515#appendix-C + return base64.RawURLEncoding.DecodeString(data) +} + +// RefreshToken is the JSON representation of a MSAL refresh token for encoding to storage. +type RefreshToken struct { + HomeAccountID string `json:"home_account_id,omitempty"` + Environment string `json:"environment,omitempty"` + CredentialType string `json:"credential_type,omitempty"` + ClientID string `json:"client_id,omitempty"` + FamilyID string `json:"family_id,omitempty"` + Secret string `json:"secret,omitempty"` + Realm string `json:"realm,omitempty"` + Target string `json:"target,omitempty"` + UserAssertionHash string `json:"user_assertion_hash,omitempty"` + + AdditionalFields map[string]interface{} +} + +// NewRefreshToken is the constructor for RefreshToken. +func NewRefreshToken(homeID, env, clientID, refreshToken, familyID string) RefreshToken { + return RefreshToken{ + HomeAccountID: homeID, + Environment: env, + CredentialType: "RefreshToken", + ClientID: clientID, + FamilyID: familyID, + Secret: refreshToken, + } +} + +// Key outputs the key that can be used to uniquely look up this entry in a map. +func (rt RefreshToken) Key() string { + var fourth = rt.FamilyID + if fourth == "" { + fourth = rt.ClientID + } + + key := strings.Join( + []string{rt.HomeAccountID, rt.Environment, rt.CredentialType, fourth}, + shared.CacheKeySeparator, + ) + return strings.ToLower(key) +} + +func (rt RefreshToken) GetSecret() string { + return rt.Secret +} + +// DeviceCodeResult stores the response from the STS device code endpoint. +type DeviceCodeResult struct { + // UserCode is the code the user needs to provide when authentication at the verification URI. + UserCode string + // DeviceCode is the code used in the access token request. + DeviceCode string + // VerificationURL is the the URL where user can authenticate. + VerificationURL string + // ExpiresOn is the expiration time of device code in seconds. + ExpiresOn time.Time + // Interval is the interval at which the STS should be polled at. + Interval int + // Message is the message which should be displayed to the user. + Message string + // ClientID is the UUID issued by the authorization server for your application. + ClientID string + // Scopes is the OpenID scopes used to request access a protected API. + Scopes []string +} + +// NewDeviceCodeResult creates a DeviceCodeResult instance. +func NewDeviceCodeResult(userCode, deviceCode, verificationURL string, expiresOn time.Time, interval int, message, clientID string, scopes []string) DeviceCodeResult { + return DeviceCodeResult{userCode, deviceCode, verificationURL, expiresOn, interval, message, clientID, scopes} +} + +func (dcr DeviceCodeResult) String() string { + return fmt.Sprintf("UserCode: (%v)\nDeviceCode: (%v)\nURL: (%v)\nMessage: (%v)\n", dcr.UserCode, dcr.DeviceCode, dcr.VerificationURL, dcr.Message) + +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go new file mode 100644 index 000000000..3f4037464 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authority.go @@ -0,0 +1,649 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package authority + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path" + "strings" + "time" + + "github.com/google/uuid" +) + +const ( + authorizationEndpoint = "https://%v/%v/oauth2/v2.0/authorize" + aadInstanceDiscoveryEndpoint = "https://%v/common/discovery/instance" + tenantDiscoveryEndpointWithRegion = "https://%s.%s/%s/v2.0/.well-known/openid-configuration" + regionName = "REGION_NAME" + 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. +const ( + defaultHost = "login.microsoftonline.com" + loginMicrosoft = "login.microsoft.com" + loginWindows = "login.windows.net" + loginSTSWindows = "sts.windows.net" + loginMicrosoftOnline = defaultHost +) + +// jsonCaller is an interface that allows us to mock the JSONCall method. +type jsonCaller interface { + JSONCall(ctx context.Context, endpoint string, headers http.Header, qv url.Values, body, resp interface{}) error +} + +// For backward compatibility, accept both old and new China endpoints for a transition period. +var aadTrustedHostList = map[string]bool{ + "login.windows.net": true, // Microsoft Azure Worldwide - Used in validation scenarios where host is not this list + "login.partner.microsoftonline.cn": true, // Microsoft Azure China (new) + "login.chinacloudapi.cn": true, // Microsoft Azure China (legacy, backward compatibility) + "login.microsoftonline.de": true, // Microsoft Azure Blackforest + "login-us.microsoftonline.com": true, // Microsoft Azure US Government - Legacy + "login.microsoftonline.us": true, // Microsoft Azure US Government + "login.microsoftonline.com": true, // Microsoft Azure Worldwide +} + +// TrustedHost checks if an AAD host is trusted/valid. +func TrustedHost(host string) bool { + if _, ok := aadTrustedHostList[host]; ok { + return true + } + return false +} + +// OAuthResponseBase is the base JSON return message for an OAuth call. +// This is embedded in other calls to get the base fields from every response. +type OAuthResponseBase struct { + Error string `json:"error"` + SubError string `json:"suberror"` + ErrorDescription string `json:"error_description"` + ErrorCodes []int `json:"error_codes"` + CorrelationID string `json:"correlation_id"` + Claims string `json:"claims"` +} + +// TenantDiscoveryResponse is the tenant endpoints from the OpenID configuration endpoint. +type TenantDiscoveryResponse struct { + OAuthResponseBase + + AuthorizationEndpoint string `json:"authorization_endpoint"` + TokenEndpoint string `json:"token_endpoint"` + Issuer string `json:"issuer"` + + AdditionalFields map[string]interface{} +} + +// Validate validates that the response had the correct values required. +func (r *TenantDiscoveryResponse) Validate() error { + switch "" { + case r.AuthorizationEndpoint: + return errors.New("TenantDiscoveryResponse: authorize endpoint was not found in the openid configuration") + case r.TokenEndpoint: + return errors.New("TenantDiscoveryResponse: token endpoint was not found in the openid configuration") + case r.Issuer: + return errors.New("TenantDiscoveryResponse: issuer was not found in the openid configuration") + } + return nil +} + +// ValidateIssuerMatchesAuthority validates that the issuer in the TenantDiscoveryResponse matches the authority. +// This is used to identity security or configuration issues in authorities and the OIDC endpoint +func (r *TenantDiscoveryResponse) ValidateIssuerMatchesAuthority(authorityURI string, aliases map[string]bool) error { + + if authorityURI == "" { + return errors.New("TenantDiscoveryResponse: empty authorityURI provided for validation") + } + + // Parse the issuer URL + issuerURL, err := url.Parse(r.Issuer) + if err != nil { + return fmt.Errorf("TenantDiscoveryResponse: failed to parse issuer URL: %w", err) + } + + // Even if it doesn't match the authority, issuers from known and trusted hosts are valid + if aliases != nil && aliases[issuerURL.Host] { + return nil + } + + // Parse the authority URL for comparison + authorityURL, err := url.Parse(authorityURI) + if err != nil { + return fmt.Errorf("TenantDiscoveryResponse: failed to parse authority URL: %w", err) + } + + // Check if the scheme and host match (paths can be ignored when validating the issuer) + if issuerURL.Scheme == authorityURL.Scheme && issuerURL.Host == authorityURL.Host { + return nil + } + + // If we get here, validation failed + return fmt.Errorf("TenantDiscoveryResponse: issuer from OIDC discovery '%s' does not match authority '%s' or a known pattern", + r.Issuer, authorityURI) +} + +type InstanceDiscoveryMetadata struct { + PreferredNetwork string `json:"preferred_network"` + PreferredCache string `json:"preferred_cache"` + Aliases []string `json:"aliases"` + + AdditionalFields map[string]interface{} +} + +type InstanceDiscoveryResponse struct { + TenantDiscoveryEndpoint string `json:"tenant_discovery_endpoint"` + Metadata []InstanceDiscoveryMetadata `json:"metadata"` + + AdditionalFields map[string]interface{} +} + +//go:generate stringer -type=AuthorizeType + +// AuthorizeType represents the type of token flow. +type AuthorizeType int + +// These are all the types of token flows. +const ( + ATUnknown AuthorizeType = iota + ATUsernamePassword + ATWindowsIntegrated + ATAuthCode + ATInteractive + ATClientCredentials + ATDeviceCode + ATRefreshToken + AccountByID + ATOnBehalfOf +) + +// These are all authority types +const ( + AAD = "MSSTS" + ADFS = "ADFS" + DSTS = "DSTS" +) + +// DSTSTenant is referenced throughout multiple files, let us use a const in case we ever need to change it. +const DSTSTenant = "7a433bfc-2514-4697-b467-e0933190487f" + +// 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 + CorrelationID string + Endpoints Endpoints + ClientID string + // Redirecturi is used for auth flows that specify a redirect URI (e.g. local server for interactive auth flow). + Redirecturi string + HomeAccountID string + // Username is the user-name portion for username/password auth flow. + Username string + // Password is the password portion for username/password auth flow. + Password string + // Scopes is the list of scopes the user consents to. + Scopes []string + // AuthorizationType specifies the auth flow being used. + AuthorizationType AuthorizeType + // State is a random value used to prevent cross-site request forgery attacks. + State string + // CodeChallenge is derived from a code verifier and is sent in the auth request. + CodeChallenge string + // CodeChallengeMethod describes the method used to create the CodeChallenge. + CodeChallengeMethod string + // Prompt specifies the user prompt type during interactive auth. + Prompt string + // IsConfidentialClient specifies if it is a confidential client. + IsConfidentialClient bool + // SendX5C specifies if x5c claim(public key of the certificate) should be sent to STS. + SendX5C bool + // UserAssertion is the access token used to acquire token on behalf of user + UserAssertion string + // Capabilities the client will include with each token request, for example "CP1". + // Call [NewClientCapabilities] to construct a value for this field. + Capabilities ClientCapabilities + // Claims required for an access token to satisfy a conditional access policy + Claims string + // KnownAuthorityHosts don't require metadata discovery because they're known to the user + KnownAuthorityHosts []string + // LoginHint is a username with which to pre-populate account selection during interactive auth + 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. +func NewAuthParams(clientID string, authorityInfo Info) AuthParams { + return AuthParams{ + ClientID: clientID, + AuthorityInfo: authorityInfo, + CorrelationID: uuid.New().String(), + AuthnScheme: &bearerAuthnScheme, + } +} + +// WithTenant returns a copy of the AuthParams having the specified tenant ID. If the given +// ID is empty, the copy is identical to the original. This function returns an error in +// several cases: +// - ID isn't specific (for example, it's "common") +// - ID is non-empty and the authority doesn't support tenants (for example, it's an ADFS authority) +// - the client is configured to authenticate only Microsoft accounts via the "consumers" endpoint +// - the resulting authority URL is invalid +func (p AuthParams) WithTenant(ID string) (AuthParams, error) { + if ID == "" || ID == p.AuthorityInfo.Tenant { + return p, nil + } + + var authority string + switch p.AuthorityInfo.AuthorityType { + case AAD: + if ID == "common" || ID == "consumers" || ID == "organizations" { + return p, fmt.Errorf(`tenant ID must be a specific tenant, not "%s"`, ID) + } + if p.AuthorityInfo.Tenant == "consumers" { + return p, errors.New(`client is configured to authenticate only personal Microsoft accounts, via the "consumers" endpoint`) + } + authority = "https://" + path.Join(p.AuthorityInfo.Host, ID) + case ADFS: + return p, errors.New("ADFS authority doesn't support tenants") + case DSTS: + return p, errors.New("dSTS authority doesn't support tenants") + } + + info, err := NewInfoFromAuthorityURI(authority, p.AuthorityInfo.ValidateAuthority, p.AuthorityInfo.InstanceDiscoveryDisabled) + if err == nil { + info.Region = p.AuthorityInfo.Region + p.AuthorityInfo = info + } + return p, err +} + +// MergeCapabilitiesAndClaims combines client capabilities and challenge claims into a value suitable for an authentication request's "claims" parameter. +func (p AuthParams) MergeCapabilitiesAndClaims() (string, error) { + claims := p.Claims + if len(p.Capabilities.asMap) > 0 { + if claims == "" { + // without claims the result is simply the capabilities + return p.Capabilities.asJSON, nil + } + // Otherwise, merge claims and capabilties into a single JSON object. + // We handle the claims challenge as a map because we don't know its structure. + var challenge map[string]any + if err := json.Unmarshal([]byte(claims), &challenge); err != nil { + return "", fmt.Errorf(`claims must be JSON. Are they base64 encoded? json.Unmarshal returned "%v"`, err) + } + if err := merge(p.Capabilities.asMap, challenge); err != nil { + return "", err + } + b, err := json.Marshal(challenge) + if err != nil { + return "", err + } + claims = string(b) + } + return claims, nil +} + +// merges a into b without overwriting b's values. Returns an error when a and b share a key for which either has a non-object value. +func merge(a, b map[string]any) error { + for k, av := range a { + if bv, ok := b[k]; !ok { + // b doesn't contain this key => simply set it to a's value + b[k] = av + } else { + // b does contain this key => recursively merge a[k] into b[k], provided both are maps. If a[k] or b[k] isn't + // a map, return an error because merging would overwrite some value in b. Errors shouldn't occur in practice + // because the challenge will be from AAD, which knows the capabilities format. + if A, ok := av.(map[string]any); ok { + if B, ok := bv.(map[string]any); ok { + return merge(A, B) + } else { + // b[k] isn't a map + return errors.New("challenge claims conflict with client capabilities") + } + } else { + // a[k] isn't a map + return errors.New("challenge claims conflict with client capabilities") + } + } + } + return nil +} + +// ClientCapabilities stores capabilities in the formats used by AuthParams.MergeCapabilitiesAndClaims. +// [NewClientCapabilities] precomputes these representations because capabilities are static for the +// lifetime of a client and are included with every authentication request i.e., these computations +// always have the same result and would otherwise have to be repeated for every request. +type ClientCapabilities struct { + // asJSON is for the common case: adding the capabilities to an auth request with no challenge claims + asJSON string + // asMap is for merging the capabilities with challenge claims + asMap map[string]any +} + +func NewClientCapabilities(capabilities []string) (ClientCapabilities, error) { + c := ClientCapabilities{} + var err error + if len(capabilities) > 0 { + cpbs := make([]string, len(capabilities)) + for i := 0; i < len(cpbs); i++ { + cpbs[i] = fmt.Sprintf(`"%s"`, capabilities[i]) + } + c.asJSON = fmt.Sprintf(`{"access_token":{"xms_cc":{"values":[%s]}}}`, strings.Join(cpbs, ",")) + // note our JSON is valid but we can't stop users breaking it with garbage like "}" + err = json.Unmarshal([]byte(c.asJSON), &c.asMap) + } + return c, err +} + +// Info consists of information about the authority. +type Info struct { + Host string + CanonicalAuthorityURI string + AuthorityType string + ValidateAuthority bool + Tenant string + Region string + InstanceDiscoveryDisabled bool + // InstanceDiscoveryMetadata stores the metadata from AAD instance discovery + InstanceDiscoveryMetadata []InstanceDiscoveryMetadata +} + +// NewInfoFromAuthorityURI creates an AuthorityInfo instance from the authority URL provided. +func NewInfoFromAuthorityURI(authority string, validateAuthority bool, instanceDiscoveryDisabled bool) (Info, error) { + + cannonicalAuthority := authority + + // suffix authority with / if it doesn't have one + if !strings.HasSuffix(cannonicalAuthority, "/") { + cannonicalAuthority += "/" + } + + u, err := url.Parse(strings.ToLower(cannonicalAuthority)) + + if err != nil { + return Info{}, fmt.Errorf("couldn't parse authority url: %w", err) + } + if u.Scheme != "https" { + return Info{}, errors.New("authority url scheme must be https") + } + + pathParts := strings.Split(u.EscapedPath(), "/") + if len(pathParts) < 3 { + return Info{}, errors.New(`authority must be an URL such as "https://login.microsoftonline.com/"`) + } + + authorityType := AAD + tenant := pathParts[1] + switch tenant { + case "adfs": + authorityType = ADFS + case "dstsv2": + if len(pathParts) != 4 { + return Info{}, fmt.Errorf("dSTS authority must be an https URL such as https:///dstsv2/%s", DSTSTenant) + } + if pathParts[2] != DSTSTenant { + return Info{}, fmt.Errorf("dSTS authority only accepts a single tenant %q", DSTSTenant) + } + authorityType = DSTS + tenant = DSTSTenant + } + + // u.Host includes the port, if any, which is required for private cloud deployments + return Info{ + Host: u.Host, + CanonicalAuthorityURI: cannonicalAuthority, + AuthorityType: authorityType, + ValidateAuthority: validateAuthority, + Tenant: tenant, + InstanceDiscoveryDisabled: instanceDiscoveryDisabled, + }, nil +} + +// Endpoints consists of the endpoints from the tenant discovery response. +type Endpoints struct { + AuthorizationEndpoint string + TokenEndpoint string + selfSignedJwtAudience string + authorityHost string +} + +// NewEndpoints creates an Endpoints object. +func NewEndpoints(authorizationEndpoint string, tokenEndpoint string, selfSignedJwtAudience string, authorityHost string) Endpoints { + return Endpoints{authorizationEndpoint, tokenEndpoint, selfSignedJwtAudience, authorityHost} +} + +// UserRealmAccountType refers to the type of user realm. +type UserRealmAccountType string + +// These are the different types of user realms. +const ( + Unknown UserRealmAccountType = "" + Federated UserRealmAccountType = "Federated" + Managed UserRealmAccountType = "Managed" +) + +// UserRealm is used for the username password request to determine user type +type UserRealm struct { + AccountType UserRealmAccountType `json:"account_type"` + DomainName string `json:"domain_name"` + CloudInstanceName string `json:"cloud_instance_name"` + CloudAudienceURN string `json:"cloud_audience_urn"` + + // required if accountType is Federated + FederationProtocol string `json:"federation_protocol"` + FederationMetadataURL string `json:"federation_metadata_url"` + + AdditionalFields map[string]interface{} +} + +func (u UserRealm) validate() error { + switch "" { + case string(u.AccountType): + return errors.New("the account type (Federated or Managed) is missing") + case u.DomainName: + return errors.New("domain name of user realm is missing") + case u.CloudInstanceName: + return errors.New("cloud instance name of user realm is missing") + case u.CloudAudienceURN: + return errors.New("cloud Instance URN is missing") + } + + if u.AccountType == Federated { + switch "" { + case u.FederationProtocol: + return errors.New("federation protocol of user realm is missing") + case u.FederationMetadataURL: + return errors.New("federation metadata URL of user realm is missing") + } + } + return nil +} + +// Client represents the REST calls to authority backends. +type Client struct { + // Comm provides the HTTP transport client. + Comm jsonCaller // *comm.Client +} + +func (c Client) UserRealm(ctx context.Context, authParams AuthParams) (UserRealm, error) { + endpoint := fmt.Sprintf("https://%s/common/UserRealm/%s", authParams.Endpoints.authorityHost, url.PathEscape(authParams.Username)) + qv := url.Values{ + "api-version": []string{"1.0"}, + } + + resp := UserRealm{} + err := c.Comm.JSONCall( + ctx, + endpoint, + http.Header{"client-request-id": []string{authParams.CorrelationID}}, + qv, + nil, + &resp, + ) + if err != nil { + return resp, err + } + + return resp, resp.validate() +} + +func (c Client) GetTenantDiscoveryResponse(ctx context.Context, openIDConfigurationEndpoint string) (TenantDiscoveryResponse, error) { + resp := TenantDiscoveryResponse{} + err := c.Comm.JSONCall( + ctx, + openIDConfigurationEndpoint, + http.Header{}, + nil, + nil, + &resp, + ) + + return resp, err +} + +// AADInstanceDiscovery attempts to discover a tenant endpoint (used in OIDC auth with an authorization endpoint). +// This is done by AAD which allows for aliasing of tenants (windows.sts.net is the same as login.windows.com). +func (c Client) AADInstanceDiscovery(ctx context.Context, authorityInfo Info) (InstanceDiscoveryResponse, error) { + region := "" + var err error + resp := InstanceDiscoveryResponse{} + if authorityInfo.Region != "" && authorityInfo.Region != autoDetectRegion { + region = authorityInfo.Region + } else if authorityInfo.Region == autoDetectRegion { + region = detectRegion(ctx) + } + if region != "" { + environment := authorityInfo.Host + switch environment { + case loginMicrosoft, loginWindows, loginSTSWindows, defaultHost: + environment = loginMicrosoft + } + + resp.TenantDiscoveryEndpoint = fmt.Sprintf(tenantDiscoveryEndpointWithRegion, region, environment, authorityInfo.Tenant) + metadata := InstanceDiscoveryMetadata{ + PreferredNetwork: fmt.Sprintf("%v.%v", region, authorityInfo.Host), + PreferredCache: authorityInfo.Host, + Aliases: []string{fmt.Sprintf("%v.%v", region, authorityInfo.Host), authorityInfo.Host}, + } + resp.Metadata = []InstanceDiscoveryMetadata{metadata} + } else { + qv := url.Values{} + qv.Set("api-version", "1.1") + qv.Set("authorization_endpoint", fmt.Sprintf(authorizationEndpoint, authorityInfo.Host, authorityInfo.Tenant)) + + discoveryHost := defaultHost + if TrustedHost(authorityInfo.Host) { + discoveryHost = authorityInfo.Host + } + + endpoint := fmt.Sprintf(aadInstanceDiscoveryEndpoint, discoveryHost) + err = c.Comm.JSONCall(ctx, endpoint, http.Header{}, qv, nil, &resp) + } + return resp, err +} + +func detectRegion(ctx context.Context) string { + region := os.Getenv(regionName) + if region != "" { + region = strings.ReplaceAll(region, " ", "") + return strings.ToLower(region) + } + // HTTP call to IMDS endpoint to get region + // Refer : https://identitydivision.visualstudio.com/DevEx/_git/AuthLibrariesApiReview?path=%2FPinAuthToRegion%2FAAD%20SDK%20Proposal%20to%20Pin%20Auth%20to%20region.md&_a=preview&version=GBdev + // Set a 2 second timeout for this http client which only does calls to IMDS endpoint + client := http.Client{ + Timeout: time.Duration(2 * time.Second), + } + req, _ := http.NewRequestWithContext(ctx, http.MethodGet, imdsEndpoint, nil) + req.Header.Set("Metadata", "true") + resp, err := client.Do(req) + if err == nil { + defer resp.Body.Close() + } + // If the request times out or there is an error, it is retried once + if err != nil || resp.StatusCode != http.StatusOK { + resp, err = client.Do(req) + if err != nil || resp.StatusCode != http.StatusOK { + return "" + } + } + response, err := io.ReadAll(resp.Body) + if err != nil { + return "" + } + return string(response) +} + +func (a *AuthParams) CacheKey(isAppCache bool) string { + if a.AuthorizationType == ATOnBehalfOf { + return a.AssertionHash() + } + if a.AuthorizationType == ATClientCredentials || isAppCache { + return a.AppKey() + } + if a.AuthorizationType == ATRefreshToken || a.AuthorizationType == AccountByID { + return a.HomeAccountID + } + return "" +} +func (a *AuthParams) AssertionHash() string { + hasher := sha256.New() + // Per documentation this never returns an error : https://pkg.go.dev/hash#pkg-types + _, _ = hasher.Write([]byte(a.UserAssertion)) + sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) + return sha +} + +func (a *AuthParams) AppKey() string { + if a.AuthorityInfo.Tenant != "" { + return fmt.Sprintf("%s_%s_AppTokenCache", a.ClientID, a.AuthorityInfo.Tenant) + } + return fmt.Sprintf("%s__AppTokenCache", a.ClientID) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authorizetype_string.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authorizetype_string.go new file mode 100644 index 000000000..10039773b --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority/authorizetype_string.go @@ -0,0 +1,30 @@ +// Code generated by "stringer -type=AuthorizeType"; DO NOT EDIT. + +package authority + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ATUnknown-0] + _ = x[ATUsernamePassword-1] + _ = x[ATWindowsIntegrated-2] + _ = x[ATAuthCode-3] + _ = x[ATInteractive-4] + _ = x[ATClientCredentials-5] + _ = x[ATDeviceCode-6] + _ = x[ATRefreshToken-7] +} + +const _AuthorizeType_name = "ATUnknownATUsernamePasswordATWindowsIntegratedATAuthCodeATInteractiveATClientCredentialsATDeviceCodeATRefreshToken" + +var _AuthorizeType_index = [...]uint8{0, 9, 27, 46, 56, 69, 88, 100, 114} + +func (i AuthorizeType) String() string { + if i < 0 || i >= AuthorizeType(len(_AuthorizeType_index)-1) { + return "AuthorizeType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _AuthorizeType_name[_AuthorizeType_index[i]:_AuthorizeType_index[i+1]] +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm/comm.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm/comm.go new file mode 100644 index 000000000..790680366 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm/comm.go @@ -0,0 +1,319 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package comm provides helpers for communicating with HTTP backends. +package comm + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "net/http" + "net/url" + "reflect" + "runtime" + "strings" + "time" + + "github.com/google/uuid" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors" + customJSON "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version" +) + +// HTTPClient represents an HTTP client. +// It's usually an *http.Client from the standard library. +type HTTPClient interface { + // Do sends an HTTP request and returns an HTTP response. + Do(req *http.Request) (*http.Response, error) + + // CloseIdleConnections closes any idle connections in a "keep-alive" state. + CloseIdleConnections() +} + +// Client provides a wrapper to our *http.Client that handles compression and serialization needs. +type Client struct { + client HTTPClient +} + +// New returns a new Client object. +func New(httpClient HTTPClient) *Client { + if httpClient == nil { + panic("http.Client cannot == nil") + } + + return &Client{client: httpClient} +} + +// JSONCall connects to the REST endpoint passing the HTTP query values, headers and JSON conversion +// of body in the HTTP body. It automatically handles compression and decompression with gzip. The response is JSON +// unmarshalled into resp. resp must be a pointer to a struct. If the body struct contains a field called +// "AdditionalFields" we use a custom marshal/unmarshal engine. +func (c *Client) JSONCall(ctx context.Context, endpoint string, headers http.Header, qv url.Values, body, resp interface{}) error { + if qv == nil { + qv = url.Values{} + } + + v := reflect.ValueOf(resp) + if err := c.checkResp(v); err != nil { + return err + } + + // Choose a JSON marshal/unmarshal depending on if we have AdditionalFields attribute. + var marshal = json.Marshal + var unmarshal = json.Unmarshal + if _, ok := v.Elem().Type().FieldByName("AdditionalFields"); ok { + marshal = customJSON.Marshal + unmarshal = customJSON.Unmarshal + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s?%s", endpoint, qv.Encode()), nil) + if err != nil { + return fmt.Errorf("could not create request: %w", err) + } + + addStdHeaders(headers) + req.Header = headers + + if body != nil { + // Note: In case your wondering why we are not gzip encoding.... + // I'm not sure if these various services support gzip on send. + headers.Add("Content-Type", "application/json; charset=utf-8") + data, err := marshal(body) + if err != nil { + return fmt.Errorf("bug: conn.Call(): could not marshal the body object: %w", err) + } + req.Body = io.NopCloser(bytes.NewBuffer(data)) + req.Method = http.MethodPost + } + + data, err := c.do(ctx, req) + if err != nil { + return err + } + + if resp != nil { + if err := unmarshal(data, resp); err != nil { + return errors.InvalidJsonErr{Err: fmt.Errorf("json decode error: %w\njson message bytes were: %s", err, string(data))} + } + } + return nil +} + +// XMLCall connects to an endpoint and decodes the XML response into resp. This is used when +// sending application/xml . If sending XML via SOAP, use SOAPCall(). +func (c *Client) XMLCall(ctx context.Context, endpoint string, headers http.Header, qv url.Values, resp interface{}) error { + if err := c.checkResp(reflect.ValueOf(resp)); err != nil { + return err + } + + if qv == nil { + qv = url.Values{} + } + + u, err := url.Parse(endpoint) + if err != nil { + return fmt.Errorf("could not parse path URL(%s): %w", endpoint, err) + } + u.RawQuery = qv.Encode() + + headers.Set("Content-Type", "application/xml; charset=utf-8") // This was not set in he original Mex(), but... + addStdHeaders(headers) + + return c.xmlCall(ctx, u, headers, "", resp) +} + +// SOAPCall returns the SOAP message given an endpoint, action, body of the request and the response object to marshal into. +func (c *Client) SOAPCall(ctx context.Context, endpoint, action string, headers http.Header, qv url.Values, body string, resp interface{}) error { + if body == "" { + return fmt.Errorf("cannot make a SOAP call with body set to empty string") + } + + if err := c.checkResp(reflect.ValueOf(resp)); err != nil { + return err + } + + if qv == nil { + qv = url.Values{} + } + + u, err := url.Parse(endpoint) + if err != nil { + return fmt.Errorf("could not parse path URL(%s): %w", endpoint, err) + } + u.RawQuery = qv.Encode() + + headers.Set("Content-Type", "application/soap+xml; charset=utf-8") + headers.Set("SOAPAction", action) + addStdHeaders(headers) + + return c.xmlCall(ctx, u, headers, body, resp) +} + +// xmlCall sends an XML in body and decodes into resp. This simply does the transport and relies on +// an upper level call to set things such as SOAP parameters and Content-Type, if required. +func (c *Client) xmlCall(ctx context.Context, u *url.URL, headers http.Header, body string, resp interface{}) error { + req := &http.Request{Method: http.MethodGet, URL: u, Header: headers} + + if len(body) > 0 { + req.Method = http.MethodPost + req.Body = io.NopCloser(strings.NewReader(body)) + } + + data, err := c.do(ctx, req) + if err != nil { + return err + } + + return xml.Unmarshal(data, resp) +} + +// URLFormCall is used to make a call where we need to send application/x-www-form-urlencoded data +// to the backend and receive JSON back. qv will be encoded into the request body. +func (c *Client) URLFormCall(ctx context.Context, endpoint string, qv url.Values, resp interface{}) error { + if len(qv) == 0 { + return fmt.Errorf("URLFormCall() requires qv to have non-zero length") + } + + if err := c.checkResp(reflect.ValueOf(resp)); err != nil { + return err + } + + u, err := url.Parse(endpoint) + if err != nil { + return fmt.Errorf("could not parse path URL(%s): %w", endpoint, err) + } + + headers := http.Header{} + headers.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + addStdHeaders(headers) + + enc := qv.Encode() + + req := &http.Request{ + Method: http.MethodPost, + URL: u, + Header: headers, + ContentLength: int64(len(enc)), + Body: io.NopCloser(strings.NewReader(enc)), + GetBody: func() (io.ReadCloser, error) { + return io.NopCloser(strings.NewReader(enc)), nil + }, + } + + data, err := c.do(ctx, req) + if err != nil { + return err + } + + v := reflect.ValueOf(resp) + if err := c.checkResp(v); err != nil { + return err + } + + var unmarshal = json.Unmarshal + if _, ok := v.Elem().Type().FieldByName("AdditionalFields"); ok { + unmarshal = customJSON.Unmarshal + } + if resp != nil { + if err := unmarshal(data, resp); err != nil { + return errors.InvalidJsonErr{Err: fmt.Errorf("json decode error: %w\nraw message was: %s", err, string(data))} + } + } + return nil +} + +// do makes the HTTP call to the server and returns the contents of the body. +func (c *Client) do(ctx context.Context, req *http.Request) ([]byte, error) { + if _, ok := ctx.Deadline(); !ok { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, 30*time.Second) + defer cancel() + } + req = req.WithContext(ctx) + + reply, err := c.client.Do(req) + if err != nil { + return nil, fmt.Errorf("server response error:\n %w", err) + } + defer reply.Body.Close() + + data, err := c.readBody(reply) + if err != nil { + return nil, fmt.Errorf("could not read the body of an HTTP Response: %w", err) + } + reply.Body = io.NopCloser(bytes.NewBuffer(data)) + + // NOTE: This doesn't happen immediately after the call so that we can get an error message + // from the server and include it in our error. + switch reply.StatusCode { + case 200, 201: + default: + sd := strings.TrimSpace(string(data)) + if sd != "" { + // We probably have the error in the body. + return nil, errors.CallErr{ + Req: req, + Resp: reply, + Err: fmt.Errorf("http call(%s)(%s) error: reply status code was %d:\n%s", req.URL.String(), req.Method, reply.StatusCode, sd), + } + } + return nil, errors.CallErr{ + Req: req, + Resp: reply, + Err: fmt.Errorf("http call(%s)(%s) error: reply status code was %d", req.URL.String(), req.Method, reply.StatusCode), + } + } + + return data, nil +} + +// checkResp checks a response object o make sure it is a pointer to a struct. +func (c *Client) checkResp(v reflect.Value) error { + if v.Kind() != reflect.Ptr { + return fmt.Errorf("bug: resp argument must a *struct, was %T", v.Interface()) + } + v = v.Elem() + if v.Kind() != reflect.Struct { + return fmt.Errorf("bug: resp argument must be a *struct, was %T", v.Interface()) + } + return nil +} + +// readBody reads the body out of an *http.Response. It supports gzip encoded responses. +func (c *Client) readBody(resp *http.Response) ([]byte, error) { + var reader io.Reader = resp.Body + switch resp.Header.Get("Content-Encoding") { + case "": + // Do nothing + case "gzip": + reader = gzipDecompress(resp.Body) + default: + return nil, fmt.Errorf("bug: comm.Client.JSONCall(): content was send with unsupported content-encoding %s", resp.Header.Get("Content-Encoding")) + } + return io.ReadAll(reader) +} + +var testID string + +// addStdHeaders adds the standard headers we use on all calls. +func addStdHeaders(headers http.Header) http.Header { + headers.Set("Accept-Encoding", "gzip") + // So that I can have a static id for tests. + if testID != "" { + headers.Set("client-request-id", testID) + headers.Set("Return-Client-Request-Id", "false") + } else { + headers.Set("client-request-id", uuid.New().String()) + headers.Set("Return-Client-Request-Id", "false") + } + headers.Set("x-client-sku", "MSAL.Go") + headers.Set("x-client-os", runtime.GOOS) + headers.Set("x-client-cpu", runtime.GOARCH) + headers.Set("x-client-ver", version.Version) + return headers +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm/compress.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm/compress.go new file mode 100644 index 000000000..4d3dbfcf0 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/comm/compress.go @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package comm + +import ( + "compress/gzip" + "io" +) + +func gzipDecompress(r io.Reader) io.Reader { + gzipReader, _ := gzip.NewReader(r) + + pipeOut, pipeIn := io.Pipe() + go func() { + // decompression bomb would have to come from Azure services. + // If we want to limit, we should do that in comm.do(). + _, err := io.Copy(pipeIn, gzipReader) //nolint + if err != nil { + // don't need the error. + pipeIn.CloseWithError(err) //nolint + gzipReader.Close() + return + } + if err := gzipReader.Close(); err != nil { + // don't need the error. + pipeIn.CloseWithError(err) //nolint + return + } + pipeIn.Close() + }() + return pipeOut +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant/grant.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant/grant.go new file mode 100644 index 000000000..b628f61ac --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant/grant.go @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package grant holds types of grants issued by authorization services. +package grant + +const ( + Password = "password" + JWT = "urn:ietf:params:oauth:grant-type:jwt-bearer" + SAMLV1 = "urn:ietf:params:oauth:grant-type:saml1_1-bearer" + SAMLV2 = "urn:ietf:params:oauth:grant-type:saml2-bearer" + DeviceCode = "device_code" + AuthCode = "authorization_code" + RefreshToken = "refresh_token" + ClientCredential = "client_credentials" + ClientAssertion = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" +) diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/ops.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/ops.go new file mode 100644 index 000000000..1f9c543fa --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/ops.go @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package ops provides operations to various backend services using REST clients. + +The REST type provides several clients that can be used to communicate to backends. +Usage is simple: + + rest := ops.New() + + // Creates an authority client and calls the UserRealm() method. + userRealm, err := rest.Authority().UserRealm(ctx, authParameters) + if err != nil { + // Do something + } +*/ +package ops + +import ( + "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/oauth/ops/internal/comm" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust" +) + +// HTTPClient represents an HTTP client. +// It's usually an *http.Client from the standard library. +type HTTPClient = comm.HTTPClient + +// REST provides REST clients for communicating with various backends used by MSAL. +type REST struct { + client *comm.Client +} + +// New is the constructor for REST. +func New(httpClient HTTPClient) *REST { + return &REST{client: comm.New(httpClient)} +} + +// Authority returns a client for querying information about various authorities. +func (r *REST) Authority() authority.Client { + return authority.Client{Comm: r.client} +} + +// AccessTokens returns a client that can be used to get various access tokens for +// authorization purposes. +func (r *REST) AccessTokens() accesstokens.Client { + return accesstokens.Client{Comm: r.client} +} + +// WSTrust provides access to various metadata in a WSTrust service. This data can +// be used to gain tokens based on SAML data using the client provided by AccessTokens(). +func (r *REST) WSTrust() wstrust.Client { + return wstrust.Client{Comm: r.client} +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/endpointtype_string.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/endpointtype_string.go new file mode 100644 index 000000000..a2bb6278a --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/endpointtype_string.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -type=endpointType"; DO NOT EDIT. + +package defs + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[etUnknown-0] + _ = x[etUsernamePassword-1] + _ = x[etWindowsTransport-2] +} + +const _endpointType_name = "etUnknownetUsernamePasswordetWindowsTransport" + +var _endpointType_index = [...]uint8{0, 9, 27, 45} + +func (i endpointType) String() string { + if i < 0 || i >= endpointType(len(_endpointType_index)-1) { + return "endpointType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _endpointType_name[_endpointType_index[i]:_endpointType_index[i+1]] +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/mex_document_definitions.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/mex_document_definitions.go new file mode 100644 index 000000000..649727002 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/mex_document_definitions.go @@ -0,0 +1,394 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package defs + +import "encoding/xml" + +type Definitions struct { + XMLName xml.Name `xml:"definitions"` + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + TargetNamespace string `xml:"targetNamespace,attr"` + WSDL string `xml:"wsdl,attr"` + XSD string `xml:"xsd,attr"` + T string `xml:"t,attr"` + SOAPENC string `xml:"soapenc,attr"` + SOAP string `xml:"soap,attr"` + TNS string `xml:"tns,attr"` + MSC string `xml:"msc,attr"` + WSAM string `xml:"wsam,attr"` + SOAP12 string `xml:"soap12,attr"` + WSA10 string `xml:"wsa10,attr"` + WSA string `xml:"wsa,attr"` + WSAW string `xml:"wsaw,attr"` + WSX string `xml:"wsx,attr"` + WSAP string `xml:"wsap,attr"` + WSU string `xml:"wsu,attr"` + Trust string `xml:"trust,attr"` + WSP string `xml:"wsp,attr"` + Policy []Policy `xml:"Policy"` + Types Types `xml:"types"` + Message []Message `xml:"message"` + PortType []PortType `xml:"portType"` + Binding []Binding `xml:"binding"` + Service Service `xml:"service"` +} + +type Policy struct { + Text string `xml:",chardata"` + ID string `xml:"Id,attr"` + ExactlyOne ExactlyOne `xml:"ExactlyOne"` +} + +type ExactlyOne struct { + Text string `xml:",chardata"` + All All `xml:"All"` +} + +type All struct { + Text string `xml:",chardata"` + NegotiateAuthentication NegotiateAuthentication `xml:"NegotiateAuthentication"` + TransportBinding TransportBinding `xml:"TransportBinding"` + UsingAddressing Text `xml:"UsingAddressing"` + EndorsingSupportingTokens EndorsingSupportingTokens `xml:"EndorsingSupportingTokens"` + WSS11 WSS11 `xml:"Wss11"` + Trust10 Trust10 `xml:"Trust10"` + SignedSupportingTokens SignedSupportingTokens `xml:"SignedSupportingTokens"` + Trust13 WSTrust13 `xml:"Trust13"` + SignedEncryptedSupportingTokens SignedEncryptedSupportingTokens `xml:"SignedEncryptedSupportingTokens"` +} + +type NegotiateAuthentication struct { + Text string `xml:",chardata"` + HTTP string `xml:"http,attr"` + XMLName xml.Name +} + +type TransportBinding struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy TransportBindingPolicy `xml:"Policy"` +} + +type TransportBindingPolicy struct { + Text string `xml:",chardata"` + TransportToken TransportToken `xml:"TransportToken"` + AlgorithmSuite AlgorithmSuite `xml:"AlgorithmSuite"` + Layout Layout `xml:"Layout"` + IncludeTimestamp Text `xml:"IncludeTimestamp"` +} + +type TransportToken struct { + Text string `xml:",chardata"` + Policy TransportTokenPolicy `xml:"Policy"` +} + +type TransportTokenPolicy struct { + Text string `xml:",chardata"` + HTTPSToken HTTPSToken `xml:"HttpsToken"` +} + +type HTTPSToken struct { + Text string `xml:",chardata"` + RequireClientCertificate string `xml:"RequireClientCertificate,attr"` +} + +type AlgorithmSuite struct { + Text string `xml:",chardata"` + Policy AlgorithmSuitePolicy `xml:"Policy"` +} + +type AlgorithmSuitePolicy struct { + Text string `xml:",chardata"` + Basic256 Text `xml:"Basic256"` + Basic128 Text `xml:"Basic128"` +} + +type Layout struct { + Text string `xml:",chardata"` + Policy LayoutPolicy `xml:"Policy"` +} + +type LayoutPolicy struct { + Text string `xml:",chardata"` + Strict Text `xml:"Strict"` +} + +type EndorsingSupportingTokens struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy EndorsingSupportingTokensPolicy `xml:"Policy"` +} + +type EndorsingSupportingTokensPolicy struct { + Text string `xml:",chardata"` + X509Token X509Token `xml:"X509Token"` + RSAToken RSAToken `xml:"RsaToken"` + SignedParts SignedParts `xml:"SignedParts"` + KerberosToken KerberosToken `xml:"KerberosToken"` + IssuedToken IssuedToken `xml:"IssuedToken"` + KeyValueToken KeyValueToken `xml:"KeyValueToken"` +} + +type X509Token struct { + Text string `xml:",chardata"` + IncludeToken string `xml:"IncludeToken,attr"` + Policy X509TokenPolicy `xml:"Policy"` +} + +type X509TokenPolicy struct { + Text string `xml:",chardata"` + RequireThumbprintReference Text `xml:"RequireThumbprintReference"` + WSSX509V3Token10 Text `xml:"WssX509V3Token10"` +} + +type RSAToken struct { + Text string `xml:",chardata"` + IncludeToken string `xml:"IncludeToken,attr"` + Optional string `xml:"Optional,attr"` + MSSP string `xml:"mssp,attr"` +} + +type SignedParts struct { + Text string `xml:",chardata"` + Header SignedPartsHeader `xml:"Header"` +} + +type SignedPartsHeader struct { + Text string `xml:",chardata"` + Name string `xml:"Name,attr"` + Namespace string `xml:"Namespace,attr"` +} + +type KerberosToken struct { + Text string `xml:",chardata"` + IncludeToken string `xml:"IncludeToken,attr"` + Policy KerberosTokenPolicy `xml:"Policy"` +} + +type KerberosTokenPolicy struct { + Text string `xml:",chardata"` + WSSGSSKerberosV5ApReqToken11 Text `xml:"WssGssKerberosV5ApReqToken11"` +} + +type IssuedToken struct { + Text string `xml:",chardata"` + IncludeToken string `xml:"IncludeToken,attr"` + RequestSecurityTokenTemplate RequestSecurityTokenTemplate `xml:"RequestSecurityTokenTemplate"` + Policy IssuedTokenPolicy `xml:"Policy"` +} + +type RequestSecurityTokenTemplate struct { + Text string `xml:",chardata"` + KeyType Text `xml:"KeyType"` + EncryptWith Text `xml:"EncryptWith"` + SignatureAlgorithm Text `xml:"SignatureAlgorithm"` + CanonicalizationAlgorithm Text `xml:"CanonicalizationAlgorithm"` + EncryptionAlgorithm Text `xml:"EncryptionAlgorithm"` + KeySize Text `xml:"KeySize"` + KeyWrapAlgorithm Text `xml:"KeyWrapAlgorithm"` +} + +type IssuedTokenPolicy struct { + Text string `xml:",chardata"` + RequireInternalReference Text `xml:"RequireInternalReference"` +} + +type KeyValueToken struct { + Text string `xml:",chardata"` + IncludeToken string `xml:"IncludeToken,attr"` + Optional string `xml:"Optional,attr"` +} + +type WSS11 struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy Wss11Policy `xml:"Policy"` +} + +type Wss11Policy struct { + Text string `xml:",chardata"` + MustSupportRefThumbprint Text `xml:"MustSupportRefThumbprint"` +} + +type Trust10 struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy Trust10Policy `xml:"Policy"` +} + +type Trust10Policy struct { + Text string `xml:",chardata"` + MustSupportIssuedTokens Text `xml:"MustSupportIssuedTokens"` + RequireClientEntropy Text `xml:"RequireClientEntropy"` + RequireServerEntropy Text `xml:"RequireServerEntropy"` +} + +type SignedSupportingTokens struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy SupportingTokensPolicy `xml:"Policy"` +} + +type SupportingTokensPolicy struct { + Text string `xml:",chardata"` + UsernameToken UsernameToken `xml:"UsernameToken"` +} +type UsernameToken struct { + Text string `xml:",chardata"` + IncludeToken string `xml:"IncludeToken,attr"` + Policy UsernameTokenPolicy `xml:"Policy"` +} + +type UsernameTokenPolicy struct { + Text string `xml:",chardata"` + WSSUsernameToken10 WSSUsernameToken10 `xml:"WssUsernameToken10"` +} + +type WSSUsernameToken10 struct { + Text string `xml:",chardata"` + XMLName xml.Name +} + +type WSTrust13 struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy WSTrust13Policy `xml:"Policy"` +} + +type WSTrust13Policy struct { + Text string `xml:",chardata"` + MustSupportIssuedTokens Text `xml:"MustSupportIssuedTokens"` + RequireClientEntropy Text `xml:"RequireClientEntropy"` + RequireServerEntropy Text `xml:"RequireServerEntropy"` +} + +type SignedEncryptedSupportingTokens struct { + Text string `xml:",chardata"` + SP string `xml:"sp,attr"` + Policy SupportingTokensPolicy `xml:"Policy"` +} + +type Types struct { + Text string `xml:",chardata"` + Schema Schema `xml:"schema"` +} + +type Schema struct { + Text string `xml:",chardata"` + TargetNamespace string `xml:"targetNamespace,attr"` + Import []Import `xml:"import"` +} + +type Import struct { + Text string `xml:",chardata"` + SchemaLocation string `xml:"schemaLocation,attr"` + Namespace string `xml:"namespace,attr"` +} + +type Message struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Part Part `xml:"part"` +} + +type Part struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Element string `xml:"element,attr"` +} + +type PortType struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Operation Operation `xml:"operation"` +} + +type Operation struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Input OperationIO `xml:"input"` + Output OperationIO `xml:"output"` +} + +type OperationIO struct { + Text string `xml:",chardata"` + Action string `xml:"Action,attr"` + Message string `xml:"message,attr"` + Body OperationIOBody `xml:"body"` +} + +type OperationIOBody struct { + Text string `xml:",chardata"` + Use string `xml:"use,attr"` +} + +type Binding struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Type string `xml:"type,attr"` + PolicyReference PolicyReference `xml:"PolicyReference"` + Binding DefinitionsBinding `xml:"binding"` + Operation BindingOperation `xml:"operation"` +} + +type PolicyReference struct { + Text string `xml:",chardata"` + URI string `xml:"URI,attr"` +} + +type DefinitionsBinding struct { + Text string `xml:",chardata"` + Transport string `xml:"transport,attr"` +} + +type BindingOperation struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Operation BindingOperationOperation `xml:"operation"` + Input BindingOperationIO `xml:"input"` + Output BindingOperationIO `xml:"output"` +} + +type BindingOperationOperation struct { + Text string `xml:",chardata"` + SoapAction string `xml:"soapAction,attr"` + Style string `xml:"style,attr"` +} + +type BindingOperationIO struct { + Text string `xml:",chardata"` + Body OperationIOBody `xml:"body"` +} + +type Service struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Port []Port `xml:"port"` +} + +type Port struct { + Text string `xml:",chardata"` + Name string `xml:"name,attr"` + Binding string `xml:"binding,attr"` + Address Address `xml:"address"` + EndpointReference PortEndpointReference `xml:"EndpointReference"` +} + +type Address struct { + Text string `xml:",chardata"` + Location string `xml:"location,attr"` +} + +type PortEndpointReference struct { + Text string `xml:",chardata"` + Address Text `xml:"Address"` + Identity Identity `xml:"Identity"` +} + +type Identity struct { + Text string `xml:",chardata"` + XMLNS string `xml:"xmlns,attr"` + SPN Text `xml:"Spn"` +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/saml_assertion_definitions.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/saml_assertion_definitions.go new file mode 100644 index 000000000..7d0725565 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/saml_assertion_definitions.go @@ -0,0 +1,230 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package defs + +import "encoding/xml" + +// TODO(msal): Someone (and it ain't gonna be me) needs to document these attributes or +// at the least put a link to RFC. + +type SAMLDefinitions struct { + XMLName xml.Name `xml:"Envelope"` + Text string `xml:",chardata"` + S string `xml:"s,attr"` + A string `xml:"a,attr"` + U string `xml:"u,attr"` + Header Header `xml:"Header"` + Body Body `xml:"Body"` +} + +type Header struct { + Text string `xml:",chardata"` + Action Action `xml:"Action"` + Security Security `xml:"Security"` +} + +type Action struct { + Text string `xml:",chardata"` + MustUnderstand string `xml:"mustUnderstand,attr"` +} + +type Security struct { + Text string `xml:",chardata"` + MustUnderstand string `xml:"mustUnderstand,attr"` + O string `xml:"o,attr"` + Timestamp Timestamp `xml:"Timestamp"` +} + +type Timestamp struct { + Text string `xml:",chardata"` + ID string `xml:"Id,attr"` + Created Text `xml:"Created"` + Expires Text `xml:"Expires"` +} + +type Text struct { + Text string `xml:",chardata"` +} + +type Body struct { + Text string `xml:",chardata"` + RequestSecurityTokenResponseCollection RequestSecurityTokenResponseCollection `xml:"RequestSecurityTokenResponseCollection"` +} + +type RequestSecurityTokenResponseCollection struct { + Text string `xml:",chardata"` + Trust string `xml:"trust,attr"` + RequestSecurityTokenResponse []RequestSecurityTokenResponse `xml:"RequestSecurityTokenResponse"` +} + +type RequestSecurityTokenResponse struct { + Text string `xml:",chardata"` + Lifetime Lifetime `xml:"Lifetime"` + AppliesTo AppliesTo `xml:"AppliesTo"` + RequestedSecurityToken RequestedSecurityToken `xml:"RequestedSecurityToken"` + RequestedAttachedReference RequestedAttachedReference `xml:"RequestedAttachedReference"` + RequestedUnattachedReference RequestedUnattachedReference `xml:"RequestedUnattachedReference"` + TokenType Text `xml:"TokenType"` + RequestType Text `xml:"RequestType"` + KeyType Text `xml:"KeyType"` +} + +type Lifetime struct { + Text string `xml:",chardata"` + Created WSUTimestamp `xml:"Created"` + Expires WSUTimestamp `xml:"Expires"` +} + +type WSUTimestamp struct { + Text string `xml:",chardata"` + Wsu string `xml:"wsu,attr"` +} + +type AppliesTo struct { + Text string `xml:",chardata"` + Wsp string `xml:"wsp,attr"` + EndpointReference EndpointReference `xml:"EndpointReference"` +} + +type EndpointReference struct { + Text string `xml:",chardata"` + Wsa string `xml:"wsa,attr"` + Address Text `xml:"Address"` +} + +type RequestedSecurityToken struct { + Text string `xml:",chardata"` + AssertionRawXML string `xml:",innerxml"` + Assertion Assertion `xml:"Assertion"` +} + +type Assertion struct { + XMLName xml.Name // Normally its `xml:"Assertion"`, but I think they want to capture the xmlns + Text string `xml:",chardata"` + MajorVersion string `xml:"MajorVersion,attr"` + MinorVersion string `xml:"MinorVersion,attr"` + AssertionID string `xml:"AssertionID,attr"` + Issuer string `xml:"Issuer,attr"` + IssueInstant string `xml:"IssueInstant,attr"` + Saml string `xml:"saml,attr"` + Conditions Conditions `xml:"Conditions"` + AttributeStatement AttributeStatement `xml:"AttributeStatement"` + AuthenticationStatement AuthenticationStatement `xml:"AuthenticationStatement"` + Signature Signature `xml:"Signature"` +} + +type Conditions struct { + Text string `xml:",chardata"` + NotBefore string `xml:"NotBefore,attr"` + NotOnOrAfter string `xml:"NotOnOrAfter,attr"` + AudienceRestrictionCondition AudienceRestrictionCondition `xml:"AudienceRestrictionCondition"` +} + +type AudienceRestrictionCondition struct { + Text string `xml:",chardata"` + Audience Text `xml:"Audience"` +} + +type AttributeStatement struct { + Text string `xml:",chardata"` + Subject Subject `xml:"Subject"` + Attribute []Attribute `xml:"Attribute"` +} + +type Subject struct { + Text string `xml:",chardata"` + NameIdentifier NameIdentifier `xml:"NameIdentifier"` + SubjectConfirmation SubjectConfirmation `xml:"SubjectConfirmation"` +} + +type NameIdentifier struct { + Text string `xml:",chardata"` + Format string `xml:"Format,attr"` +} + +type SubjectConfirmation struct { + Text string `xml:",chardata"` + ConfirmationMethod Text `xml:"ConfirmationMethod"` +} + +type Attribute struct { + Text string `xml:",chardata"` + AttributeName string `xml:"AttributeName,attr"` + AttributeNamespace string `xml:"AttributeNamespace,attr"` + AttributeValue Text `xml:"AttributeValue"` +} + +type AuthenticationStatement struct { + Text string `xml:",chardata"` + AuthenticationMethod string `xml:"AuthenticationMethod,attr"` + AuthenticationInstant string `xml:"AuthenticationInstant,attr"` + Subject Subject `xml:"Subject"` +} + +type Signature struct { + Text string `xml:",chardata"` + Ds string `xml:"ds,attr"` + SignedInfo SignedInfo `xml:"SignedInfo"` + SignatureValue Text `xml:"SignatureValue"` + KeyInfo KeyInfo `xml:"KeyInfo"` +} + +type SignedInfo struct { + Text string `xml:",chardata"` + CanonicalizationMethod Method `xml:"CanonicalizationMethod"` + SignatureMethod Method `xml:"SignatureMethod"` + Reference Reference `xml:"Reference"` +} + +type Method struct { + Text string `xml:",chardata"` + Algorithm string `xml:"Algorithm,attr"` +} + +type Reference struct { + Text string `xml:",chardata"` + URI string `xml:"URI,attr"` + Transforms Transforms `xml:"Transforms"` + DigestMethod Method `xml:"DigestMethod"` + DigestValue Text `xml:"DigestValue"` +} + +type Transforms struct { + Text string `xml:",chardata"` + Transform []Method `xml:"Transform"` +} + +type KeyInfo struct { + Text string `xml:",chardata"` + Xmlns string `xml:"xmlns,attr"` + X509Data X509Data `xml:"X509Data"` +} + +type X509Data struct { + Text string `xml:",chardata"` + X509Certificate Text `xml:"X509Certificate"` +} + +type RequestedAttachedReference struct { + Text string `xml:",chardata"` + SecurityTokenReference SecurityTokenReference `xml:"SecurityTokenReference"` +} + +type SecurityTokenReference struct { + Text string `xml:",chardata"` + TokenType string `xml:"TokenType,attr"` + O string `xml:"o,attr"` + K string `xml:"k,attr"` + KeyIdentifier KeyIdentifier `xml:"KeyIdentifier"` +} + +type KeyIdentifier struct { + Text string `xml:",chardata"` + ValueType string `xml:"ValueType,attr"` +} + +type RequestedUnattachedReference struct { + Text string `xml:",chardata"` + SecurityTokenReference SecurityTokenReference `xml:"SecurityTokenReference"` +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/version_string.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/version_string.go new file mode 100644 index 000000000..6fe5efa8a --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/version_string.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -type=Version"; DO NOT EDIT. + +package defs + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[TrustUnknown-0] + _ = x[Trust2005-1] + _ = x[Trust13-2] +} + +const _Version_name = "TrustUnknownTrust2005Trust13" + +var _Version_index = [...]uint8{0, 12, 21, 28} + +func (i Version) String() string { + if i < 0 || i >= Version(len(_Version_index)-1) { + return "Version(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Version_name[_Version_index[i]:_Version_index[i+1]] +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/wstrust_endpoint.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/wstrust_endpoint.go new file mode 100644 index 000000000..8fad5efb5 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/wstrust_endpoint.go @@ -0,0 +1,199 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package defs + +import ( + "encoding/xml" + "fmt" + "time" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority" + uuid "github.com/google/uuid" +) + +//go:generate stringer -type=Version + +type Version int + +const ( + TrustUnknown Version = iota + Trust2005 + Trust13 +) + +// Endpoint represents a WSTrust endpoint. +type Endpoint struct { + // Version is the version of the endpoint. + Version Version + // URL is the URL of the endpoint. + URL string +} + +type wsTrustTokenRequestEnvelope struct { + XMLName xml.Name `xml:"s:Envelope"` + Text string `xml:",chardata"` + S string `xml:"xmlns:s,attr"` + Wsa string `xml:"xmlns:wsa,attr"` + Wsu string `xml:"xmlns:wsu,attr"` + Header struct { + Text string `xml:",chardata"` + Action struct { + Text string `xml:",chardata"` + MustUnderstand string `xml:"s:mustUnderstand,attr"` + } `xml:"wsa:Action"` + MessageID struct { + Text string `xml:",chardata"` + } `xml:"wsa:messageID"` + ReplyTo struct { + Text string `xml:",chardata"` + Address struct { + Text string `xml:",chardata"` + } `xml:"wsa:Address"` + } `xml:"wsa:ReplyTo"` + To struct { + Text string `xml:",chardata"` + MustUnderstand string `xml:"s:mustUnderstand,attr"` + } `xml:"wsa:To"` + Security struct { + Text string `xml:",chardata"` + MustUnderstand string `xml:"s:mustUnderstand,attr"` + Wsse string `xml:"xmlns:wsse,attr"` + Timestamp struct { + Text string `xml:",chardata"` + ID string `xml:"wsu:Id,attr"` + Created struct { + Text string `xml:",chardata"` + } `xml:"wsu:Created"` + Expires struct { + Text string `xml:",chardata"` + } `xml:"wsu:Expires"` + } `xml:"wsu:Timestamp"` + UsernameToken struct { + Text string `xml:",chardata"` + ID string `xml:"wsu:Id,attr"` + Username struct { + Text string `xml:",chardata"` + } `xml:"wsse:Username"` + Password struct { + Text string `xml:",chardata"` + } `xml:"wsse:Password"` + } `xml:"wsse:UsernameToken"` + } `xml:"wsse:Security"` + } `xml:"s:Header"` + Body struct { + Text string `xml:",chardata"` + RequestSecurityToken struct { + Text string `xml:",chardata"` + Wst string `xml:"xmlns:wst,attr"` + AppliesTo struct { + Text string `xml:",chardata"` + Wsp string `xml:"xmlns:wsp,attr"` + EndpointReference struct { + Text string `xml:",chardata"` + Address struct { + Text string `xml:",chardata"` + } `xml:"wsa:Address"` + } `xml:"wsa:EndpointReference"` + } `xml:"wsp:AppliesTo"` + KeyType struct { + Text string `xml:",chardata"` + } `xml:"wst:KeyType"` + RequestType struct { + Text string `xml:",chardata"` + } `xml:"wst:RequestType"` + } `xml:"wst:RequestSecurityToken"` + } `xml:"s:Body"` +} + +func buildTimeString(t time.Time) string { + // Golang time formats are weird: https://stackoverflow.com/questions/20234104/how-to-format-current-time-using-a-yyyymmddhhmmss-format + return t.Format("2006-01-02T15:04:05.000Z") +} + +func (wte *Endpoint) buildTokenRequestMessage(authType authority.AuthorizeType, cloudAudienceURN string, username string, password string) (string, error) { + var soapAction string + var trustNamespace string + var keyType string + var requestType string + + createdTime := time.Now().UTC() + expiresTime := createdTime.Add(10 * time.Minute) + + switch wte.Version { + case Trust2005: + soapAction = trust2005Spec + trustNamespace = "http://schemas.xmlsoap.org/ws/2005/02/trust" + keyType = "http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey" + requestType = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue" + case Trust13: + soapAction = trust13Spec + trustNamespace = "http://docs.oasis-open.org/ws-sx/ws-trust/200512" + keyType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer" + requestType = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue" + default: + return "", fmt.Errorf("buildTokenRequestMessage had Version == %q, which is not recognized", wte.Version) + } + + var envelope wsTrustTokenRequestEnvelope + + messageUUID := uuid.New() + + envelope.S = "http://www.w3.org/2003/05/soap-envelope" + envelope.Wsa = "http://www.w3.org/2005/08/addressing" + envelope.Wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" + + envelope.Header.Action.MustUnderstand = "1" + envelope.Header.Action.Text = soapAction + envelope.Header.MessageID.Text = "urn:uuid:" + messageUUID.String() + envelope.Header.ReplyTo.Address.Text = "http://www.w3.org/2005/08/addressing/anonymous" + envelope.Header.To.MustUnderstand = "1" + envelope.Header.To.Text = wte.URL + + switch authType { + case authority.ATUnknown: + return "", fmt.Errorf("buildTokenRequestMessage had no authority type(%v)", authType) + case authority.ATUsernamePassword: + endpointUUID := uuid.New() + + var trustID string + if wte.Version == Trust2005 { + trustID = "UnPwSecTok2005-" + endpointUUID.String() + } else { + trustID = "UnPwSecTok13-" + endpointUUID.String() + } + + envelope.Header.Security.MustUnderstand = "1" + envelope.Header.Security.Wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" + envelope.Header.Security.Timestamp.ID = "MSATimeStamp" + envelope.Header.Security.Timestamp.Created.Text = buildTimeString(createdTime) + envelope.Header.Security.Timestamp.Expires.Text = buildTimeString(expiresTime) + envelope.Header.Security.UsernameToken.ID = trustID + envelope.Header.Security.UsernameToken.Username.Text = username + envelope.Header.Security.UsernameToken.Password.Text = password + default: + // This is just to note that we don't do anything for other cases. + // We aren't missing anything I know of. + } + + envelope.Body.RequestSecurityToken.Wst = trustNamespace + envelope.Body.RequestSecurityToken.AppliesTo.Wsp = "http://schemas.xmlsoap.org/ws/2004/09/policy" + envelope.Body.RequestSecurityToken.AppliesTo.EndpointReference.Address.Text = cloudAudienceURN + envelope.Body.RequestSecurityToken.KeyType.Text = keyType + envelope.Body.RequestSecurityToken.RequestType.Text = requestType + + output, err := xml.Marshal(envelope) + if err != nil { + return "", err + } + + return string(output), nil +} + +func (wte *Endpoint) BuildTokenRequestMessageWIA(cloudAudienceURN string) (string, error) { + return wte.buildTokenRequestMessage(authority.ATWindowsIntegrated, cloudAudienceURN, "", "") +} + +func (wte *Endpoint) BuildTokenRequestMessageUsernamePassword(cloudAudienceURN string, username string, password string) (string, error) { + return wte.buildTokenRequestMessage(authority.ATUsernamePassword, cloudAudienceURN, username, password) +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/wstrust_mex_document.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/wstrust_mex_document.go new file mode 100644 index 000000000..e3d19886e --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs/wstrust_mex_document.go @@ -0,0 +1,159 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package defs + +import ( + "errors" + "fmt" + "strings" +) + +//go:generate stringer -type=endpointType + +type endpointType int + +const ( + etUnknown endpointType = iota + etUsernamePassword + etWindowsTransport +) + +type wsEndpointData struct { + Version Version + EndpointType endpointType +} + +const trust13Spec string = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue" +const trust2005Spec string = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue" + +type MexDocument struct { + UsernamePasswordEndpoint Endpoint + WindowsTransportEndpoint Endpoint + policies map[string]endpointType + bindings map[string]wsEndpointData +} + +func updateEndpoint(cached *Endpoint, found Endpoint) { + if cached == nil || cached.Version == TrustUnknown { + *cached = found + return + } + if (*cached).Version == Trust2005 && found.Version == Trust13 { + *cached = found + return + } +} + +// TODO(msal): Someone needs to write tests for everything below. + +// NewFromDef creates a new MexDocument. +func NewFromDef(defs Definitions) (MexDocument, error) { + policies, err := policies(defs) + if err != nil { + return MexDocument{}, err + } + + bindings, err := bindings(defs, policies) + if err != nil { + return MexDocument{}, err + } + + userPass, windows, err := endpoints(defs, bindings) + if err != nil { + return MexDocument{}, err + } + + return MexDocument{ + UsernamePasswordEndpoint: userPass, + WindowsTransportEndpoint: windows, + policies: policies, + bindings: bindings, + }, nil +} + +func policies(defs Definitions) (map[string]endpointType, error) { + policies := make(map[string]endpointType, len(defs.Policy)) + + for _, policy := range defs.Policy { + if policy.ExactlyOne.All.NegotiateAuthentication.XMLName.Local != "" { + if policy.ExactlyOne.All.TransportBinding.SP != "" && policy.ID != "" { + policies["#"+policy.ID] = etWindowsTransport + } + } + + if policy.ExactlyOne.All.SignedEncryptedSupportingTokens.Policy.UsernameToken.Policy.WSSUsernameToken10.XMLName.Local != "" { + if policy.ExactlyOne.All.TransportBinding.SP != "" && policy.ID != "" { + policies["#"+policy.ID] = etUsernamePassword + } + } + if policy.ExactlyOne.All.SignedSupportingTokens.Policy.UsernameToken.Policy.WSSUsernameToken10.XMLName.Local != "" { + if policy.ExactlyOne.All.TransportBinding.SP != "" && policy.ID != "" { + policies["#"+policy.ID] = etUsernamePassword + } + } + } + + if len(policies) == 0 { + return policies, errors.New("no policies for mex document") + } + + return policies, nil +} + +func bindings(defs Definitions, policies map[string]endpointType) (map[string]wsEndpointData, error) { + bindings := make(map[string]wsEndpointData, len(defs.Binding)) + + for _, binding := range defs.Binding { + policyName := binding.PolicyReference.URI + transport := binding.Binding.Transport + + if transport == "http://schemas.xmlsoap.org/soap/http" { + if policy, ok := policies[policyName]; ok { + bindingName := binding.Name + specVersion := binding.Operation.Operation.SoapAction + + if specVersion == trust13Spec { + bindings[bindingName] = wsEndpointData{Trust13, policy} + } else if specVersion == trust2005Spec { + bindings[bindingName] = wsEndpointData{Trust2005, policy} + } else { + return nil, errors.New("found unknown spec version in mex document") + } + } + } + } + return bindings, nil +} + +func endpoints(defs Definitions, bindings map[string]wsEndpointData) (userPass, windows Endpoint, err error) { + for _, port := range defs.Service.Port { + bindingName := port.Binding + + index := strings.Index(bindingName, ":") + if index != -1 { + bindingName = bindingName[index+1:] + } + + if binding, ok := bindings[bindingName]; ok { + url := strings.TrimSpace(port.EndpointReference.Address.Text) + if url == "" { + return Endpoint{}, Endpoint{}, fmt.Errorf("MexDocument cannot have blank URL endpoint") + } + if binding.Version == TrustUnknown { + return Endpoint{}, Endpoint{}, fmt.Errorf("endpoint version unknown") + } + endpoint := Endpoint{Version: binding.Version, URL: url} + + switch binding.EndpointType { + case etUsernamePassword: + updateEndpoint(&userPass, endpoint) + case etWindowsTransport: + updateEndpoint(&windows, endpoint) + default: + return Endpoint{}, Endpoint{}, errors.New("found unknown port type in MEX document") + } + } + } + return userPass, windows, nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/wstrust.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/wstrust.go new file mode 100644 index 000000000..47cd4c692 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/wstrust.go @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package wstrust provides a client for communicating with a WSTrust (https://en.wikipedia.org/wiki/WS-Trust#:~:text=WS%2DTrust%20is%20a%20WS,in%20a%20secure%20message%20exchange.) +for the purposes of extracting metadata from the service. This data can be used to acquire +tokens using the accesstokens.Client.GetAccessTokenFromSamlGrant() call. +*/ +package wstrust + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/url" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs" +) + +type xmlCaller interface { + XMLCall(ctx context.Context, endpoint string, headers http.Header, qv url.Values, resp interface{}) error + SOAPCall(ctx context.Context, endpoint, action string, headers http.Header, qv url.Values, body string, resp interface{}) error +} + +type SamlTokenInfo struct { + AssertionType string // Should be either constants SAMLV1Grant or SAMLV2Grant. + Assertion string +} + +// Client represents the REST calls to get tokens from token generator backends. +type Client struct { + // Comm provides the HTTP transport client. + Comm xmlCaller +} + +// TODO(msal): This allows me to call Mex without having a real Def file on line 45. +// This would fail because policies() would not find a policy. This is easy enough to +// fix in test data, but.... Definitions is defined with built in structs. That needs +// to be pulled apart and until then I have this hack in. +var newFromDef = defs.NewFromDef + +// Mex provides metadata about a wstrust service. +func (c Client) Mex(ctx context.Context, federationMetadataURL string) (defs.MexDocument, error) { + resp := defs.Definitions{} + err := c.Comm.XMLCall( + ctx, + federationMetadataURL, + http.Header{}, + nil, + &resp, + ) + if err != nil { + return defs.MexDocument{}, err + } + + return newFromDef(resp) +} + +const ( + SoapActionDefault = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue" + + // Note: Commented out because this action is not supported. It was in the original code + // but only used in a switch where it errored. Since there was only one value, a default + // worked better. However, buildTokenRequestMessage() had 2005 support. I'm not actually + // sure what's going on here. It like we have half support. For now this is here just + // for documentation purposes in case we are going to add support. + // + // SoapActionWSTrust2005 = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue" +) + +// SAMLTokenInfo provides SAML information that is used to generate a SAML token. +func (c Client) SAMLTokenInfo(ctx context.Context, authParameters authority.AuthParams, cloudAudienceURN string, endpoint defs.Endpoint) (SamlTokenInfo, error) { + var wsTrustRequestMessage string + var err error + + switch authParameters.AuthorizationType { + case authority.ATWindowsIntegrated: + wsTrustRequestMessage, err = endpoint.BuildTokenRequestMessageWIA(cloudAudienceURN) + if err != nil { + return SamlTokenInfo{}, err + } + case authority.ATUsernamePassword: + wsTrustRequestMessage, err = endpoint.BuildTokenRequestMessageUsernamePassword( + cloudAudienceURN, authParameters.Username, authParameters.Password) + if err != nil { + return SamlTokenInfo{}, err + } + default: + return SamlTokenInfo{}, fmt.Errorf("unknown auth type %v", authParameters.AuthorizationType) + } + + var soapAction string + switch endpoint.Version { + case defs.Trust13: + soapAction = SoapActionDefault + case defs.Trust2005: + return SamlTokenInfo{}, errors.New("WS Trust 2005 support is not implemented") + default: + return SamlTokenInfo{}, fmt.Errorf("the SOAP endpoint for a wstrust call had an invalid version: %v", endpoint.Version) + } + + resp := defs.SAMLDefinitions{} + err = c.Comm.SOAPCall(ctx, endpoint.URL, soapAction, http.Header{}, nil, wsTrustRequestMessage, &resp) + if err != nil { + return SamlTokenInfo{}, err + } + + return c.samlAssertion(resp) +} + +const ( + samlv1Assertion = "urn:oasis:names:tc:SAML:1.0:assertion" + samlv2Assertion = "urn:oasis:names:tc:SAML:2.0:assertion" +) + +func (c Client) samlAssertion(def defs.SAMLDefinitions) (SamlTokenInfo, error) { + for _, tokenResponse := range def.Body.RequestSecurityTokenResponseCollection.RequestSecurityTokenResponse { + token := tokenResponse.RequestedSecurityToken + if token.Assertion.XMLName.Local != "" { + assertion := token.AssertionRawXML + + samlVersion := token.Assertion.Saml + switch samlVersion { + case samlv1Assertion: + return SamlTokenInfo{AssertionType: grant.SAMLV1, Assertion: assertion}, nil + case samlv2Assertion: + return SamlTokenInfo{AssertionType: grant.SAMLV2, Assertion: assertion}, nil + } + return SamlTokenInfo{}, fmt.Errorf("couldn't parse SAML assertion, version unknown: %q", samlVersion) + } + } + return SamlTokenInfo{}, errors.New("unknown WS-Trust version") +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go new file mode 100644 index 000000000..d220a9946 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/resolvers.go @@ -0,0 +1,164 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// TODO(msal): Write some tests. The original code this came from didn't have tests and I'm too +// tired at this point to do it. It, like many other *Manager code I found was broken because +// they didn't have mutex protection. + +package oauth + +import ( + "context" + "errors" + "fmt" + "strings" + "sync" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority" +) + +type cacheEntry struct { + Endpoints authority.Endpoints + ValidForDomainsInList map[string]bool + // Aliases stores host aliases from instance discovery for quick lookup + Aliases map[string]bool +} + +func createcacheEntry(endpoints authority.Endpoints) cacheEntry { + return cacheEntry{endpoints, map[string]bool{}, map[string]bool{}} +} + +// AuthorityEndpoint retrieves endpoints from an authority for auth and token acquisition. +type authorityEndpoint struct { + rest *ops.REST + + mu sync.Mutex + cache map[string]cacheEntry +} + +// newAuthorityEndpoint is the constructor for AuthorityEndpoint. +func newAuthorityEndpoint(rest *ops.REST) *authorityEndpoint { + m := &authorityEndpoint{rest: rest, cache: map[string]cacheEntry{}} + return m +} + +// ResolveEndpoints gets the authorization and token endpoints and creates an AuthorityEndpoints instance +func (m *authorityEndpoint) ResolveEndpoints(ctx context.Context, authorityInfo authority.Info, userPrincipalName string) (authority.Endpoints, error) { + + if endpoints, found := m.cachedEndpoints(authorityInfo, userPrincipalName); found { + return endpoints, nil + } + + endpoint, err := m.openIDConfigurationEndpoint(ctx, authorityInfo) + if err != nil { + return authority.Endpoints{}, err + } + + resp, err := m.rest.Authority().GetTenantDiscoveryResponse(ctx, endpoint) + if err != nil { + return authority.Endpoints{}, err + } + if err := resp.Validate(); err != nil { + return authority.Endpoints{}, fmt.Errorf("ResolveEndpoints(): %w", err) + } + + tenant := authorityInfo.Tenant + + endpoints := authority.NewEndpoints( + strings.Replace(resp.AuthorizationEndpoint, "{tenant}", tenant, -1), + strings.Replace(resp.TokenEndpoint, "{tenant}", tenant, -1), + strings.Replace(resp.Issuer, "{tenant}", tenant, -1), + authorityInfo.Host) + + m.addCachedEndpoints(authorityInfo, userPrincipalName, endpoints) + + if err := resp.ValidateIssuerMatchesAuthority(authorityInfo.CanonicalAuthorityURI, + m.cache[authorityInfo.CanonicalAuthorityURI].Aliases); err != nil { + return authority.Endpoints{}, fmt.Errorf("ResolveEndpoints(): %w", err) + } + + return endpoints, nil +} + +// cachedEndpoints returns the cached endpoints if they exist. If not, we return false. +func (m *authorityEndpoint) cachedEndpoints(authorityInfo authority.Info, userPrincipalName string) (authority.Endpoints, bool) { + m.mu.Lock() + defer m.mu.Unlock() + + if cacheEntry, ok := m.cache[authorityInfo.CanonicalAuthorityURI]; ok { + if authorityInfo.AuthorityType == authority.ADFS { + domain, err := adfsDomainFromUpn(userPrincipalName) + if err == nil { + if _, ok := cacheEntry.ValidForDomainsInList[domain]; ok { + return cacheEntry.Endpoints, true + } + } + } + return cacheEntry.Endpoints, true + } + return authority.Endpoints{}, false +} + +func (m *authorityEndpoint) addCachedEndpoints(authorityInfo authority.Info, userPrincipalName string, endpoints authority.Endpoints) { + m.mu.Lock() + defer m.mu.Unlock() + + updatedCacheEntry := createcacheEntry(endpoints) + + if authorityInfo.AuthorityType == authority.ADFS { + // Since we're here, we've made a call to the backend. We want to ensure we're caching + // the latest values from the server. + if cacheEntry, ok := m.cache[authorityInfo.CanonicalAuthorityURI]; ok { + for k := range cacheEntry.ValidForDomainsInList { + updatedCacheEntry.ValidForDomainsInList[k] = true + } + } + domain, err := adfsDomainFromUpn(userPrincipalName) + if err == nil { + updatedCacheEntry.ValidForDomainsInList[domain] = true + } + } + + // Extract aliases from instance discovery metadata and add to cache + for _, metadata := range authorityInfo.InstanceDiscoveryMetadata { + for _, alias := range metadata.Aliases { + updatedCacheEntry.Aliases[alias] = true + } + } + + m.cache[authorityInfo.CanonicalAuthorityURI] = updatedCacheEntry +} + +func (m *authorityEndpoint) openIDConfigurationEndpoint(ctx context.Context, authorityInfo authority.Info) (string, error) { + if authorityInfo.AuthorityType == authority.ADFS { + return fmt.Sprintf("https://%s/adfs/.well-known/openid-configuration", authorityInfo.Host), nil + } else if authorityInfo.AuthorityType == authority.DSTS { + return fmt.Sprintf("https://%s/dstsv2/%s/v2.0/.well-known/openid-configuration", authorityInfo.Host, authority.DSTSTenant), nil + + } else if authorityInfo.ValidateAuthority && !authority.TrustedHost(authorityInfo.Host) { + resp, err := m.rest.Authority().AADInstanceDiscovery(ctx, authorityInfo) + if err != nil { + return "", err + } + authorityInfo.InstanceDiscoveryMetadata = resp.Metadata + return resp.TenantDiscoveryEndpoint, nil + } else if authorityInfo.Region != "" { + resp, err := m.rest.Authority().AADInstanceDiscovery(ctx, authorityInfo) + if err != nil { + return "", err + } + authorityInfo.InstanceDiscoveryMetadata = resp.Metadata + return resp.TenantDiscoveryEndpoint, nil + } + + return authorityInfo.CanonicalAuthorityURI + "v2.0/.well-known/openid-configuration", nil +} + +func adfsDomainFromUpn(userPrincipalName string) (string, error) { + parts := strings.Split(userPrincipalName, "@") + if len(parts) < 2 { + return "", errors.New("no @ present in user principal name") + } + return parts[1], nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/options/options.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/options/options.go new file mode 100644 index 000000000..4561d72db --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/options/options.go @@ -0,0 +1,52 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package options + +import ( + "errors" + "fmt" +) + +// CallOption implements an optional argument to a method call. See +// https://blog.devgenius.io/go-call-option-that-can-be-used-with-multiple-methods-6c81734f3dbe +// for an explanation of the usage pattern. +type CallOption interface { + Do(any) error + callOption() +} + +// ApplyOptions applies all the callOptions to options. options must be a pointer to a struct and +// callOptions must be a list of objects that implement CallOption. +func ApplyOptions[O, C any](options O, callOptions []C) error { + for _, o := range callOptions { + if t, ok := any(o).(CallOption); !ok { + return fmt.Errorf("unexpected option type %T", o) + } else if err := t.Do(options); err != nil { + return err + } + } + return nil +} + +// NewCallOption returns a new CallOption whose Do() method calls function "f". +func NewCallOption(f func(any) error) CallOption { + if f == nil { + // This isn't a practical concern because only an MSAL maintainer can get + // us here, by implementing a do-nothing option. But if someone does that, + // the below ensures the method invoked with the option returns an error. + return callOption(func(any) error { + return errors.New("invalid option: missing implementation") + }) + } + return callOption(f) +} + +// callOption is an adapter for a function to a CallOption +type callOption func(any) error + +func (c callOption) Do(a any) error { + return c(a) +} + +func (callOption) callOption() {} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared/shared.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared/shared.go new file mode 100644 index 000000000..d8ab71356 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared/shared.go @@ -0,0 +1,72 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package shared + +import ( + "net/http" + "reflect" + "strings" +) + +const ( + // CacheKeySeparator is used in creating the keys of the cache. + CacheKeySeparator = "-" +) + +type Account struct { + HomeAccountID string `json:"home_account_id,omitempty"` + Environment string `json:"environment,omitempty"` + Realm string `json:"realm,omitempty"` + LocalAccountID string `json:"local_account_id,omitempty"` + AuthorityType string `json:"authority_type,omitempty"` + PreferredUsername string `json:"username,omitempty"` + GivenName string `json:"given_name,omitempty"` + FamilyName string `json:"family_name,omitempty"` + MiddleName string `json:"middle_name,omitempty"` + Name string `json:"name,omitempty"` + AlternativeID string `json:"alternative_account_id,omitempty"` + RawClientInfo string `json:"client_info,omitempty"` + UserAssertionHash string `json:"user_assertion_hash,omitempty"` + + AdditionalFields map[string]interface{} +} + +// NewAccount creates an account. +func NewAccount(homeAccountID, env, realm, localAccountID, authorityType, username string) Account { + return Account{ + HomeAccountID: homeAccountID, + Environment: env, + Realm: realm, + LocalAccountID: localAccountID, + AuthorityType: authorityType, + PreferredUsername: username, + } +} + +// Key creates the key for storing accounts in the cache. +func (acc Account) Key() string { + key := strings.Join([]string{acc.HomeAccountID, acc.Environment, acc.Realm}, CacheKeySeparator) + return strings.ToLower(key) +} + +// IsZero checks the zero value of account. +func (acc Account) IsZero() bool { + v := reflect.ValueOf(acc) + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + if !field.IsZero() { + switch field.Kind() { + case reflect.Map, reflect.Slice: + if field.Len() == 0 { + continue + } + } + return false + } + } + return true +} + +// DefaultClient is our default shared HTTP client. +var DefaultClient = &http.Client{} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version/version.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version/version.go new file mode 100644 index 000000000..5e551abc8 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version/version.go @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +// Package version keeps the version number of the client package. +package version + +// Version is the version of this client package that is communicated to the server. +const Version = "1.4.2" diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/azure_ml.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/azure_ml.go new file mode 100644 index 000000000..d7cffc295 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/azure_ml.go @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package managedidentity + +import ( + "context" + "net/http" + "os" +) + +func createAzureMLAuthRequest(ctx context.Context, id ID, resource string) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodGet, os.Getenv(msiEndpointEnvVar), nil) + if err != nil { + return nil, err + } + + req.Header.Set("secret", os.Getenv(msiSecretEnvVar)) + q := req.URL.Query() + q.Set(apiVersionQueryParameterName, azureMLAPIVersion) + q.Set(resourceQueryParameterName, resource) + q.Set("clientid", os.Getenv("DEFAULT_IDENTITY_CLIENT_ID")) + if cid, ok := id.(UserAssignedClientID); ok { + q.Set("clientid", string(cid)) + } + req.URL.RawQuery = q.Encode() + return req, nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/cloud_shell.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/cloud_shell.go new file mode 100644 index 000000000..be9a0bca3 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/cloud_shell.go @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package managedidentity + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "os" + "strings" +) + +func createCloudShellAuthRequest(ctx context.Context, resource string) (*http.Request, error) { + msiEndpoint := os.Getenv(msiEndpointEnvVar) + msiEndpointParsed, err := url.Parse(msiEndpoint) + if err != nil { + return nil, fmt.Errorf("couldn't parse %q: %s", msiEndpoint, err) + } + + data := url.Values{} + data.Set(resourceQueryParameterName, resource) + msiDataEncoded := data.Encode() + body := io.NopCloser(strings.NewReader(msiDataEncoded)) + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, msiEndpointParsed.String(), body) + if err != nil { + return nil, fmt.Errorf("error creating http request %s", err) + } + + req.Header.Set(metaHTTPHeaderName, "true") + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + + return req, nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/managedidentity.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/managedidentity.go new file mode 100644 index 000000000..ca3de4325 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/managedidentity.go @@ -0,0 +1,717 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package managedidentity provides a client for retrieval of Managed Identity applications. +The Managed Identity Client is used to acquire a token for managed identity assigned to +an azure resource such as Azure function, app service, virtual machine, etc. to acquire a token +without using credentials. +*/ +package managedidentity + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + "runtime" + "strings" + "sync/atomic" + "time" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops" + "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" +) + +// AuthResult contains the results of one token acquisition operation. +// For details see https://aka.ms/msal-net-authenticationresult +type AuthResult = base.AuthResult + +type TokenSource = base.TokenSource + +const ( + TokenSourceIdentityProvider = base.TokenSourceIdentityProvider + TokenSourceCache = base.TokenSourceCache +) + +const ( + // DefaultToIMDS indicates that the source is defaulted to IMDS when no environment variables are set. + DefaultToIMDS Source = "DefaultToIMDS" + AzureArc Source = "AzureArc" + ServiceFabric Source = "ServiceFabric" + CloudShell Source = "CloudShell" + AzureML Source = "AzureML" + AppService Source = "AppService" + + // General request query parameter names + metaHTTPHeaderName = "Metadata" + apiVersionQueryParameterName = "api-version" + resourceQueryParameterName = "resource" + wwwAuthenticateHeaderName = "www-authenticate" + + // UAMI query parameter name + miQueryParameterClientId = "client_id" + miQueryParameterObjectId = "object_id" + miQueryParameterPrincipalId = "principal_id" + miQueryParameterResourceIdIMDS = "msi_res_id" + miQueryParameterResourceId = "mi_res_id" + + // IMDS + imdsDefaultEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" + imdsAPIVersion = "2018-02-01" + systemAssignedManagedIdentity = "system_assigned_managed_identity" + + // Azure Arc + azureArcEndpoint = "http://127.0.0.1:40342/metadata/identity/oauth2/token" + azureArcAPIVersion = "2020-06-01" + azureArcFileExtension = ".key" + azureArcMaxFileSizeBytes int64 = 4096 + linuxTokenPath = "/var/opt/azcmagent/tokens" // #nosec G101 + linuxHimdsPath = "/opt/azcmagent/bin/himds" + azureConnectedMachine = "AzureConnectedMachineAgent" + himdsExecutableName = "himds.exe" + tokenName = "Tokens" + + // App Service + appServiceAPIVersion = "2019-08-01" + + // AzureML + azureMLAPIVersion = "2017-09-01" + // Service Fabric + serviceFabricAPIVersion = "2019-07-01-preview" + + // Environment Variables + identityEndpointEnvVar = "IDENTITY_ENDPOINT" + identityHeaderEnvVar = "IDENTITY_HEADER" + azurePodIdentityAuthorityHostEnvVar = "AZURE_POD_IDENTITY_AUTHORITY_HOST" + imdsEndVar = "IMDS_ENDPOINT" + msiEndpointEnvVar = "MSI_ENDPOINT" + msiSecretEnvVar = "MSI_SECRET" + identityServerThumbprintEnvVar = "IDENTITY_SERVER_THUMBPRINT" + + defaultRetryCount = 3 +) + +var retryCodesForIMDS = []int{ + http.StatusNotFound, // 404 + http.StatusGone, // 410 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusNotImplemented, // 501 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 + http.StatusHTTPVersionNotSupported, // 505 + http.StatusVariantAlsoNegotiates, // 506 + http.StatusInsufficientStorage, // 507 + http.StatusLoopDetected, // 508 + http.StatusNotExtended, // 510 + http.StatusNetworkAuthenticationRequired, // 511 +} + +var retryStatusCodes = []int{ + http.StatusRequestTimeout, // 408 + http.StatusTooManyRequests, // 429 + http.StatusInternalServerError, // 500 + http.StatusBadGateway, // 502 + http.StatusServiceUnavailable, // 503 + http.StatusGatewayTimeout, // 504 +} + +var getAzureArcPlatformPath = func(platform string) string { + switch platform { + case "windows": + return filepath.Join(os.Getenv("ProgramData"), azureConnectedMachine, tokenName) + case "linux": + return linuxTokenPath + default: + return "" + } +} + +var getAzureArcHimdsFilePath = func(platform string) string { + switch platform { + case "windows": + return filepath.Join(os.Getenv("ProgramData"), azureConnectedMachine, himdsExecutableName) + case "linux": + return linuxHimdsPath + default: + return "" + } +} + +type Source string + +type ID interface { + value() string +} + +type systemAssignedValue string // its private for a reason to make the input consistent. +type UserAssignedClientID string +type UserAssignedObjectID string +type UserAssignedResourceID string + +func (s systemAssignedValue) value() string { return string(s) } +func (c UserAssignedClientID) value() string { return string(c) } +func (o UserAssignedObjectID) value() string { return string(o) } +func (r UserAssignedResourceID) value() string { return string(r) } +func SystemAssigned() ID { + return systemAssignedValue(systemAssignedManagedIdentity) +} + +// cache never uses the client because instance discovery is always disabled. +var cacheManager *storage.Manager = storage.New(nil) + +type Client struct { + httpClient ops.HTTPClient + miType ID + source Source + authParams authority.AuthParams + retryPolicyEnabled bool + canRefresh *atomic.Value +} + +type AcquireTokenOptions struct { + claims string +} + +type ClientOption func(*Client) + +type AcquireTokenOption func(o *AcquireTokenOptions) + +// WithClaims sets additional claims to request for the token, such as those required by token revocation or conditional access policies. +// Use this option when Azure AD returned a claims challenge for a prior request. The argument must be decoded. +func WithClaims(claims string) AcquireTokenOption { + return func(o *AcquireTokenOptions) { + o.claims = claims + } +} + +// WithHTTPClient allows for a custom HTTP client to be set. +func WithHTTPClient(httpClient ops.HTTPClient) ClientOption { + return func(c *Client) { + c.httpClient = httpClient + } +} + +func WithRetryPolicyDisabled() ClientOption { + return func(c *Client) { + c.retryPolicyEnabled = false + } +} + +// Client to be used to acquire tokens for managed identity. +// ID: [SystemAssigned], [UserAssignedClientID], [UserAssignedResourceID], [UserAssignedObjectID] +// +// Options: [WithHTTPClient] +func New(id ID, options ...ClientOption) (Client, error) { + source, err := GetSource() + if err != nil { + return Client{}, err + } + + // Check for user-assigned restrictions based on the source + switch source { + case AzureArc: + switch id.(type) { + case UserAssignedClientID, UserAssignedResourceID, UserAssignedObjectID: + return Client{}, errors.New("Azure Arc doesn't support user-assigned managed identities") + } + case AzureML: + switch id.(type) { + case UserAssignedObjectID, UserAssignedResourceID: + return Client{}, errors.New("Azure ML supports specifying a user-assigned managed identity by client ID only") + } + case CloudShell: + switch id.(type) { + case UserAssignedClientID, UserAssignedResourceID, UserAssignedObjectID: + return Client{}, errors.New("Cloud Shell doesn't support user-assigned managed identities") + } + case ServiceFabric: + switch id.(type) { + case UserAssignedClientID, UserAssignedResourceID, UserAssignedObjectID: + return Client{}, errors.New("Service Fabric API doesn't support specifying a user-assigned identity. The identity is determined by cluster resource configuration. See https://aka.ms/servicefabricmi") + } + } + + switch t := id.(type) { + case UserAssignedClientID: + if len(string(t)) == 0 { + return Client{}, fmt.Errorf("empty %T", t) + } + case UserAssignedResourceID: + if len(string(t)) == 0 { + return Client{}, fmt.Errorf("empty %T", t) + } + case UserAssignedObjectID: + if len(string(t)) == 0 { + return Client{}, fmt.Errorf("empty %T", t) + } + case systemAssignedValue: + default: + return Client{}, fmt.Errorf("unsupported type %T", id) + } + zero := atomic.Value{} + zero.Store(false) + client := Client{ + miType: id, + httpClient: shared.DefaultClient, + retryPolicyEnabled: true, + source: source, + canRefresh: &zero, + } + for _, option := range options { + option(&client) + } + fakeAuthInfo, err := authority.NewInfoFromAuthorityURI("https://login.microsoftonline.com/managed_identity", false, true) + if err != nil { + return Client{}, err + } + client.authParams = authority.NewAuthParams(client.miType.value(), fakeAuthInfo) + return client, nil +} + +// GetSource detects and returns the managed identity source available on the environment. +func GetSource() (Source, error) { + identityEndpoint := os.Getenv(identityEndpointEnvVar) + identityHeader := os.Getenv(identityHeaderEnvVar) + identityServerThumbprint := os.Getenv(identityServerThumbprintEnvVar) + msiEndpoint := os.Getenv(msiEndpointEnvVar) + msiSecret := os.Getenv(msiSecretEnvVar) + imdsEndpoint := os.Getenv(imdsEndVar) + + if identityEndpoint != "" && identityHeader != "" { + if identityServerThumbprint != "" { + return ServiceFabric, nil + } + return AppService, nil + } else if msiEndpoint != "" { + if msiSecret != "" { + return AzureML, nil + } else { + return CloudShell, nil + } + } else if isAzureArcEnvironment(identityEndpoint, imdsEndpoint) { + return AzureArc, nil + } + + return DefaultToIMDS, nil +} + +// This function wraps time.Now() and is used for refreshing the application +// was created to test the function against refreshin +var now = time.Now + +// Acquires tokens from the configured managed identity on an azure resource. +// +// Resource: scopes application is requesting access to +// Options: [WithClaims] +func (c Client) AcquireToken(ctx context.Context, resource string, options ...AcquireTokenOption) (AuthResult, error) { + resource = strings.TrimSuffix(resource, "/.default") + o := AcquireTokenOptions{} + for _, option := range options { + option(&o) + } + c.authParams.Scopes = []string{resource} + + // ignore cached access tokens when given claims + if o.claims == "" { + stResp, err := cacheManager.Read(ctx, c.authParams) + if err != nil { + return AuthResult{}, err + } + ar, err := base.AuthResultFromStorage(stResp) + if err == nil { + if !stResp.AccessToken.RefreshOn.T.IsZero() && !stResp.AccessToken.RefreshOn.T.After(now()) && c.canRefresh.CompareAndSwap(false, true) { + defer c.canRefresh.Store(false) + if tr, er := c.getToken(ctx, resource); er == nil { + return tr, nil + } + } + ar.AccessToken, err = c.authParams.AuthnScheme.FormatAccessToken(ar.AccessToken) + return ar, err + } + } + return c.getToken(ctx, resource) +} + +func (c Client) getToken(ctx context.Context, resource string) (AuthResult, error) { + switch c.source { + case AzureArc: + return c.acquireTokenForAzureArc(ctx, resource) + case AzureML: + return c.acquireTokenForAzureML(ctx, resource) + case CloudShell: + return c.acquireTokenForCloudShell(ctx, resource) + case DefaultToIMDS: + return c.acquireTokenForIMDS(ctx, resource) + case AppService: + return c.acquireTokenForAppService(ctx, resource) + case ServiceFabric: + return c.acquireTokenForServiceFabric(ctx, resource) + default: + return AuthResult{}, fmt.Errorf("unsupported source %q", c.source) + } +} + +func (c Client) acquireTokenForAppService(ctx context.Context, resource string) (AuthResult, error) { + req, err := createAppServiceAuthRequest(ctx, c.miType, resource) + if err != nil { + return AuthResult{}, err + } + tokenResponse, err := c.getTokenForRequest(req, resource) + if err != nil { + return AuthResult{}, err + } + return authResultFromToken(c.authParams, tokenResponse) +} + +func (c Client) acquireTokenForIMDS(ctx context.Context, resource string) (AuthResult, error) { + req, err := createIMDSAuthRequest(ctx, c.miType, resource) + if err != nil { + return AuthResult{}, err + } + tokenResponse, err := c.getTokenForRequest(req, resource) + if err != nil { + return AuthResult{}, err + } + return authResultFromToken(c.authParams, tokenResponse) +} + +func (c Client) acquireTokenForCloudShell(ctx context.Context, resource string) (AuthResult, error) { + req, err := createCloudShellAuthRequest(ctx, resource) + if err != nil { + return AuthResult{}, err + } + tokenResponse, err := c.getTokenForRequest(req, resource) + if err != nil { + return AuthResult{}, err + } + return authResultFromToken(c.authParams, tokenResponse) +} + +func (c Client) acquireTokenForAzureML(ctx context.Context, resource string) (AuthResult, error) { + req, err := createAzureMLAuthRequest(ctx, c.miType, resource) + if err != nil { + return AuthResult{}, err + } + tokenResponse, err := c.getTokenForRequest(req, resource) + if err != nil { + return AuthResult{}, err + } + return authResultFromToken(c.authParams, tokenResponse) +} + +func (c Client) acquireTokenForServiceFabric(ctx context.Context, resource string) (AuthResult, error) { + req, err := createServiceFabricAuthRequest(ctx, resource) + if err != nil { + return AuthResult{}, err + } + tokenResponse, err := c.getTokenForRequest(req, resource) + if err != nil { + return AuthResult{}, err + } + return authResultFromToken(c.authParams, tokenResponse) +} + +func (c Client) acquireTokenForAzureArc(ctx context.Context, resource string) (AuthResult, error) { + req, err := createAzureArcAuthRequest(ctx, resource, "") + if err != nil { + return AuthResult{}, err + } + + response, err := c.httpClient.Do(req) + if err != nil { + return AuthResult{}, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusUnauthorized { + return AuthResult{}, fmt.Errorf("expected a 401 response, received %d", response.StatusCode) + } + + secret, err := c.getAzureArcSecretKey(response, runtime.GOOS) + if err != nil { + return AuthResult{}, err + } + + secondRequest, err := createAzureArcAuthRequest(ctx, resource, string(secret)) + if err != nil { + return AuthResult{}, err + } + + tokenResponse, err := c.getTokenForRequest(secondRequest, resource) + if err != nil { + return AuthResult{}, err + } + return authResultFromToken(c.authParams, tokenResponse) +} + +func authResultFromToken(authParams authority.AuthParams, token accesstokens.TokenResponse) (AuthResult, error) { + if cacheManager == nil { + return AuthResult{}, errors.New("cache instance is nil") + } + account, err := cacheManager.Write(authParams, token) + if err != nil { + return AuthResult{}, err + } + // if refreshOn is not set, set it to half of the time until expiry if expiry is more than 2 hours away + if token.RefreshOn.T.IsZero() { + if lifetime := time.Until(token.ExpiresOn); lifetime > 2*time.Hour { + token.RefreshOn.T = time.Now().Add(lifetime / 2) + } + } + ar, err := base.NewAuthResult(token, account) + if err != nil { + return AuthResult{}, err + } + ar.AccessToken, err = authParams.AuthnScheme.FormatAccessToken(ar.AccessToken) + return ar, err +} + +// contains checks if the element is present in the list. +func contains[T comparable](list []T, element T) bool { + for _, v := range list { + if v == element { + return true + } + } + return false +} + +// retry performs an HTTP request with retries based on the provided options. +func (c Client) retry(maxRetries int, req *http.Request) (*http.Response, error) { + var resp *http.Response + var err error + for attempt := 0; attempt < maxRetries; attempt++ { + tryCtx, tryCancel := context.WithTimeout(req.Context(), time.Minute) + defer tryCancel() + if resp != nil && resp.Body != nil { + _, _ = io.Copy(io.Discard, resp.Body) + resp.Body.Close() + } + cloneReq := req.Clone(tryCtx) + resp, err = c.httpClient.Do(cloneReq) + retrylist := retryStatusCodes + if c.source == DefaultToIMDS { + retrylist = retryCodesForIMDS + } + if err == nil && !contains(retrylist, resp.StatusCode) { + return resp, nil + } + select { + case <-time.After(time.Second): + case <-req.Context().Done(): + err = req.Context().Err() + return resp, err + } + } + return resp, err +} + +func (c Client) getTokenForRequest(req *http.Request, resource string) (accesstokens.TokenResponse, error) { + r := accesstokens.TokenResponse{} + var resp *http.Response + var err error + + if c.retryPolicyEnabled { + resp, err = c.retry(defaultRetryCount, req) + } else { + resp, err = c.httpClient.Do(req) + } + if err != nil { + return r, err + } + responseBytes, err := io.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return r, err + } + switch resp.StatusCode { + case http.StatusOK, http.StatusAccepted: + default: + sd := strings.TrimSpace(string(responseBytes)) + if sd != "" { + return r, errors.CallErr{ + Req: req, + Resp: resp, + Err: fmt.Errorf("http call(%s)(%s) error: reply status code was %d:\n%s", + req.URL.String(), + req.Method, + resp.StatusCode, + sd), + } + } + return r, errors.CallErr{ + Req: req, + Resp: resp, + Err: fmt.Errorf("http call(%s)(%s) error: reply status code was %d", req.URL.String(), req.Method, resp.StatusCode), + } + } + + err = json.Unmarshal(responseBytes, &r) + if err != nil { + return r, errors.InvalidJsonErr{ + Err: fmt.Errorf("error parsing the json error: %s", err), + } + } + r.GrantedScopes.Slice = append(r.GrantedScopes.Slice, resource) + + return r, err +} + +func createAppServiceAuthRequest(ctx context.Context, id ID, resource string) (*http.Request, error) { + identityEndpoint := os.Getenv(identityEndpointEnvVar) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, identityEndpoint, nil) + if err != nil { + return nil, err + } + req.Header.Set("X-IDENTITY-HEADER", os.Getenv(identityHeaderEnvVar)) + q := req.URL.Query() + q.Set("api-version", appServiceAPIVersion) + q.Set("resource", resource) + switch t := id.(type) { + case UserAssignedClientID: + q.Set(miQueryParameterClientId, string(t)) + case UserAssignedResourceID: + q.Set(miQueryParameterResourceId, string(t)) + case UserAssignedObjectID: + q.Set(miQueryParameterObjectId, string(t)) + case systemAssignedValue: + default: + return nil, fmt.Errorf("unsupported type %T", id) + } + req.URL.RawQuery = q.Encode() + return req, nil +} + +func createIMDSAuthRequest(ctx context.Context, id ID, resource string) (*http.Request, error) { + msiEndpoint, err := url.Parse(imdsDefaultEndpoint) + if err != nil { + return nil, fmt.Errorf("couldn't parse %q: %s", imdsDefaultEndpoint, err) + } + msiParameters := msiEndpoint.Query() + msiParameters.Set(apiVersionQueryParameterName, imdsAPIVersion) + msiParameters.Set(resourceQueryParameterName, resource) + + switch t := id.(type) { + case UserAssignedClientID: + msiParameters.Set(miQueryParameterClientId, string(t)) + case UserAssignedResourceID: + msiParameters.Set(miQueryParameterResourceIdIMDS, string(t)) + case UserAssignedObjectID: + msiParameters.Set(miQueryParameterObjectId, string(t)) + case systemAssignedValue: // not adding anything + default: + return nil, fmt.Errorf("unsupported type %T", id) + } + + msiEndpoint.RawQuery = msiParameters.Encode() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, msiEndpoint.String(), nil) + if err != nil { + return nil, fmt.Errorf("error creating http request %s", err) + } + req.Header.Set(metaHTTPHeaderName, "true") + return req, nil +} + +func createAzureArcAuthRequest(ctx context.Context, resource string, key string) (*http.Request, error) { + identityEndpoint := os.Getenv(identityEndpointEnvVar) + if identityEndpoint == "" { + identityEndpoint = azureArcEndpoint + } + msiEndpoint, parseErr := url.Parse(identityEndpoint) + + if parseErr != nil { + return nil, fmt.Errorf("couldn't parse %q: %s", identityEndpoint, parseErr) + } + + msiParameters := msiEndpoint.Query() + msiParameters.Set(apiVersionQueryParameterName, azureArcAPIVersion) + msiParameters.Set(resourceQueryParameterName, resource) + + msiEndpoint.RawQuery = msiParameters.Encode() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, msiEndpoint.String(), nil) + if err != nil { + return nil, fmt.Errorf("error creating http request %s", err) + } + req.Header.Set(metaHTTPHeaderName, "true") + + if key != "" { + req.Header.Set("Authorization", fmt.Sprintf("Basic %s", key)) + } + + return req, nil +} + +func isAzureArcEnvironment(identityEndpoint, imdsEndpoint string) bool { + if identityEndpoint != "" && imdsEndpoint != "" { + return true + } + himdsFilePath := getAzureArcHimdsFilePath(runtime.GOOS) + if himdsFilePath != "" { + if _, err := os.Stat(himdsFilePath); err == nil { + return true + } + } + return false +} + +func (c *Client) getAzureArcSecretKey(response *http.Response, platform string) (string, error) { + wwwAuthenticateHeader := response.Header.Get(wwwAuthenticateHeaderName) + + if len(wwwAuthenticateHeader) == 0 { + return "", errors.New("response has no www-authenticate header") + } + + // check if the platform is supported + expectedSecretFilePath := getAzureArcPlatformPath(platform) + if expectedSecretFilePath == "" { + return "", errors.New("platform not supported, expected linux or windows") + } + + parts := strings.Split(wwwAuthenticateHeader, "Basic realm=") + if len(parts) < 2 { + return "", fmt.Errorf("basic realm= not found in the string, instead found: %s", wwwAuthenticateHeader) + } + + secretFilePath := parts + + // check that the file in the file path is a .key file + fileName := filepath.Base(secretFilePath[1]) + if !strings.HasSuffix(fileName, azureArcFileExtension) { + return "", fmt.Errorf("invalid file extension, expected %s, got %s", azureArcFileExtension, filepath.Ext(fileName)) + } + + // check that file path from header matches the expected file path for the platform + if expectedSecretFilePath != filepath.Dir(secretFilePath[1]) { + return "", fmt.Errorf("invalid file path, expected %s, got %s", expectedSecretFilePath, filepath.Dir(secretFilePath[1])) + } + + fileInfo, err := os.Stat(secretFilePath[1]) + if err != nil { + return "", fmt.Errorf("failed to get metadata for %s due to error: %s", secretFilePath[1], err) + } + + // Throw an error if the secret file's size is greater than 4096 bytes + if s := fileInfo.Size(); s > azureArcMaxFileSizeBytes { + return "", fmt.Errorf("invalid secret file size, expected %d, file size was %d", azureArcMaxFileSizeBytes, s) + } + + // Attempt to read the contents of the secret file + secret, err := os.ReadFile(secretFilePath[1]) + if err != nil { + return "", fmt.Errorf("failed to read %q due to error: %s", secretFilePath[1], err) + } + + return string(secret), nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/servicefabric.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/servicefabric.go new file mode 100644 index 000000000..535065e9d --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity/servicefabric.go @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +package managedidentity + +import ( + "context" + "net/http" + "os" +) + +func createServiceFabricAuthRequest(ctx context.Context, resource string) (*http.Request, error) { + identityEndpoint := os.Getenv(identityEndpointEnvVar) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, identityEndpoint, nil) + if err != nil { + return nil, err + } + req.Header.Set("Accept", "application/json") + req.Header.Set("Secret", os.Getenv(identityHeaderEnvVar)) + q := req.URL.Query() + q.Set("api-version", serviceFabricAPIVersion) + q.Set("resource", resource) + req.URL.RawQuery = q.Encode() + return req, nil +} diff --git a/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/public/public.go b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/public/public.go new file mode 100644 index 000000000..7beed2617 --- /dev/null +++ b/vendor/github.com/AzureAD/microsoft-authentication-library-for-go/apps/public/public.go @@ -0,0 +1,763 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +/* +Package public provides a client for authentication of "public" applications. A "public" +application is defined as an app that runs on client devices (android, ios, windows, linux, ...). +These devices are "untrusted" and access resources via web APIs that must authenticate. +*/ +package public + +/* +Design note: + +public.Client uses client.Base as an embedded type. client.Base statically assigns its attributes +during creation. As it doesn't have any pointers in it, anything borrowed from it, such as +Base.AuthParams is a copy that is free to be manipulated here. +*/ + +// TODO(msal): This should have example code for each method on client using Go's example doc framework. +// base usage details should be includee in the package documentation. + +import ( + "context" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "net/url" + "reflect" + "strconv" + + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops" + "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/options" + "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared" + "github.com/google/uuid" + "github.com/pkg/browser" +) + +// AuthResult contains the results of one token acquisition operation. +// For details see https://aka.ms/msal-net-authenticationresult +type AuthResult = base.AuthResult + +type AuthenticationScheme = authority.AuthenticationScheme + +type Account = shared.Account + +type TokenSource = base.TokenSource + +const ( + TokenSourceIdentityProvider = base.TokenSourceIdentityProvider + TokenSourceCache = base.TokenSourceCache +) + +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 { + accessor cache.ExportReplace + authority string + capabilities []string + disableInstanceDiscovery bool + httpClient ops.HTTPClient +} + +func (p *clientOptions) validate() error { + u, err := url.Parse(p.authority) + if err != nil { + return fmt.Errorf("Authority options cannot be URL parsed: %w", err) + } + if u.Scheme != "https" { + return fmt.Errorf("Authority(%s) did not start with https://", u.String()) + } + return nil +} + +// Option is an optional argument to the New constructor. +type Option func(o *clientOptions) + +// WithAuthority allows for a custom authority to be set. This must be a valid https url. +func WithAuthority(authority string) Option { + return func(o *clientOptions) { + o.authority = authority + } +} + +// WithCache provides an accessor that will read and write authentication data to an externally managed cache. +func WithCache(accessor cache.ExportReplace) Option { + return func(o *clientOptions) { + o.accessor = accessor + } +} + +// WithClientCapabilities allows configuring one or more client capabilities such as "CP1" +func WithClientCapabilities(capabilities []string) Option { + return func(o *clientOptions) { + // there's no danger of sharing the slice's underlying memory with the application because + // this slice is simply passed to base.WithClientCapabilities, which copies its data + o.capabilities = capabilities + } +} + +// WithHTTPClient allows for a custom HTTP client to be set. +func WithHTTPClient(httpClient ops.HTTPClient) Option { + return func(o *clientOptions) { + o.httpClient = httpClient + } +} + +// WithInstanceDiscovery set to false to disable authority validation (to support private cloud scenarios) +func WithInstanceDiscovery(enabled bool) Option { + return func(o *clientOptions) { + o.disableInstanceDiscovery = !enabled + } +} + +// Client is a representation of authentication client for public applications as defined in the +// package doc. For more information, visit https://docs.microsoft.com/azure/active-directory/develop/msal-client-applications. +type Client struct { + base base.Client +} + +// New is the constructor for Client. +func New(clientID string, options ...Option) (Client, error) { + opts := clientOptions{ + authority: base.AuthorityPublicCloud, + httpClient: shared.DefaultClient, + } + + for _, o := range options { + o(&opts) + } + if err := opts.validate(); err != nil { + return Client{}, err + } + + base, err := base.New(clientID, opts.authority, oauth.New(opts.httpClient), base.WithCacheAccessor(opts.accessor), base.WithClientCapabilities(opts.capabilities), base.WithInstanceDiscovery(!opts.disableInstanceDiscovery)) + if err != nil { + return Client{}, err + } + return Client{base}, nil +} + +// authCodeURLOptions contains options for AuthCodeURL +type authCodeURLOptions struct { + claims, loginHint, tenantID, domainHint string +} + +// AuthCodeURLOption is implemented by options for AuthCodeURL +type AuthCodeURLOption interface { + authCodeURLOption() +} + +// AuthCodeURL creates a URL used to acquire an authorization code. +// +// Options: [WithClaims], [WithDomainHint], [WithLoginHint], [WithTenantID] +func (pca Client) AuthCodeURL(ctx context.Context, clientID, redirectURI string, scopes []string, opts ...AuthCodeURLOption) (string, error) { + o := authCodeURLOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return "", err + } + ap, err := pca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return "", err + } + ap.Claims = o.claims + ap.LoginHint = o.loginHint + ap.DomainHint = o.domainHint + return pca.base.AuthCodeURL(ctx, clientID, redirectURI, scopes, ap) +} + +// WithClaims sets additional claims to request for the token, such as those required by conditional access policies. +// Use this option when Azure AD returned a claims challenge for a prior request. The argument must be decoded. +// This option is valid for any token acquisition method. +func WithClaims(claims string) interface { + AcquireByAuthCodeOption + AcquireByDeviceCodeOption + AcquireByUsernamePasswordOption + AcquireInteractiveOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption +} { + return struct { + AcquireByAuthCodeOption + AcquireByDeviceCodeOption + AcquireByUsernamePasswordOption + AcquireInteractiveOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenByAuthCodeOptions: + t.claims = claims + case *acquireTokenByDeviceCodeOptions: + t.claims = claims + case *acquireTokenByUsernamePasswordOptions: + t.claims = claims + case *acquireTokenSilentOptions: + t.claims = claims + case *authCodeURLOptions: + t.claims = claims + case *interactiveAuthOptions: + t.claims = claims + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// 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 + AcquireByUsernamePasswordOption + options.CallOption +} { + return struct { + AcquireSilentOption + AcquireInteractiveOption + AcquireByUsernamePasswordOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenSilentOptions: + t.authnScheme = authnScheme + case *interactiveAuthOptions: + t.authnScheme = authnScheme + case *acquireTokenByUsernamePasswordOptions: + 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 { + AcquireByAuthCodeOption + AcquireByDeviceCodeOption + AcquireByUsernamePasswordOption + AcquireInteractiveOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption +} { + return struct { + AcquireByAuthCodeOption + AcquireByDeviceCodeOption + AcquireByUsernamePasswordOption + AcquireInteractiveOption + AcquireSilentOption + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenByAuthCodeOptions: + t.tenantID = tenantID + case *acquireTokenByDeviceCodeOptions: + t.tenantID = tenantID + case *acquireTokenByUsernamePasswordOptions: + t.tenantID = tenantID + case *acquireTokenSilentOptions: + t.tenantID = tenantID + case *authCodeURLOptions: + t.tenantID = tenantID + case *interactiveAuthOptions: + t.tenantID = tenantID + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// acquireTokenSilentOptions are all the optional settings to an AcquireTokenSilent() call. +// These are set by using various AcquireTokenSilentOption functions. +type acquireTokenSilentOptions struct { + account Account + claims, tenantID string + authnScheme AuthenticationScheme +} + +// AcquireSilentOption is implemented by options for AcquireTokenSilent +type AcquireSilentOption interface { + acquireSilentOption() +} + +// WithSilentAccount uses the passed account during an AcquireTokenSilent() call. +func WithSilentAccount(account Account) interface { + AcquireSilentOption + options.CallOption +} { + return struct { + AcquireSilentOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenSilentOptions: + t.account = account + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// AcquireTokenSilent acquires a token from either the cache or using a refresh token. +// +// Options: [WithClaims], [WithSilentAccount], [WithTenantID] +func (pca Client) AcquireTokenSilent(ctx context.Context, scopes []string, opts ...AcquireSilentOption) (AuthResult, error) { + o := acquireTokenSilentOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + // an account is required to find user tokens in the cache + if reflect.ValueOf(o.account).IsZero() { + return AuthResult{}, errNoAccount + } + + silentParameters := base.AcquireTokenSilentParameters{ + Scopes: scopes, + Account: o.account, + Claims: o.claims, + RequestType: accesstokens.ATPublic, + IsAppCache: false, + TenantID: o.tenantID, + AuthnScheme: o.authnScheme, + } + + return pca.base.AcquireTokenSilent(ctx, silentParameters) +} + +// acquireTokenByUsernamePasswordOptions contains optional configuration for AcquireTokenByUsernamePassword +type acquireTokenByUsernamePasswordOptions struct { + claims, tenantID string + authnScheme AuthenticationScheme +} + +// AcquireByUsernamePasswordOption is implemented by options for AcquireTokenByUsernamePassword +type AcquireByUsernamePasswordOption interface { + acquireByUsernamePasswordOption() +} + +// AcquireTokenByUsernamePassword acquires a security token from the authority, via Username/Password Authentication. +// NOTE: this flow is NOT recommended. +// +// Options: [WithClaims], [WithTenantID] +func (pca Client) AcquireTokenByUsernamePassword(ctx context.Context, scopes []string, username, password string, opts ...AcquireByUsernamePasswordOption) (AuthResult, error) { + o := acquireTokenByUsernamePasswordOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + authParams, err := pca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return AuthResult{}, err + } + authParams.Scopes = scopes + authParams.AuthorizationType = authority.ATUsernamePassword + authParams.Claims = o.claims + authParams.Username = username + authParams.Password = password + if o.authnScheme != nil { + authParams.AuthnScheme = o.authnScheme + } + + token, err := pca.base.Token.UsernamePassword(ctx, authParams) + if err != nil { + return AuthResult{}, err + } + return pca.base.AuthResultFromToken(ctx, authParams, token) +} + +type DeviceCodeResult = accesstokens.DeviceCodeResult + +// DeviceCode provides the results of the device code flows first stage (containing the code) +// that must be entered on the second device and provides a method to retrieve the AuthenticationResult +// once that code has been entered and verified. +type DeviceCode struct { + // Result holds the information about the device code (such as the code). + Result DeviceCodeResult + + authParams authority.AuthParams + client Client + dc oauth.DeviceCode +} + +// AuthenticationResult retreives the AuthenticationResult once the user enters the code +// on the second device. Until then it blocks until the .AcquireTokenByDeviceCode() context +// is cancelled or the token expires. +func (d DeviceCode) AuthenticationResult(ctx context.Context) (AuthResult, error) { + token, err := d.dc.Token(ctx) + if err != nil { + return AuthResult{}, err + } + return d.client.base.AuthResultFromToken(ctx, d.authParams, token) +} + +// acquireTokenByDeviceCodeOptions contains optional configuration for AcquireTokenByDeviceCode +type acquireTokenByDeviceCodeOptions struct { + claims, tenantID string +} + +// AcquireByDeviceCodeOption is implemented by options for AcquireTokenByDeviceCode +type AcquireByDeviceCodeOption interface { + acquireByDeviceCodeOptions() +} + +// AcquireTokenByDeviceCode acquires a security token from the authority, by acquiring a device code and using that to acquire the token. +// Users need to create an AcquireTokenDeviceCodeParameters instance and pass it in. +// +// Options: [WithClaims], [WithTenantID] +func (pca Client) AcquireTokenByDeviceCode(ctx context.Context, scopes []string, opts ...AcquireByDeviceCodeOption) (DeviceCode, error) { + o := acquireTokenByDeviceCodeOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return DeviceCode{}, err + } + authParams, err := pca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return DeviceCode{}, err + } + authParams.Scopes = scopes + authParams.AuthorizationType = authority.ATDeviceCode + authParams.Claims = o.claims + + dc, err := pca.base.Token.DeviceCode(ctx, authParams) + if err != nil { + return DeviceCode{}, err + } + + return DeviceCode{Result: dc.Result, authParams: authParams, client: pca, dc: dc}, nil +} + +// acquireTokenByAuthCodeOptions contains the optional parameters used to acquire an access token using the authorization code flow. +type acquireTokenByAuthCodeOptions struct { + challenge, claims, tenantID string +} + +// AcquireByAuthCodeOption is implemented by options for AcquireTokenByAuthCode +type AcquireByAuthCodeOption interface { + acquireByAuthCodeOption() +} + +// WithChallenge allows you to provide a code for the .AcquireTokenByAuthCode() call. +func WithChallenge(challenge string) interface { + AcquireByAuthCodeOption + options.CallOption +} { + return struct { + AcquireByAuthCodeOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *acquireTokenByAuthCodeOptions: + t.challenge = challenge + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// AcquireTokenByAuthCode is a request to acquire a security token from the authority, using an authorization code. +// The specified redirect URI must be the same URI that was used when the authorization code was requested. +// +// Options: [WithChallenge], [WithClaims], [WithTenantID] +func (pca Client) AcquireTokenByAuthCode(ctx context.Context, code string, redirectURI string, scopes []string, opts ...AcquireByAuthCodeOption) (AuthResult, error) { + o := acquireTokenByAuthCodeOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + + params := base.AcquireTokenAuthCodeParameters{ + Scopes: scopes, + Code: code, + Challenge: o.challenge, + Claims: o.claims, + AppType: accesstokens.ATPublic, + RedirectURI: redirectURI, + TenantID: o.tenantID, + } + + return pca.base.AcquireTokenByAuthCode(ctx, params) +} + +// Accounts gets all the accounts in the token cache. +// If there are no accounts in the cache the returned slice is empty. +func (pca Client) Accounts(ctx context.Context) ([]Account, error) { + return pca.base.AllAccounts(ctx) +} + +// RemoveAccount signs the account out and forgets account from token cache. +func (pca Client) RemoveAccount(ctx context.Context, account Account) error { + return pca.base.RemoveAccount(ctx, account) +} + +// interactiveAuthOptions contains the optional parameters used to acquire an access token for interactive auth code flow. +type interactiveAuthOptions struct { + claims, domainHint, loginHint, redirectURI, tenantID string + openURL func(url string) error + authnScheme AuthenticationScheme +} + +// AcquireInteractiveOption is implemented by options for AcquireTokenInteractive +type AcquireInteractiveOption interface { + acquireInteractiveOption() +} + +// WithLoginHint pre-populates the login prompt with a username. +func WithLoginHint(username string) interface { + AcquireInteractiveOption + AuthCodeURLOption + options.CallOption +} { + return struct { + AcquireInteractiveOption + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *authCodeURLOptions: + t.loginHint = username + case *interactiveAuthOptions: + t.loginHint = username + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// WithDomainHint adds the IdP domain as domain_hint query parameter in the auth url. +func WithDomainHint(domain string) interface { + AcquireInteractiveOption + AuthCodeURLOption + options.CallOption +} { + return struct { + AcquireInteractiveOption + AuthCodeURLOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *authCodeURLOptions: + t.domainHint = domain + case *interactiveAuthOptions: + t.domainHint = domain + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// WithRedirectURI sets a port for the local server used in interactive authentication, for +// example http://localhost:port. All URI components other than the port are ignored. +func WithRedirectURI(redirectURI string) interface { + AcquireInteractiveOption + options.CallOption +} { + return struct { + AcquireInteractiveOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *interactiveAuthOptions: + t.redirectURI = redirectURI + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// WithOpenURL allows you to provide a function to open the browser to complete the interactive login, instead of launching the system default browser. +func WithOpenURL(openURL func(url string) error) interface { + AcquireInteractiveOption + options.CallOption +} { + return struct { + AcquireInteractiveOption + options.CallOption + }{ + CallOption: options.NewCallOption( + func(a any) error { + switch t := a.(type) { + case *interactiveAuthOptions: + t.openURL = openURL + default: + return fmt.Errorf("unexpected options type %T", a) + } + return nil + }, + ), + } +} + +// AcquireTokenInteractive acquires a security token from the authority using the default web browser to select the account. +// https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-authentication-flows#interactive-and-non-interactive-authentication +// +// Options: [WithDomainHint], [WithLoginHint], [WithOpenURL], [WithRedirectURI], [WithTenantID] +func (pca Client) AcquireTokenInteractive(ctx context.Context, scopes []string, opts ...AcquireInteractiveOption) (AuthResult, error) { + o := interactiveAuthOptions{} + if err := options.ApplyOptions(&o, opts); err != nil { + return AuthResult{}, err + } + // the code verifier is a random 32-byte sequence that's been base-64 encoded without padding. + // it's used to prevent MitM attacks during auth code flow, see https://tools.ietf.org/html/rfc7636 + cv, challenge, err := codeVerifier() + if err != nil { + return AuthResult{}, err + } + var redirectURL *url.URL + if o.redirectURI != "" { + redirectURL, err = url.Parse(o.redirectURI) + if err != nil { + return AuthResult{}, err + } + } + if o.openURL == nil { + o.openURL = browser.OpenURL + } + authParams, err := pca.base.AuthParams.WithTenant(o.tenantID) + if err != nil { + return AuthResult{}, err + } + authParams.Scopes = scopes + authParams.AuthorizationType = authority.ATInteractive + authParams.Claims = o.claims + authParams.CodeChallenge = challenge + authParams.CodeChallengeMethod = "S256" + authParams.LoginHint = o.loginHint + 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 + } + authParams.Redirecturi = res.redirectURI + + req, err := accesstokens.NewCodeChallengeRequest(authParams, accesstokens.ATPublic, nil, res.authCode, cv) + if err != nil { + return AuthResult{}, err + } + + token, err := pca.base.Token.AuthCode(ctx, req) + if err != nil { + return AuthResult{}, err + } + + return pca.base.AuthResultFromToken(ctx, authParams, token) +} + +type interactiveAuthResult struct { + authCode string + redirectURI string +} + +// parses the port number from the provided URL. +// returns 0 if nil or no port is specified. +func parsePort(u *url.URL) (int, error) { + if u == nil { + return 0, nil + } + p := u.Port() + if p == "" { + return 0, nil + } + return strconv.Atoi(p) +} + +// browserLogin calls openURL and waits for a user to log in +func (pca Client) browserLogin(ctx context.Context, redirectURI *url.URL, params authority.AuthParams, openURL func(string) error) (interactiveAuthResult, error) { + // start local redirect server so login can call us back + port, err := parsePort(redirectURI) + if err != nil { + return interactiveAuthResult{}, err + } + srv, err := local.New(params.State, port) + if err != nil { + return interactiveAuthResult{}, err + } + defer srv.Shutdown() + params.Scopes = accesstokens.AppendDefaultScopes(params) + authURL, err := pca.base.AuthCodeURL(ctx, params.ClientID, srv.Addr, params.Scopes, params) + if err != nil { + return interactiveAuthResult{}, err + } + // open browser window so user can select credentials + if err := openURL(authURL); err != nil { + return interactiveAuthResult{}, err + } + // now wait until the logic calls us back + res := srv.Result(ctx) + if res.Err != nil { + return interactiveAuthResult{}, res.Err + } + return interactiveAuthResult{ + authCode: res.Code, + redirectURI: srv.Addr, + }, nil +} + +// creates a code verifier string along with its SHA256 hash which +// is used as the challenge when requesting an auth code. +// used in interactive auth flow for PKCE. +func codeVerifier() (codeVerifier string, challenge string, err error) { + cvBytes := make([]byte, 32) + if _, err = rand.Read(cvBytes); err != nil { + return + } + codeVerifier = base64.RawURLEncoding.EncodeToString(cvBytes) + // for PKCE, create a hash of the code verifier + cvh := sha256.Sum256([]byte(codeVerifier)) + challenge = base64.RawURLEncoding.EncodeToString(cvh[:]) + return +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/.gitignore b/vendor/github.com/golang-jwt/jwt/v5/.gitignore new file mode 100644 index 000000000..09573e016 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bin +.idea/ + diff --git a/vendor/github.com/golang-jwt/jwt/v5/LICENSE b/vendor/github.com/golang-jwt/jwt/v5/LICENSE new file mode 100644 index 000000000..35dbc2520 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) 2012 Dave Grijalva +Copyright (c) 2021 golang-jwt maintainers + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md new file mode 100644 index 000000000..b3178e751 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/MIGRATION_GUIDE.md @@ -0,0 +1,195 @@ +# Migration Guide (v5.0.0) + +Version `v5` contains a major rework of core functionalities in the `jwt-go` +library. This includes support for several validation options as well as a +re-design of the `Claims` interface. Lastly, we reworked how errors work under +the hood, which should provide a better overall developer experience. + +Starting from [v5.0.0](https://github.com/golang-jwt/jwt/releases/tag/v5.0.0), +the import path will be: + + "github.com/golang-jwt/jwt/v5" + +For most users, changing the import path *should* suffice. However, since we +intentionally changed and cleaned some of the public API, existing programs +might need to be updated. The following sections describe significant changes +and corresponding updates for existing programs. + +## Parsing and Validation Options + +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 +and changes are: + * Added `WithLeeway` to support specifying the leeway that is allowed when + validating time-based claims, such as `exp` or `nbf`. + * Changed default behavior to not check the `iat` claim. Usage of this claim + is OPTIONAL according to the JWT RFC. The claim itself is also purely + informational according to the RFC, so a strict validation failure is not + recommended. If you want to check for sensible values in these claims, + please use the `WithIssuedAt` parser option. + * Added `WithAudience`, `WithSubject` and `WithIssuer` to support checking for + expected `aud`, `sub` and `iss`. + * Added `WithStrictDecoding` and `WithPaddingAllowed` options to allow + previously global settings to enable base64 strict encoding and the parsing + of base64 strings with padding. The latter is strictly speaking against the + standard, but unfortunately some of the major identity providers issue some + of these incorrect tokens. Both options are disabled by default. + +## Changes to the `Claims` interface + +### Complete Restructuring + +Previously, the claims interface was satisfied with an implementation of a +`Valid() error` function. This had several issues: + * The different claim types (struct claims, map claims, etc.) then contained + similar (but not 100 % identical) code of how this validation was done. This + lead to a lot of (almost) duplicate code and was hard to maintain + * It was not really semantically close to what a "claim" (or a set of claims) + really is; which is a list of defined key/value pairs with a certain + semantic meaning. + +Since all the validation functionality is now extracted into the validator, all +`VerifyXXX` and `Valid` functions have been removed from the `Claims` interface. +Instead, the interface now represents a list of getters to retrieve values with +a specific meaning. This allows us to completely decouple the validation logic +with the underlying storage representation of the claim, which could be a +struct, a map or even something stored in a database. + +```go +type Claims interface { + GetExpirationTime() (*NumericDate, error) + GetIssuedAt() (*NumericDate, error) + GetNotBefore() (*NumericDate, error) + GetIssuer() (string, error) + GetSubject() (string, error) + GetAudience() (ClaimStrings, error) +} +``` + +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 +`RegisteredClaims` both implement the necessary functions of this interface. The +old `StandardClaims` struct, which has already been deprecated in `v4` is now +removed. + +Users using custom claims, in most cases, will not experience any changes in the +behavior as long as they embedded `RegisteredClaims`. If they created a new +claim type from scratch, they now need to implemented the proper getter +functions. + +### Migrating Application Specific Logic of the old `Valid` + +Previously, users could override the `Valid` method in a custom claim, for +example to extend the validation with application-specific claims. However, this +was always very dangerous, since once could easily disable the standard +validation and signature checking. + +In order to avoid that, while still supporting the use-case, a new +`ClaimsValidator` interface has been introduced. This interface consists of the +`Validate() error` function. If the validator sees, that a `Claims` struct +implements this interface, the errors returned to the `Validate` function will +be *appended* to the regular standard validation. It is not possible to disable +the standard validation anymore (even only by accident). + +Usage examples can be found in [example_test.go](./example_test.go), to build +claims structs like the following. + +```go +// MyCustomClaims includes all registered claims, plus Foo. +type MyCustomClaims struct { + Foo string `json:"foo"` + jwt.RegisteredClaims +} + +// Validate can be used to execute additional application-specific claims +// validation. +func (m MyCustomClaims) Validate() error { + if m.Foo != "bar" { + return errors.New("must be foobar") + } + + return nil +} +``` + +## Changes to the `Token` and `Parser` struct + +The previously global functions `DecodeSegment` and `EncodeSegment` were moved +to the `Parser` and `Token` struct respectively. This will allow us in the +future to configure the behavior of these two based on options supplied on the +parser or the token (creation). This also removes two previously global +variables and moves them to parser options `WithStrictDecoding` and +`WithPaddingAllowed`. + +In order to do that, we had to adjust the way signing methods work. Previously +they were given a base64 encoded signature in `Verify` and were expected to +return a base64 encoded version of the signature in `Sign`, both as a `string`. +However, this made it necessary to have `DecodeSegment` and `EncodeSegment` +global and was a less than perfect design because we were repeating +encoding/decoding steps for all signing methods. Now, `Sign` and `Verify` +operate on a decoded signature as a `[]byte`, which feels more natural for a +cryptographic operation anyway. Lastly, `Parse` and `SignedString` take care of +the final encoding/decoding part. + +In addition to that, we also changed the `Signature` field on `Token` from a +`string` to `[]byte` and this is also now populated with the decoded form. This +is also more consistent, because the other parts of the JWT, mainly `Header` and +`Claims` were already stored in decoded form in `Token`. Only the signature was +stored in base64 encoded form, which was redundant with the information in the +`Raw` field, which contains the complete token as base64. + +```go +type Token struct { + Raw string // Raw contains the raw token + Method SigningMethod // Method is the signing method used or to be used + Header map[string]any // Header is the first segment of the token in decoded form + Claims Claims // Claims is the second segment of the token in decoded form + Signature []byte // Signature is the third segment of the token in decoded form + Valid bool // Valid specifies if the token is valid +} +``` + +Most (if not all) of these changes should not impact the normal usage of this +library. Only users directly accessing the `Signature` field as well as +developers of custom signing methods should be affected. + +# Migration Guide (v4.0.0) + +Starting from [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0), +the import path will be: + + "github.com/golang-jwt/jwt/v4" + +The `/v4` version will be backwards compatible with existing `v3.x.y` tags in +this repo, as well as `github.com/dgrijalva/jwt-go`. For most users this should +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/v4`, either manually +or by using tools such as `sed` or `gofmt`. + +And then you'd typically run: + +``` +go get github.com/golang-jwt/jwt/v4 +go mod tidy +``` + +# Older releases (before v3.2.0) + +The original migration guide for older releases can be found at +https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md. diff --git a/vendor/github.com/golang-jwt/jwt/v5/README.md b/vendor/github.com/golang-jwt/jwt/v5/README.md new file mode 100644 index 000000000..0bb636f22 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/README.md @@ -0,0 +1,167 @@ +# jwt-go + +[![build](https://github.com/golang-jwt/jwt/actions/workflows/build.yml/badge.svg)](https://github.com/golang-jwt/jwt/actions/workflows/build.yml) +[![Go +Reference](https://pkg.go.dev/badge/github.com/golang-jwt/jwt/v5.svg)](https://pkg.go.dev/github.com/golang-jwt/jwt/v5) +[![Coverage Status](https://coveralls.io/repos/github/golang-jwt/jwt/badge.svg?branch=main)](https://coveralls.io/github/golang-jwt/jwt?branch=main) + +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) +implementation of [JSON Web +Tokens](https://datatracker.ietf.org/doc/html/rfc7519). + +Starting with [v4.0.0](https://github.com/golang-jwt/jwt/releases/tag/v4.0.0) +this project adds Go module support, but maintains backward compatibility with +older `v3.x.y` tags and upstream `github.com/dgrijalva/jwt-go`. See the +[`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information. Version +v5.0.0 introduces major improvements to the validation of tokens, but is not +entirely backward compatible. + +> After the original author of the library suggested migrating the maintenance +> of `jwt-go`, a dedicated team of open source maintainers decided to clone the +> existing library into this repository. See +> [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a +> detailed discussion on this topic. + + +**SECURITY NOTICE:** Some older versions of Go have a security issue in the +crypto/elliptic. The recommendation is to upgrade to at least 1.15 See issue +[dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more +detail. + +**SECURITY NOTICE:** It's important that you [validate the `alg` presented is +what you +expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). +This library attempts to make it easy to do the right thing by requiring key +types to match the expected alg, but you should take the extra step to verify it in +your usage. See the examples provided. + +### Supported Go versions + +Our support of Go versions is aligned with Go's [version release +policy](https://golang.org/doc/devel/release#policy). So we will support a major +version of Go until there are two newer major releases. We no longer support +building jwt-go with unsupported Go versions, as these contain security +vulnerabilities that will not be fixed. + +## What the heck is a JWT? + +JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web +Tokens. + +In short, it's a signed JSON object that does something useful (for example, +authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is +made of three parts, separated by `.`'s. The first two parts are JSON objects, +that have been [base64url](https://datatracker.ietf.org/doc/html/rfc4648) +encoded. The last part is the signature, encoded the same way. + +The first part is called the header. It contains the necessary information for +verifying the last part, the signature. For example, which encryption method +was used for signing and what key was used. + +The part in the middle is the interesting bit. It's called the Claims and +contains the actual stuff you care about. Refer to [RFC +7519](https://datatracker.ietf.org/doc/html/rfc7519) for information about +reserved keys and the proper way to add your own. + +## What's in the box? + +This library supports the parsing and verification as well as the generation and +signing of JWTs. Current supported signing algorithms are HMAC SHA, RSA, +RSA-PSS, and ECDSA, though hooks are present for adding your own. + +## Installation Guidelines + +1. To install the jwt package, you first need to have + [Go](https://go.dev/doc/install) installed, then you can use the command + below to add `jwt-go` as a dependency in your Go program. + +```sh +go get -u github.com/golang-jwt/jwt/v5 +``` + +2. Import it in your code: + +```go +import "github.com/golang-jwt/jwt/v5" +``` + +## Usage + +A detailed usage guide, including how to sign and verify tokens can be found on +our [documentation website](https://golang-jwt.github.io/jwt/usage/create/). + +## Examples + +See [the project documentation](https://pkg.go.dev/github.com/golang-jwt/jwt/v5) +for examples of usage: + +* [Simple example of parsing and validating a + token](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-Parse-Hmac) +* [Simple example of building and signing a + token](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#example-New-Hmac) +* [Directory of + Examples](https://pkg.go.dev/github.com/golang-jwt/jwt/v5#pkg-examples) + +## Compliance + +This library was last reviewed to comply with [RFC +7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few +notable differences: + +* In order to protect against accidental use of [Unsecured + JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using + `alg=none` will only be accepted if the constant + `jwt.UnsafeAllowNoneSignatureType` is provided as the key. + +## Project Status & Versioning + +This library is considered production ready. Feedback and feature requests are +appreciated. The API should be considered stable. There should be very few +backward-incompatible changes outside of major version updates (and only with +good reason). + +This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull +requests will land on `main`. Periodically, versions will be tagged from +`main`. You can find all the releases on [the project releases +page](https://github.com/golang-jwt/jwt/releases). + +**BREAKING CHANGES:** A full list of breaking changes is available in +`VERSION_HISTORY.md`. See [`MIGRATION_GUIDE.md`](./MIGRATION_GUIDE.md) for more information on updating +your code. + +## Extensions + +This library publishes all the necessary components for adding your own signing +methods or key functions. Simply implement the `SigningMethod` interface and +register a factory method using `RegisterSigningMethod` or provide a +`jwt.Keyfunc`. + +A common use case would be integrating with different 3rd party signature +providers, like key management services from various cloud providers or Hardware +Security Modules (HSMs) or to implement additional standards. + +| Extension | Purpose | Repo | +| --------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------ | +| GCP | Integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS) | https://github.com/someone1/gcp-jwt-go | +| AWS | Integrates with AWS Key Management Service, KMS | https://github.com/matelang/jwt-go-aws-kms | +| JWKS | Provides support for JWKS ([RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517)) as a `jwt.Keyfunc` | https://github.com/MicahParks/keyfunc | + +*Disclaimer*: Unless otherwise specified, these integrations are maintained by +third parties and should not be considered as a primary offer by any of the +mentioned cloud providers + +## More + +Go package documentation can be found [on +pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt/v5). Additional +documentation can be found on [our project +page](https://golang-jwt.github.io/jwt/). + +The command line utility included in this project (cmd/jwt) provides a +straightforward example of token creation and parsing as well as a useful tool +for debugging your own integration. You'll also find several implementation +examples in the documentation. + +[golang-jwt](https://github.com/orgs/golang-jwt) incorporates a modified version +of the JWT logo, which is distributed under the terms of the [MIT +License](https://github.com/jsonwebtoken/jsonwebtoken.github.io/blob/master/LICENSE.txt). diff --git a/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md new file mode 100644 index 000000000..2740597f1 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +As of November 2024 (and until this document is updated), the latest version `v5` is supported. In critical cases, we might supply back-ported patches for `v4`. + +## Reporting a Vulnerability + +If you think you found a vulnerability, and even if you are not sure, please report it a [GitHub Security Advisory](https://github.com/golang-jwt/jwt/security/advisories/new). Please try be explicit, describe steps to reproduce the security issue with code example(s). + +You will receive a response within a timely manner. If the issue is confirmed, we will do our best to release a patch as soon as possible given the complexity of the problem. + +## Public Discussions + +Please avoid publicly discussing a potential security vulnerability. + +Let's take this offline and find a solution first, this limits the potential impact as much as possible. + +We appreciate your help! diff --git a/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md b/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md new file mode 100644 index 000000000..b5039e49c --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/VERSION_HISTORY.md @@ -0,0 +1,137 @@ +# `jwt-go` Version History + +The following version history is kept for historic purposes. To retrieve the current changes of each version, please refer to the change-log of the specific release versions on https://github.com/golang-jwt/jwt/releases. + +## 4.0.0 + +* Introduces support for Go modules. The `v4` version will be backwards compatible with `v3.x.y`. + +## 3.2.2 + +* Starting from this release, we are adopting the policy to support the most 2 recent versions of Go currently available. By the time of this release, this is Go 1.15 and 1.16 ([#28](https://github.com/golang-jwt/jwt/pull/28)). +* Fixed a potential issue that could occur when the verification of `exp`, `iat` or `nbf` was not required and contained invalid contents, i.e. non-numeric/date. Thanks for @thaJeztah for making us aware of that and @giorgos-f3 for originally reporting it to the formtech fork ([#40](https://github.com/golang-jwt/jwt/pull/40)). +* Added support for EdDSA / ED25519 ([#36](https://github.com/golang-jwt/jwt/pull/36)). +* Optimized allocations ([#33](https://github.com/golang-jwt/jwt/pull/33)). + +## 3.2.1 + +* **Import Path Change**: See MIGRATION_GUIDE.md for tips on updating your code + * Changed the import path from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt` +* Fixed type confusing issue between `string` and `[]string` in `VerifyAudience` ([#12](https://github.com/golang-jwt/jwt/pull/12)). This fixes CVE-2020-26160 + +#### 3.2.0 + +* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation +* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate +* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before. +* Deprecated `ParseFromRequestWithClaims` to simplify API in the future. + +#### 3.1.0 + +* Improvements to `jwt` command line tool +* Added `SkipClaimsValidation` option to `Parser` +* Documentation updates + +#### 3.0.0 + +* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code + * Dropped support for `[]byte` keys when using RSA signing methods. This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods. + * `ParseFromRequest` has been moved to `request` subpackage and usage has changed + * The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`. The default value is type `MapClaims`, which is an alias to `map[string]interface{}`. This makes it possible to use a custom type when decoding claims. +* Other Additions and Changes + * Added `Claims` interface type to allow users to decode the claims into a custom type + * Added `ParseWithClaims`, which takes a third argument of type `Claims`. Use this function instead of `Parse` if you have a custom type you'd like to decode into. + * Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage + * Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims` + * Added new interface type `Extractor`, which is used for extracting JWT strings from http requests. Used with `ParseFromRequest` and `ParseFromRequestWithClaims`. + * Added several new, more specific, validation errors to error type bitmask + * Moved examples from README to executable example files + * Signing method registry is now thread safe + * Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser) + +#### 2.7.0 + +This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes. + +* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying +* Error text for expired tokens includes how long it's been expired +* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM` +* Documentation updates + +#### 2.6.0 + +* Exposed inner error within ValidationError +* Fixed validation errors when using UseJSONNumber flag +* Added several unit tests + +#### 2.5.0 + +* Added support for signing method none. You shouldn't use this. The API tries to make this clear. +* Updated/fixed some documentation +* Added more helpful error message when trying to parse tokens that begin with `BEARER ` + +#### 2.4.0 + +* Added new type, Parser, to allow for configuration of various parsing parameters + * You can now specify a list of valid signing methods. Anything outside this set will be rejected. + * You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON +* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go) +* Fixed some bugs with ECDSA parsing + +#### 2.3.0 + +* Added support for ECDSA signing methods +* Added support for RSA PSS signing methods (requires go v1.4) + +#### 2.2.0 + +* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`. Result will now be the parsed token and an error, instead of a panic. + +#### 2.1.0 + +Backwards compatible API change that was missed in 2.0.0. + +* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte` + +#### 2.0.0 + +There were two major reasons for breaking backwards compatibility with this update. The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations. There will likely be no required code changes to support this change. + +The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods. Not all keys used for all signing methods have a single standard on-disk representation. Requiring `[]byte` as the type for all keys proved too limiting. Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys. Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`. + +It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`. + +* **Compatibility Breaking Changes** + * `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct` + * `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct` + * `KeyFunc` now returns `interface{}` instead of `[]byte` + * `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key + * `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key +* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodHS256` + * Added public package global `SigningMethodHS384` + * Added public package global `SigningMethodHS512` +* Renamed type `SigningMethodRS256` to `SigningMethodRSA`. Specific sizes are now just instances of this type. + * Added public package global `SigningMethodRS256` + * Added public package global `SigningMethodRS384` + * Added public package global `SigningMethodRS512` +* Moved sample private key for HMAC tests from an inline value to a file on disk. Value is unchanged. +* Refactored the RSA implementation to be easier to read +* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM` + +## 1.0.2 + +* Fixed bug in parsing public keys from certificates +* Added more tests around the parsing of keys for RS256 +* Code refactoring in RS256 implementation. No functional changes + +## 1.0.1 + +* Fixed panic if RS256 signing method was passed an invalid key + +## 1.0.0 + +* First versioned release +* API stabilized +* Supports creating, signing, parsing, and validating JWT tokens +* Supports RS256 and HS256 signing methods diff --git a/vendor/github.com/golang-jwt/jwt/v5/claims.go b/vendor/github.com/golang-jwt/jwt/v5/claims.go new file mode 100644 index 000000000..d50ff3dad --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/claims.go @@ -0,0 +1,16 @@ +package jwt + +// Claims represent any form of a JWT Claims Set according to +// https://datatracker.ietf.org/doc/html/rfc7519#section-4. In order to have a +// common basis for validation, it is required that an implementation is able to +// supply at least the claim names provided in +// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 namely `exp`, +// `iat`, `nbf`, `iss`, `sub` and `aud`. +type Claims interface { + GetExpirationTime() (*NumericDate, error) + GetIssuedAt() (*NumericDate, error) + GetNotBefore() (*NumericDate, error) + GetIssuer() (string, error) + GetSubject() (string, error) + GetAudience() (ClaimStrings, error) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/doc.go b/vendor/github.com/golang-jwt/jwt/v5/doc.go new file mode 100644 index 000000000..a86dc1a3b --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/doc.go @@ -0,0 +1,4 @@ +// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html +// +// See README.md for more info. +package jwt diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go new file mode 100644 index 000000000..06cd94d23 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa.go @@ -0,0 +1,134 @@ +package jwt + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "errors" + "math/big" +) + +var ( + // Sadly this is missing from crypto/ecdsa compared to crypto/rsa + ErrECDSAVerification = errors.New("crypto/ecdsa: verification error") +) + +// SigningMethodECDSA implements the ECDSA family of signing methods. +// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification +type SigningMethodECDSA struct { + Name string + Hash crypto.Hash + KeySize int + CurveBits int +} + +// Specific instances for EC256 and company +var ( + SigningMethodES256 *SigningMethodECDSA + SigningMethodES384 *SigningMethodECDSA + SigningMethodES512 *SigningMethodECDSA +) + +func init() { + // ES256 + SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256} + RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod { + return SigningMethodES256 + }) + + // ES384 + SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384} + RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod { + return SigningMethodES384 + }) + + // ES512 + SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521} + RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod { + return SigningMethodES512 + }) +} + +func (m *SigningMethodECDSA) Alg() string { + return m.Name +} + +// Verify implements token verification for the SigningMethod. +// For this verify method, key must be an ecdsa.PublicKey struct +func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key any) error { + // Get the key + var ecdsaKey *ecdsa.PublicKey + switch k := key.(type) { + case *ecdsa.PublicKey: + ecdsaKey = k + default: + return newError("ECDSA verify expects *ecdsa.PublicKey", ErrInvalidKeyType) + } + + if len(sig) != 2*m.KeySize { + return ErrECDSAVerification + } + + r := big.NewInt(0).SetBytes(sig[:m.KeySize]) + s := big.NewInt(0).SetBytes(sig[m.KeySize:]) + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus { + return nil + } + + return ErrECDSAVerification +} + +// Sign implements token signing for the SigningMethod. +// For this signing method, key must be an ecdsa.PrivateKey struct +func (m *SigningMethodECDSA) Sign(signingString string, key any) ([]byte, error) { + // Get the key + var ecdsaKey *ecdsa.PrivateKey + switch k := key.(type) { + case *ecdsa.PrivateKey: + ecdsaKey = k + default: + return nil, newError("ECDSA sign expects *ecdsa.PrivateKey", ErrInvalidKeyType) + } + + // Create the hasher + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return r, s + if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil { + curveBits := ecdsaKey.Curve.Params().BitSize + + if m.CurveBits != curveBits { + return nil, ErrInvalidKey + } + + keyBytes := curveBits / 8 + if curveBits%8 > 0 { + keyBytes += 1 + } + + // We serialize the outputs (r and s) into big-endian byte arrays + // padded with zeros on the left to make sure the sizes work out. + // Output must be 2*keyBytes long. + out := make([]byte, 2*keyBytes) + r.FillBytes(out[0:keyBytes]) // r is assigned to the first half of output. + s.FillBytes(out[keyBytes:]) // s is assigned to the second half of output. + + return out, nil + } else { + return nil, err + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go new file mode 100644 index 000000000..44a3b7a1c --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ecdsa_utils.go @@ -0,0 +1,69 @@ +package jwt + +import ( + "crypto/ecdsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotECPublicKey = errors.New("key is not a valid ECDSA public key") + ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key") +) + +// ParseECPrivateKeyFromPEM parses a PEM encoded Elliptic Curve Private Key Structure +func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey any + if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *ecdsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok { + return nil, ErrNotECPrivateKey + } + + return pkey, nil +} + +// ParseECPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key +func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey any + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + return nil, err + } + } + + var pkey *ecdsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok { + return nil, ErrNotECPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go new file mode 100644 index 000000000..4159e57bf --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519.go @@ -0,0 +1,79 @@ +package jwt + +import ( + "crypto" + "crypto/ed25519" + "crypto/rand" + "errors" +) + +var ( + ErrEd25519Verification = errors.New("ed25519: verification error") +) + +// SigningMethodEd25519 implements the EdDSA family. +// Expects ed25519.PrivateKey for signing and ed25519.PublicKey for verification +type SigningMethodEd25519 struct{} + +// Specific instance for EdDSA +var ( + SigningMethodEdDSA *SigningMethodEd25519 +) + +func init() { + SigningMethodEdDSA = &SigningMethodEd25519{} + RegisterSigningMethod(SigningMethodEdDSA.Alg(), func() SigningMethod { + return SigningMethodEdDSA + }) +} + +func (m *SigningMethodEd25519) Alg() string { + return "EdDSA" +} + +// Verify implements token verification for the SigningMethod. +// For this verify method, key must be an ed25519.PublicKey +func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key any) error { + var ed25519Key ed25519.PublicKey + var ok bool + + if ed25519Key, ok = key.(ed25519.PublicKey); !ok { + return newError("Ed25519 verify expects ed25519.PublicKey", ErrInvalidKeyType) + } + + if len(ed25519Key) != ed25519.PublicKeySize { + return ErrInvalidKey + } + + // Verify the signature + if !ed25519.Verify(ed25519Key, []byte(signingString), sig) { + return ErrEd25519Verification + } + + return nil +} + +// Sign implements token signing for the SigningMethod. +// For this signing method, key must be an ed25519.PrivateKey +func (m *SigningMethodEd25519) Sign(signingString string, key any) ([]byte, error) { + var ed25519Key crypto.Signer + var ok bool + + if ed25519Key, ok = key.(crypto.Signer); !ok { + return nil, newError("Ed25519 sign expects crypto.Signer", ErrInvalidKeyType) + } + + if _, ok := ed25519Key.Public().(ed25519.PublicKey); !ok { + return nil, ErrInvalidKey + } + + // Sign the string and return the result. ed25519 performs a two-pass hash + // as part of its algorithm. Therefore, we need to pass a non-prehashed + // message into the Sign function, as indicated by crypto.Hash(0) + sig, err := ed25519Key.Sign(rand.Reader, []byte(signingString), crypto.Hash(0)) + if err != nil { + return nil, err + } + + return sig, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go new file mode 100644 index 000000000..6f46e8860 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/ed25519_utils.go @@ -0,0 +1,64 @@ +package jwt + +import ( + "crypto" + "crypto/ed25519" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrNotEdPrivateKey = errors.New("key is not a valid Ed25519 private key") + ErrNotEdPublicKey = errors.New("key is not a valid Ed25519 public key") +) + +// ParseEdPrivateKeyFromPEM parses a PEM-encoded Edwards curve private key +func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey any + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + + var pkey ed25519.PrivateKey + var ok bool + if pkey, ok = parsedKey.(ed25519.PrivateKey); !ok { + return nil, ErrNotEdPrivateKey + } + + return pkey, nil +} + +// ParseEdPublicKeyFromPEM parses a PEM-encoded Edwards curve public key +func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey any + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + return nil, err + } + + var pkey ed25519.PublicKey + var ok bool + if pkey, ok = parsedKey.(ed25519.PublicKey); !ok { + return nil, ErrNotEdPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/errors.go b/vendor/github.com/golang-jwt/jwt/v5/errors.go new file mode 100644 index 000000000..14e007516 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/errors.go @@ -0,0 +1,89 @@ +package jwt + +import ( + "errors" + "fmt" + "strings" +) + +var ( + ErrInvalidKey = errors.New("key is invalid") + ErrInvalidKeyType = errors.New("key is of invalid type") + ErrHashUnavailable = errors.New("the requested hash function is unavailable") + ErrTokenMalformed = errors.New("token is malformed") + ErrTokenUnverifiable = errors.New("token is unverifiable") + ErrTokenSignatureInvalid = errors.New("token signature is invalid") + ErrTokenRequiredClaimMissing = errors.New("token is missing required claim") + ErrTokenInvalidAudience = errors.New("token has invalid audience") + ErrTokenExpired = errors.New("token is expired") + ErrTokenUsedBeforeIssued = errors.New("token used before issued") + ErrTokenInvalidIssuer = errors.New("token has invalid issuer") + ErrTokenInvalidSubject = errors.New("token has invalid subject") + ErrTokenNotValidYet = errors.New("token is not valid yet") + ErrTokenInvalidId = errors.New("token has invalid id") + ErrTokenInvalidClaims = errors.New("token has invalid claims") + ErrInvalidType = errors.New("invalid type for claim") +) + +// joinedError is an error type that works similar to what [errors.Join] +// produces, with the exception that it has a nice error string; mainly its +// error messages are concatenated using a comma, rather than a newline. +type joinedError struct { + errs []error +} + +func (je joinedError) Error() string { + msg := []string{} + for _, err := range je.errs { + msg = append(msg, err.Error()) + } + + return strings.Join(msg, ", ") +} + +// joinErrors joins together multiple errors. Useful for scenarios where +// multiple errors next to each other occur, e.g., in claims validation. +func joinErrors(errs ...error) error { + return &joinedError{ + errs: errs, + } +} + +// Unwrap implements the multiple error unwrapping for this error type, which is +// possible in Go 1.20. +func (je joinedError) Unwrap() []error { + return je.errs +} + +// newError creates a new error message with a detailed error message. The +// message will be prefixed with the contents of the supplied error type. +// Additionally, more errors, that provide more context can be supplied which +// will be appended to the message. This makes use of Go 1.20's possibility to +// include more than one %w formatting directive in [fmt.Errorf]. +// +// For example, +// +// newError("no keyfunc was provided", ErrTokenUnverifiable) +// +// will produce the error string +// +// "token is unverifiable: no keyfunc was provided" +func newError(message string, err error, more ...error) error { + var format string + var args []any + if message != "" { + format = "%w: %s" + args = []any{err, message} + } else { + format = "%w" + args = []any{err} + } + + for _, e := range more { + format += ": %w" + args = append(args, e) + } + + err = fmt.Errorf(format, args...) + return err +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/hmac.go b/vendor/github.com/golang-jwt/jwt/v5/hmac.go new file mode 100644 index 000000000..1bef138c3 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/hmac.go @@ -0,0 +1,104 @@ +package jwt + +import ( + "crypto" + "crypto/hmac" + "errors" +) + +// SigningMethodHMAC implements the HMAC-SHA family of signing methods. +// Expects key type of []byte for both signing and validation +type SigningMethodHMAC struct { + Name string + Hash crypto.Hash +} + +// Specific instances for HS256 and company +var ( + SigningMethodHS256 *SigningMethodHMAC + SigningMethodHS384 *SigningMethodHMAC + SigningMethodHS512 *SigningMethodHMAC + ErrSignatureInvalid = errors.New("signature is invalid") +) + +func init() { + // HS256 + SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod { + return SigningMethodHS256 + }) + + // HS384 + SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod { + return SigningMethodHS384 + }) + + // HS512 + SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod { + return SigningMethodHS512 + }) +} + +func (m *SigningMethodHMAC) Alg() string { + return m.Name +} + +// Verify implements token verification for the SigningMethod. Returns nil if +// the signature is valid. Key must be []byte. +// +// Note it is not advised to provide a []byte which was converted from a 'human +// readable' string using a subset of ASCII characters. To maximize entropy, you +// should ideally be providing a []byte key which was produced from a +// cryptographically random source, e.g. crypto/rand. Additional information +// about this, and why we intentionally are not supporting string as a key can +// be found on our usage guide +// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types. +func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key any) error { + // Verify the key is the right type + keyBytes, ok := key.([]byte) + if !ok { + return newError("HMAC verify expects []byte", ErrInvalidKeyType) + } + + // Can we use the specified hashing method? + if !m.Hash.Available() { + return ErrHashUnavailable + } + + // This signing method is symmetric, so we validate the signature + // by reproducing the signature from the signing string and key, then + // comparing that against the provided signature. + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + if !hmac.Equal(sig, hasher.Sum(nil)) { + return ErrSignatureInvalid + } + + // No validation errors. Signature is good. + return nil +} + +// Sign implements token signing for the SigningMethod. Key must be []byte. +// +// Note it is not advised to provide a []byte which was converted from a 'human +// readable' string using a subset of ASCII characters. To maximize entropy, you +// should ideally be providing a []byte key which was produced from a +// cryptographically random source, e.g. crypto/rand. Additional information +// about this, and why we intentionally are not supporting string as a key can +// be found on our usage guide https://golang-jwt.github.io/jwt/usage/signing_methods/. +func (m *SigningMethodHMAC) Sign(signingString string, key any) ([]byte, error) { + if keyBytes, ok := key.([]byte); ok { + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := hmac.New(m.Hash.New, keyBytes) + hasher.Write([]byte(signingString)) + + return hasher.Sum(nil), nil + } + + return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/map_claims.go b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go new file mode 100644 index 000000000..3b9205272 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/map_claims.go @@ -0,0 +1,109 @@ +package jwt + +import ( + "encoding/json" + "fmt" +) + +// MapClaims is a claims type that uses the map[string]any for JSON +// decoding. This is the default claims type if you don't supply one +type MapClaims map[string]any + +// GetExpirationTime implements the Claims interface. +func (m MapClaims) GetExpirationTime() (*NumericDate, error) { + return m.parseNumericDate("exp") +} + +// GetNotBefore implements the Claims interface. +func (m MapClaims) GetNotBefore() (*NumericDate, error) { + return m.parseNumericDate("nbf") +} + +// GetIssuedAt implements the Claims interface. +func (m MapClaims) GetIssuedAt() (*NumericDate, error) { + return m.parseNumericDate("iat") +} + +// GetAudience implements the Claims interface. +func (m MapClaims) GetAudience() (ClaimStrings, error) { + return m.parseClaimsString("aud") +} + +// GetIssuer implements the Claims interface. +func (m MapClaims) GetIssuer() (string, error) { + return m.parseString("iss") +} + +// GetSubject implements the Claims interface. +func (m MapClaims) GetSubject() (string, error) { + return m.parseString("sub") +} + +// parseNumericDate tries to parse a key in the map claims type as a number +// date. This will succeed, if the underlying type is either a [float64] or a +// [json.Number]. Otherwise, nil will be returned. +func (m MapClaims) parseNumericDate(key string) (*NumericDate, error) { + v, ok := m[key] + if !ok { + return nil, nil + } + + switch exp := v.(type) { + case float64: + if exp == 0 { + return nil, nil + } + + return newNumericDateFromSeconds(exp), nil + case json.Number: + v, _ := exp.Float64() + + return newNumericDateFromSeconds(v), nil + } + + return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) +} + +// parseClaimsString tries to parse a key in the map claims type as a +// [ClaimsStrings] type, which can either be a string or an array of string. +func (m MapClaims) parseClaimsString(key string) (ClaimStrings, error) { + var cs []string + switch v := m[key].(type) { + case string: + cs = append(cs, v) + case []string: + cs = v + case []any: + for _, a := range v { + vs, ok := a.(string) + if !ok { + return nil, newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) + } + cs = append(cs, vs) + } + } + + return cs, nil +} + +// parseString tries to parse a key in the map claims type as a [string] type. +// If the key does not exist, an empty string is returned. If the key has the +// wrong type, an error is returned. +func (m MapClaims) parseString(key string) (string, error) { + var ( + ok bool + raw any + iss string + ) + raw, ok = m[key] + if !ok { + return "", nil + } + + iss, ok = raw.(string) + if !ok { + return "", newError(fmt.Sprintf("%s is invalid", key), ErrInvalidType) + } + + return iss, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/none.go b/vendor/github.com/golang-jwt/jwt/v5/none.go new file mode 100644 index 000000000..624ad55e8 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/none.go @@ -0,0 +1,50 @@ +package jwt + +// SigningMethodNone implements the none signing method. This is required by the spec +// but you probably should never use it. +var SigningMethodNone *signingMethodNone + +const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed" + +var NoneSignatureTypeDisallowedError error + +type signingMethodNone struct{} +type unsafeNoneMagicConstant string + +func init() { + SigningMethodNone = &signingMethodNone{} + NoneSignatureTypeDisallowedError = newError("'none' signature type is not allowed", ErrTokenUnverifiable) + + RegisterSigningMethod(SigningMethodNone.Alg(), func() SigningMethod { + return SigningMethodNone + }) +} + +func (m *signingMethodNone) Alg() string { + return "none" +} + +// Only allow 'none' alg type if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Verify(signingString string, sig []byte, key any) (err error) { + // Key must be UnsafeAllowNoneSignatureType to prevent accidentally + // accepting 'none' signing method + if _, ok := key.(unsafeNoneMagicConstant); !ok { + return NoneSignatureTypeDisallowedError + } + // If signing method is none, signature must be an empty string + if len(sig) != 0 { + return newError("'none' signing method with non-empty signature", ErrTokenUnverifiable) + } + + // Accept 'none' signing method. + return nil +} + +// Only allow 'none' signing if UnsafeAllowNoneSignatureType is specified as the key +func (m *signingMethodNone) Sign(signingString string, key any) ([]byte, error) { + if _, ok := key.(unsafeNoneMagicConstant); ok { + return []byte{}, nil + } + + return nil, NoneSignatureTypeDisallowedError +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser.go b/vendor/github.com/golang-jwt/jwt/v5/parser.go new file mode 100644 index 000000000..054c7eb6f --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/parser.go @@ -0,0 +1,268 @@ +package jwt + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "strings" +) + +const tokenDelimiter = "." + +type Parser struct { + // If populated, only these methods will be considered valid. + validMethods []string + + // Use JSON Number format in JSON decoder. + useJSONNumber bool + + // Skip claims validation during token parsing. + skipClaimsValidation bool + + validator *Validator + + decodeStrict bool + + decodePaddingAllowed bool +} + +// NewParser creates a new Parser with the specified options +func NewParser(options ...ParserOption) *Parser { + p := &Parser{ + validator: &Validator{}, + } + + // Loop through our parsing options and apply them + for _, option := range options { + option(p) + } + + return p +} + +// Parse parses, validates, verifies the signature and returns the parsed token. +// keyFunc will receive the parsed token and should return the key for validating. +func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { + return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) +} + +// ParseWithClaims parses, validates, and verifies like Parse, but supplies a default object implementing the Claims +// interface. This provides default values which can be overridden and allows a caller to use their own type, rather +// than the default MapClaims implementation of Claims. +// +// Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims), +// make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the +// proper memory for it before passing in the overall claims, otherwise you might run into a panic. +func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { + token, parts, err := p.ParseUnverified(tokenString, claims) + if err != nil { + return token, err + } + + // Verify signing method is in the required set + if p.validMethods != nil { + var signingMethodValid = false + var alg = token.Method.Alg() + for _, m := range p.validMethods { + if m == alg { + signingMethodValid = true + break + } + } + if !signingMethodValid { + // signing method is not in the listed set + return token, newError(fmt.Sprintf("signing method %v is invalid", alg), ErrTokenSignatureInvalid) + } + } + + // 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], ".") + + // 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) + } + + // Validate Claims + if !p.skipClaimsValidation { + // Make sure we have at least a default validator + if p.validator == nil { + p.validator = NewValidator() + } + + if err := p.validator.Validate(claims); err != nil { + return token, newError("", ErrTokenInvalidClaims, err) + } + } + + // No errors so far, token is valid. + token.Valid = true + + return token, nil +} + +// ParseUnverified parses the token but doesn't validate the signature. +// +// 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 (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) { + var ok bool + parts, ok = splitToken(tokenString) + if !ok { + return nil, nil, newError("token contains an invalid number of segments", ErrTokenMalformed) + } + + token = &Token{Raw: tokenString} + + // parse Header + var headerBytes []byte + if headerBytes, err = p.DecodeSegment(parts[0]); err != nil { + return token, parts, newError("could not base64 decode header", ErrTokenMalformed, err) + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, parts, newError("could not JSON decode header", ErrTokenMalformed, err) + } + + // parse Claims + token.Claims = claims + + claimBytes, err := p.DecodeSegment(parts[1]) + if err != nil { + return token, parts, newError("could not base64 decode claim", ErrTokenMalformed, err) + } + + // 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 { + 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) + } + } + if err != nil { + return token, parts, newError("could not JSON decode claim", ErrTokenMalformed, err) + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, parts, newError("signing method (alg) is unavailable", ErrTokenUnverifiable) + } + } else { + return token, parts, newError("signing method (alg) is unspecified", ErrTokenUnverifiable) + } + + return token, parts, nil +} + +// splitToken splits a token string into three parts: header, claims, and signature. It will only +// return true if the token contains exactly two delimiters and three parts. In all other cases, it +// will return nil parts and false. +func splitToken(token string) ([]string, bool) { + parts := make([]string, 3) + header, remain, ok := strings.Cut(token, tokenDelimiter) + if !ok { + return nil, false + } + parts[0] = header + claims, remain, ok := strings.Cut(remain, tokenDelimiter) + if !ok { + return nil, false + } + parts[1] = claims + // One more cut to ensure the signature is the last part of the token and there are no more + // delimiters. This avoids an issue where malicious input could contain additional delimiters + // causing unecessary overhead parsing tokens. + signature, _, unexpected := strings.Cut(remain, tokenDelimiter) + if unexpected { + return nil, false + } + parts[2] = signature + + return parts, true +} + +// DecodeSegment decodes a JWT specific base64url encoding. This function will +// take into account whether the [Parser] is configured with additional options, +// such as [WithStrictDecoding] or [WithPaddingAllowed]. +func (p *Parser) DecodeSegment(seg string) ([]byte, error) { + encoding := base64.RawURLEncoding + + if p.decodePaddingAllowed { + if l := len(seg) % 4; l > 0 { + seg += strings.Repeat("=", 4-l) + } + encoding = base64.URLEncoding + } + + if p.decodeStrict { + encoding = encoding.Strict() + } + return encoding.DecodeString(seg) +} + +// Parse parses, validates, verifies the signature and returns the parsed token. +// keyFunc will receive the parsed token and should return the cryptographic key +// for verifying the signature. The caller is strongly encouraged to set the +// WithValidMethods option to validate the 'alg' claim in the token matches the +// expected algorithm. For more details about the importance of validating the +// 'alg' claim, see +// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ +func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { + return NewParser(options...).Parse(tokenString, keyFunc) +} + +// ParseWithClaims is a shortcut for NewParser().ParseWithClaims(). +// +// Note: If you provide a custom claim implementation that embeds one of the +// standard claims (such as RegisteredClaims), make sure that a) you either +// embed a non-pointer version of the claims or b) if you are using a pointer, +// allocate the proper memory for it before passing in the overall claims, +// otherwise you might run into a panic. +func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { + return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser_option.go b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go new file mode 100644 index 000000000..431573557 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/parser_option.go @@ -0,0 +1,145 @@ +package jwt + +import "time" + +// ParserOption is used to implement functional-style options that modify the +// behavior of the parser. To add new options, just create a function (ideally +// beginning with With or Without) that returns an anonymous function that takes +// a *Parser type as input and manipulates its configuration accordingly. +type ParserOption func(*Parser) + +// WithValidMethods is an option to supply algorithm methods that the parser +// will check. Only those methods will be considered valid. It is heavily +// encouraged to use this option in order to prevent attacks such as +// https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/. +func WithValidMethods(methods []string) ParserOption { + return func(p *Parser) { + p.validMethods = methods + } +} + +// WithJSONNumber is an option to configure the underlying JSON parser with +// UseNumber. +func WithJSONNumber() ParserOption { + return func(p *Parser) { + p.useJSONNumber = true + } +} + +// WithoutClaimsValidation is an option to disable claims validation. This +// option should only be used if you exactly know what you are doing. +func WithoutClaimsValidation() ParserOption { + return func(p *Parser) { + p.skipClaimsValidation = true + } +} + +// WithLeeway returns the ParserOption for specifying the leeway window. +func WithLeeway(leeway time.Duration) ParserOption { + return func(p *Parser) { + p.validator.leeway = leeway + } +} + +// WithTimeFunc returns the ParserOption for specifying the time func. The +// primary use-case for this is testing. If you are looking for a way to account +// for clock-skew, WithLeeway should be used instead. +func WithTimeFunc(f func() time.Time) ParserOption { + return func(p *Parser) { + p.validator.timeFunc = f + } +} + +// WithIssuedAt returns the ParserOption to enable verification +// of issued-at. +func WithIssuedAt() ParserOption { + return func(p *Parser) { + p.validator.verifyIat = true + } +} + +// 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 any of the specified +// audiences in the `aud` claim. Validation will fail if the audience is not +// listed in the token or the `aud` claim is missing. +// +// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an audience is expected. +func WithAudience(aud ...string) ParserOption { + return func(p *Parser) { + p.validator.expectedAud = aud + } +} + +// WithAllAudiences configures the validator to require all the specified +// audiences in the `aud` claim. Validation will fail if the specified audiences +// are not listed in the token or the `aud` claim is missing. Duplicates within +// the list are de-duplicated since internally, we use a map to look up the +// audiences. +// +// NOTE: While the `aud` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an audience is expected. +func WithAllAudiences(aud ...string) ParserOption { + return func(p *Parser) { + p.validator.expectedAud = aud + p.validator.expectAllAud = true + } +} + +// WithIssuer configures the validator to require the specified issuer in the +// `iss` claim. Validation will fail if a different issuer is specified in the +// token or the `iss` claim is missing. +// +// NOTE: While the `iss` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if an issuer is expected. +func WithIssuer(iss string) ParserOption { + return func(p *Parser) { + p.validator.expectedIss = iss + } +} + +// WithSubject configures the validator to require the specified subject in the +// `sub` claim. Validation will fail if a different subject is specified in the +// token or the `sub` claim is missing. +// +// NOTE: While the `sub` claim is OPTIONAL in a JWT, the handling of it is +// application-specific. Since this validation API is helping developers in +// writing secure application, we decided to REQUIRE the existence of the claim, +// if a subject is expected. +func WithSubject(sub string) ParserOption { + return func(p *Parser) { + p.validator.expectedSub = sub + } +} + +// WithPaddingAllowed will enable the codec used for decoding JWTs to allow +// padding. Note that the JWS RFC7515 states that the tokens will utilize a +// Base64url encoding with no padding. Unfortunately, some implementations of +// JWT are producing non-standard tokens, and thus require support for decoding. +func WithPaddingAllowed() ParserOption { + return func(p *Parser) { + p.decodePaddingAllowed = true + } +} + +// WithStrictDecoding will switch the codec used for decoding JWTs into strict +// mode. In this mode, the decoder requires that trailing padding bits are zero, +// as described in RFC 4648 section 3.5. +func WithStrictDecoding() ParserOption { + return func(p *Parser) { + p.decodeStrict = true + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go b/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go new file mode 100644 index 000000000..77951a531 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/registered_claims.go @@ -0,0 +1,63 @@ +package jwt + +// RegisteredClaims are a structured version of the JWT Claims Set, +// restricted to Registered Claim Names, as referenced at +// https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 +// +// This type can be used on its own, but then additional private and +// public claims embedded in the JWT will not be parsed. The typical use-case +// therefore is to embedded this in a user-defined claim type. +// +// See examples for how to use this with your own claim types. +type RegisteredClaims struct { + // the `iss` (Issuer) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1 + Issuer string `json:"iss,omitempty"` + + // the `sub` (Subject) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2 + Subject string `json:"sub,omitempty"` + + // the `aud` (Audience) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3 + Audience ClaimStrings `json:"aud,omitempty"` + + // the `exp` (Expiration Time) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4 + ExpiresAt *NumericDate `json:"exp,omitempty"` + + // the `nbf` (Not Before) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5 + NotBefore *NumericDate `json:"nbf,omitempty"` + + // the `iat` (Issued At) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6 + IssuedAt *NumericDate `json:"iat,omitempty"` + + // the `jti` (JWT ID) claim. See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7 + ID string `json:"jti,omitempty"` +} + +// GetExpirationTime implements the Claims interface. +func (c RegisteredClaims) GetExpirationTime() (*NumericDate, error) { + return c.ExpiresAt, nil +} + +// GetNotBefore implements the Claims interface. +func (c RegisteredClaims) GetNotBefore() (*NumericDate, error) { + return c.NotBefore, nil +} + +// GetIssuedAt implements the Claims interface. +func (c RegisteredClaims) GetIssuedAt() (*NumericDate, error) { + return c.IssuedAt, nil +} + +// GetAudience implements the Claims interface. +func (c RegisteredClaims) GetAudience() (ClaimStrings, error) { + return c.Audience, nil +} + +// GetIssuer implements the Claims interface. +func (c RegisteredClaims) GetIssuer() (string, error) { + return c.Issuer, nil +} + +// GetSubject implements the Claims interface. +func (c RegisteredClaims) GetSubject() (string, error) { + return c.Subject, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa.go b/vendor/github.com/golang-jwt/jwt/v5/rsa.go new file mode 100644 index 000000000..98b960a78 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/rsa.go @@ -0,0 +1,93 @@ +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// SigningMethodRSA implements the RSA family of signing methods. +// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation +type SigningMethodRSA struct { + Name string + Hash crypto.Hash +} + +// Specific instances for RS256 and company +var ( + SigningMethodRS256 *SigningMethodRSA + SigningMethodRS384 *SigningMethodRSA + SigningMethodRS512 *SigningMethodRSA +) + +func init() { + // RS256 + SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256} + RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod { + return SigningMethodRS256 + }) + + // RS384 + SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384} + RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod { + return SigningMethodRS384 + }) + + // RS512 + SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512} + RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod { + return SigningMethodRS512 + }) +} + +func (m *SigningMethodRSA) Alg() string { + return m.Name +} + +// Verify implements token verification for the SigningMethod +// For this signing method, must be an *rsa.PublicKey structure. +func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key any) error { + var rsaKey *rsa.PublicKey + var ok bool + + if rsaKey, ok = key.(*rsa.PublicKey); !ok { + return newError("RSA verify expects *rsa.PublicKey", ErrInvalidKeyType) + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Verify the signature + return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig) +} + +// Sign implements token signing for the SigningMethod +// For this signing method, must be an *rsa.PrivateKey structure. +func (m *SigningMethodRSA) Sign(signingString string, key any) ([]byte, error) { + var rsaKey *rsa.PrivateKey + var ok bool + + // Validate type of key + if rsaKey, ok = key.(*rsa.PrivateKey); !ok { + return nil, newError("RSA sign expects *rsa.PrivateKey", ErrInvalidKeyType) + } + + // Create the hasher + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil { + return sigBytes, nil + } else { + return nil, err + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go new file mode 100644 index 000000000..f17590cc4 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_pss.go @@ -0,0 +1,132 @@ +package jwt + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +// SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods +type SigningMethodRSAPSS struct { + *SigningMethodRSA + Options *rsa.PSSOptions + // VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS. + // Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow + // https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously. + // See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details. + VerifyOptions *rsa.PSSOptions +} + +// Specific instances for RS/PS and company. +var ( + SigningMethodPS256 *SigningMethodRSAPSS + SigningMethodPS384 *SigningMethodRSAPSS + SigningMethodPS512 *SigningMethodRSAPSS +) + +func init() { + // PS256 + SigningMethodPS256 = &SigningMethodRSAPSS{ + SigningMethodRSA: &SigningMethodRSA{ + Name: "PS256", + Hash: crypto.SHA256, + }, + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + }, + } + RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod { + return SigningMethodPS256 + }) + + // PS384 + SigningMethodPS384 = &SigningMethodRSAPSS{ + SigningMethodRSA: &SigningMethodRSA{ + Name: "PS384", + Hash: crypto.SHA384, + }, + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + }, + } + RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod { + return SigningMethodPS384 + }) + + // PS512 + SigningMethodPS512 = &SigningMethodRSAPSS{ + SigningMethodRSA: &SigningMethodRSA{ + Name: "PS512", + Hash: crypto.SHA512, + }, + Options: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + }, + VerifyOptions: &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthAuto, + }, + } + RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod { + return SigningMethodPS512 + }) +} + +// Verify implements token verification for the SigningMethod. +// For this verify method, key must be an rsa.PublicKey struct +func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key any) error { + var rsaKey *rsa.PublicKey + switch k := key.(type) { + case *rsa.PublicKey: + rsaKey = k + default: + return newError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType) + } + + // Create hasher + if !m.Hash.Available() { + return ErrHashUnavailable + } + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + opts := m.Options + if m.VerifyOptions != nil { + opts = m.VerifyOptions + } + + return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts) +} + +// Sign implements token signing for the SigningMethod. +// For this signing method, key must be an rsa.PrivateKey struct +func (m *SigningMethodRSAPSS) Sign(signingString string, key any) ([]byte, error) { + var rsaKey *rsa.PrivateKey + + switch k := key.(type) { + case *rsa.PrivateKey: + rsaKey = k + default: + return nil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType) + } + + // Create the hasher + if !m.Hash.Available() { + return nil, ErrHashUnavailable + } + + hasher := m.Hash.New() + hasher.Write([]byte(signingString)) + + // Sign the string and return the encoded bytes + if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { + return sigBytes, nil + } else { + return nil, err + } +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go new file mode 100644 index 000000000..f22c3d068 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/rsa_utils.go @@ -0,0 +1,107 @@ +package jwt + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" +) + +var ( + ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be a PEM encoded PKCS1 or PKCS8 key") + ErrNotRSAPrivateKey = errors.New("key is not a valid RSA private key") + ErrNotRSAPublicKey = errors.New("key is not a valid RSA public key") +) + +// ParseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key +func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey any + if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// ParseRSAPrivateKeyFromPEMWithPassword parses a PEM encoded PKCS1 or PKCS8 private key protected with password +// +// Deprecated: This function is deprecated and should not be used anymore. It uses the deprecated x509.DecryptPEMBlock +// function, which was deprecated since RFC 1423 is regarded insecure by design. Unfortunately, there is no alternative +// in the Go standard library for now. See https://github.com/golang/go/issues/8860. +func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + var parsedKey any + + var blockDecrypted []byte + if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil { + return nil, err + } + + if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil { + if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil { + return nil, err + } + } + + var pkey *rsa.PrivateKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { + return nil, ErrNotRSAPrivateKey + } + + return pkey, nil +} + +// ParseRSAPublicKeyFromPEM parses a certificate or a PEM encoded PKCS1 or PKIX public key +func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { + var err error + + // Parse PEM block + var block *pem.Block + if block, _ = pem.Decode(key); block == nil { + return nil, ErrKeyMustBePEMEncoded + } + + // Parse the key + var parsedKey any + if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { + if cert, err := x509.ParseCertificate(block.Bytes); err == nil { + parsedKey = cert.PublicKey + } else { + if parsedKey, err = x509.ParsePKCS1PublicKey(block.Bytes); err != nil { + return nil, err + } + } + } + + var pkey *rsa.PublicKey + var ok bool + if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { + return nil, ErrNotRSAPublicKey + } + + return pkey, nil +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/signing_method.go b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go new file mode 100644 index 000000000..096d0ed4c --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/signing_method.go @@ -0,0 +1,49 @@ +package jwt + +import ( + "sync" +) + +var signingMethods = map[string]func() SigningMethod{} +var signingMethodLock = new(sync.RWMutex) + +// SigningMethod can be used add new methods for signing or verifying tokens. It +// takes a decoded signature as an input in the Verify function and produces a +// signature in Sign. The signature is then usually base64 encoded as part of a +// JWT. +type SigningMethod interface { + Verify(signingString string, sig []byte, key any) error // Returns nil if signature is valid + Sign(signingString string, key any) ([]byte, error) // Returns signature or error + Alg() string // returns the alg identifier for this method (example: 'HS256') +} + +// RegisterSigningMethod registers the "alg" name and a factory function for signing method. +// This is typically done during init() in the method's implementation +func RegisterSigningMethod(alg string, f func() SigningMethod) { + signingMethodLock.Lock() + defer signingMethodLock.Unlock() + + signingMethods[alg] = f +} + +// GetSigningMethod retrieves a signing method from an "alg" string +func GetSigningMethod(alg string) (method SigningMethod) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + if methodF, ok := signingMethods[alg]; ok { + method = methodF() + } + return +} + +// GetAlgorithms returns a list of registered "alg" names +func GetAlgorithms() (algs []string) { + signingMethodLock.RLock() + defer signingMethodLock.RUnlock() + + for alg := range signingMethods { + algs = append(algs, alg) + } + return +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf b/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf new file mode 100644 index 000000000..53745d51d --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/staticcheck.conf @@ -0,0 +1 @@ +checks = ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1023"] diff --git a/vendor/github.com/golang-jwt/jwt/v5/token.go b/vendor/github.com/golang-jwt/jwt/v5/token.go new file mode 100644 index 000000000..3f7155888 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/token.go @@ -0,0 +1,100 @@ +package jwt + +import ( + "crypto" + "encoding/base64" + "encoding/json" +) + +// Keyfunc will be used by the Parse methods as a callback function to supply +// 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 any may be a single key or a VerificationKeySet containing +// multiple keys. +type Keyfunc func(*Token) (any, 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 { + Raw string // Raw contains the raw token. Populated when you [Parse] a token + Method SigningMethod // Method is the signing method used or to be used + Header map[string]any // Header is the first segment of the token in decoded form + Claims Claims // Claims is the second segment of the token in decoded form + Signature []byte // Signature is the third segment of the token in decoded form. Populated when you Parse a token + Valid bool // Valid specifies if the token is valid. Populated when you Parse/Verify a token +} + +// New creates a new [Token] with the specified signing method and an empty map +// of claims. Additional options can be specified, but are currently unused. +func New(method SigningMethod, opts ...TokenOption) *Token { + return NewWithClaims(method, MapClaims{}, opts...) +} + +// NewWithClaims creates a new [Token] with the specified signing method and +// claims. Additional options can be specified, but are currently unused. +func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *Token { + return &Token{ + Header: map[string]any{ + "typ": "JWT", + "alg": method.Alg(), + }, + Claims: claims, + Method: method, + } +} + +// SignedString creates and returns a complete, signed JWT. The token is signed +// using the SigningMethod specified in the token. Please refer to +// https://golang-jwt.github.io/jwt/usage/signing_methods/#signing-methods-and-key-types +// for an overview of the different signing methods and their respective key +// types. +func (t *Token) SignedString(key any) (string, error) { + sstr, err := t.SigningString() + if err != nil { + return "", err + } + + sig, err := t.Method.Sign(sstr, key) + if err != nil { + return "", err + } + + return sstr + "." + t.EncodeSegment(sig), nil +} + +// SigningString generates the signing string. This is the most expensive part +// of the whole deal. Unless you need this for something special, just go +// straight for the SignedString. +func (t *Token) SigningString() (string, error) { + h, err := json.Marshal(t.Header) + if err != nil { + return "", err + } + + c, err := json.Marshal(t.Claims) + if err != nil { + return "", err + } + + return t.EncodeSegment(h) + "." + t.EncodeSegment(c), nil +} + +// EncodeSegment encodes a JWT specific base64url encoding with padding +// stripped. In the future, this function might take into account a +// [TokenOption]. Therefore, this function exists as a method of [Token], rather +// than a global function. +func (*Token) EncodeSegment(seg []byte) string { + return base64.RawURLEncoding.EncodeToString(seg) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/token_option.go b/vendor/github.com/golang-jwt/jwt/v5/token_option.go new file mode 100644 index 000000000..b4ae3badf --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/token_option.go @@ -0,0 +1,5 @@ +package jwt + +// TokenOption is a reserved type, which provides some forward compatibility, +// if we ever want to introduce token creation-related options. +type TokenOption func(*Token) diff --git a/vendor/github.com/golang-jwt/jwt/v5/types.go b/vendor/github.com/golang-jwt/jwt/v5/types.go new file mode 100644 index 000000000..a3e0ef121 --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/types.go @@ -0,0 +1,149 @@ +package jwt + +import ( + "encoding/json" + "fmt" + "math" + "strconv" + "time" +) + +// TimePrecision sets the precision of times and dates within this library. This +// has an influence on the precision of times when comparing expiry or other +// related time fields. Furthermore, it is also the precision of times when +// serializing. +// +// For backwards compatibility the default precision is set to seconds, so that +// no fractional timestamps are generated. +var TimePrecision = time.Second + +// MarshalSingleStringAsArray modifies the behavior of the ClaimStrings type, +// especially its MarshalJSON function. +// +// If it is set to true (the default), it will always serialize the type as an +// array of strings, even if it just contains one element, defaulting to the +// behavior of the underlying []string. If it is set to false, it will serialize +// to a single string, if it contains one element. Otherwise, it will serialize +// to an array of strings. +var MarshalSingleStringAsArray = true + +// NumericDate represents a JSON numeric date value, as referenced at +// https://datatracker.ietf.org/doc/html/rfc7519#section-2. +type NumericDate struct { + time.Time +} + +// NewNumericDate constructs a new *NumericDate from a standard library time.Time struct. +// It will truncate the timestamp according to the precision specified in TimePrecision. +func NewNumericDate(t time.Time) *NumericDate { + return &NumericDate{t.Truncate(TimePrecision)} +} + +// newNumericDateFromSeconds creates a new *NumericDate out of a float64 representing a +// UNIX epoch with the float fraction representing non-integer seconds. +func newNumericDateFromSeconds(f float64) *NumericDate { + round, frac := math.Modf(f) + return NewNumericDate(time.Unix(int64(round), int64(frac*1e9))) +} + +// MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch +// represented in NumericDate to a byte array, using the precision specified in TimePrecision. +func (date NumericDate) MarshalJSON() (b []byte, err error) { + var prec int + if TimePrecision < time.Second { + prec = int(math.Log10(float64(time.Second) / float64(TimePrecision))) + } + truncatedDate := date.Truncate(TimePrecision) + + // For very large timestamps, UnixNano would overflow an int64, but this + // function requires nanosecond level precision, so we have to use the + // following technique to get round the issue: + // + // 1. Take the normal unix timestamp to form the whole number part of the + // output, + // 2. Take the result of the Nanosecond function, which returns the offset + // within the second of the particular unix time instance, to form the + // decimal part of the output + // 3. Concatenate them to produce the final result + seconds := strconv.FormatInt(truncatedDate.Unix(), 10) + nanosecondsOffset := strconv.FormatFloat(float64(truncatedDate.Nanosecond())/float64(time.Second), 'f', prec, 64) + + output := append([]byte(seconds), []byte(nanosecondsOffset)[1:]...) + + return output, nil +} + +// UnmarshalJSON is an implementation of the json.RawMessage interface and +// deserializes a [NumericDate] from a JSON representation, i.e. a +// [json.Number]. This number represents an UNIX epoch with either integer or +// non-integer seconds. +func (date *NumericDate) UnmarshalJSON(b []byte) (err error) { + var ( + number json.Number + f float64 + ) + + if err = json.Unmarshal(b, &number); err != nil { + return fmt.Errorf("could not parse NumericData: %w", err) + } + + if f, err = number.Float64(); err != nil { + return fmt.Errorf("could not convert json number value to float: %w", err) + } + + n := newNumericDateFromSeconds(f) + *date = *n + + return nil +} + +// ClaimStrings is basically just a slice of strings, but it can be either +// serialized from a string array or just a string. This type is necessary, +// since the "aud" claim can either be a single string or an array. +type ClaimStrings []string + +func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) { + var value any + + if err = json.Unmarshal(data, &value); err != nil { + return err + } + + var aud []string + + switch v := value.(type) { + case string: + aud = append(aud, v) + case []string: + aud = ClaimStrings(v) + case []any: + for _, vv := range v { + vs, ok := vv.(string) + if !ok { + return ErrInvalidType + } + aud = append(aud, vs) + } + case nil: + return nil + default: + return ErrInvalidType + } + + *s = aud + + return +} + +func (s ClaimStrings) MarshalJSON() (b []byte, err error) { + // This handles a special case in the JWT RFC. If the string array, e.g. + // used by the "aud" field, only contains one element, it MAY be serialized + // as a single string. This may or may not be desired based on the ecosystem + // of other JWT library used, so we make it configurable by the variable + // MarshalSingleStringAsArray. + if len(s) == 1 && !MarshalSingleStringAsArray { + return json.Marshal(s[0]) + } + + return json.Marshal([]string(s)) +} diff --git a/vendor/github.com/golang-jwt/jwt/v5/validator.go b/vendor/github.com/golang-jwt/jwt/v5/validator.go new file mode 100644 index 000000000..92b5c057c --- /dev/null +++ b/vendor/github.com/golang-jwt/jwt/v5/validator.go @@ -0,0 +1,326 @@ +package jwt + +import ( + "fmt" + "slices" + "time" +) + +// ClaimsValidator is an interface that can be implemented by custom claims who +// wish to execute any additional claims validation based on +// application-specific logic. The Validate function is then executed in +// addition to the regular claims validation and any error returned is appended +// to the final validation result. +// +// type MyCustomClaims struct { +// Foo string `json:"foo"` +// jwt.RegisteredClaims +// } +// +// func (m MyCustomClaims) Validate() error { +// if m.Foo != "bar" { +// return errors.New("must be foobar") +// } +// return nil +// } +type ClaimsValidator interface { + Claims + Validate() error +} + +// 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. +// +// 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 + + // timeFunc is used to supply the current time that is needed for + // 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 + // necessary. However, if wanted, it can be checked if the iat is + // unrealistic, i.e., in the future. + verifyIat bool + + // expectedAud contains the audience this token expects. Supplying an empty + // slice will disable aud checking. + expectedAud []string + + // expectAllAud specifies whether all expected audiences must be present in + // the token. If false, only one of the expected audiences must be present. + expectAllAud bool + + // expectedIss contains the issuer this token expects. Supplying an empty + // string will disable iss checking. + expectedIss string + + // expectedSub contains the subject this token expects. Supplying an empty + // string will disable sub checking. + expectedSub string +} + +// 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. +// +// 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. +// +// 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 = make([]error, 0, 6) + err error + ) + + // Check, if we have a time func + if v.timeFunc != nil { + now = v.timeFunc() + } else { + now = time.Now() + } + + // We always need to check the expiration time, but usage of the claim + // 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) + } + + // We always need to check not-before, but usage of the claim itself is + // OPTIONAL. + if err = v.verifyNotBefore(claims, now, false); err != nil { + errs = append(errs, err) + } + + // Check issued-at if the option is enabled + if v.verifyIat { + if err = v.verifyIssuedAt(claims, now, false); err != nil { + errs = append(errs, err) + } + } + + // If we have an expected audience, we also require the audience claim + if len(v.expectedAud) > 0 { + if err = v.verifyAudience(claims, v.expectedAud, v.expectAllAud); err != nil { + errs = append(errs, err) + } + } + + // If we have an expected issuer, we also require the issuer claim + if v.expectedIss != "" { + if err = v.verifyIssuer(claims, v.expectedIss, true); err != nil { + errs = append(errs, err) + } + } + + // If we have an expected subject, we also require the subject claim + if v.expectedSub != "" { + if err = v.verifySubject(claims, v.expectedSub, true); err != nil { + errs = append(errs, err) + } + } + + // Finally, we want to give the claim itself some possibility to do some + // additional custom validation based on a custom Validate function. + cvt, ok := claims.(ClaimsValidator) + if ok { + if err := cvt.Validate(); err != nil { + errs = append(errs, err) + } + } + + if len(errs) == 0 { + return nil + } + + return joinErrors(errs...) +} + +// verifyExpiresAt compares the exp claim in claims against cmp. This function +// will succeed if cmp < exp. Additional leeway is taken into account. +// +// If exp is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// 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 { + exp, err := claims.GetExpirationTime() + if err != nil { + return err + } + + if exp == nil { + return errorIfRequired(required, "exp") + } + + return errorIfFalse(cmp.Before((exp.Time).Add(+v.leeway)), ErrTokenExpired) +} + +// verifyIssuedAt compares the iat claim in claims against cmp. This function +// will succeed if cmp >= iat. Additional leeway is taken into account. +// +// If iat is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// 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 { + iat, err := claims.GetIssuedAt() + if err != nil { + return err + } + + if iat == nil { + return errorIfRequired(required, "iat") + } + + return errorIfFalse(!cmp.Before(iat.Add(-v.leeway)), ErrTokenUsedBeforeIssued) +} + +// verifyNotBefore compares the nbf claim in claims against cmp. This function +// will return true if cmp >= nbf. Additional leeway is taken into account. +// +// If nbf is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// 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 { + nbf, err := claims.GetNotBefore() + if err != nil { + return err + } + + if nbf == nil { + return errorIfRequired(required, "nbf") + } + + return errorIfFalse(!cmp.Before(nbf.Add(-v.leeway)), ErrTokenNotValidYet) +} + +// verifyAudience compares the aud claim against cmp. +// +// If aud is not set or an empty list, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// 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, expectAllAud bool) error { + aud, err := claims.GetAudience() + if err != nil { + return err + } + + // Check that aud exists and is not empty. We only require the aud claim + // if we expect at least one audience to be present. + if len(aud) == 0 || len(aud) == 1 && aud[0] == "" { + required := len(v.expectedAud) > 0 + return errorIfRequired(required, "aud") + } + + if !expectAllAud { + for _, a := range aud { + // If we only expect one match, we can stop early if we find a match + if slices.Contains(cmp, a) { + return nil + } + } + + return ErrTokenInvalidAudience + } + + // Note that we are looping cmp here to ensure that all expected audiences + // are present in the aud claim. + for _, a := range cmp { + if !slices.Contains(aud, a) { + return ErrTokenInvalidAudience + } + } + + return nil +} + +// verifyIssuer compares the iss claim in claims against cmp. +// +// If iss is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// 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 { + iss, err := claims.GetIssuer() + if err != nil { + return err + } + + if iss == "" { + return errorIfRequired(required, "iss") + } + + return errorIfFalse(iss == cmp, ErrTokenInvalidIssuer) +} + +// verifySubject compares the sub claim against cmp. +// +// If sub is not set, it will succeed if the claim is not required, +// otherwise ErrTokenRequiredClaimMissing will be returned. +// +// 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 { + sub, err := claims.GetSubject() + if err != nil { + return err + } + + if sub == "" { + return errorIfRequired(required, "sub") + } + + return errorIfFalse(sub == cmp, ErrTokenInvalidSubject) +} + +// errorIfFalse returns the error specified in err, if the value is true. +// Otherwise, nil is returned. +func errorIfFalse(value bool, err error) error { + if value { + return nil + } else { + return err + } +} + +// errorIfRequired returns an ErrTokenRequiredClaimMissing error if required is +// true. Otherwise, nil is returned. +func errorIfRequired(required bool, claim string) error { + if required { + return newError(fmt.Sprintf("%s claim is required", claim), ErrTokenRequiredClaimMissing) + } else { + return nil + } +} diff --git a/vendor/github.com/kylelemons/godebug/pretty/.gitignore b/vendor/github.com/kylelemons/godebug/pretty/.gitignore new file mode 100644 index 000000000..fa9a735da --- /dev/null +++ b/vendor/github.com/kylelemons/godebug/pretty/.gitignore @@ -0,0 +1,5 @@ +*.test +*.bench +*.golden +*.txt +*.prof diff --git a/vendor/github.com/kylelemons/godebug/pretty/doc.go b/vendor/github.com/kylelemons/godebug/pretty/doc.go new file mode 100644 index 000000000..03b5718a7 --- /dev/null +++ b/vendor/github.com/kylelemons/godebug/pretty/doc.go @@ -0,0 +1,25 @@ +// Copyright 2013 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package pretty pretty-prints Go structures. +// +// This package uses reflection to examine a Go value and can +// print out in a nice, aligned fashion. It supports three +// modes (normal, compact, and extended) for advanced use. +// +// See the Reflect and Print examples for what the output looks like. +package pretty + +// TODO: +// - Catch cycles diff --git a/vendor/github.com/kylelemons/godebug/pretty/public.go b/vendor/github.com/kylelemons/godebug/pretty/public.go new file mode 100644 index 000000000..fbc5d7abb --- /dev/null +++ b/vendor/github.com/kylelemons/godebug/pretty/public.go @@ -0,0 +1,188 @@ +// Copyright 2013 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pretty + +import ( + "bytes" + "fmt" + "io" + "net" + "reflect" + "time" + + "github.com/kylelemons/godebug/diff" +) + +// A Config represents optional configuration parameters for formatting. +// +// Some options, notably ShortList, dramatically increase the overhead +// of pretty-printing a value. +type Config struct { + // Verbosity options + Compact bool // One-line output. Overrides Diffable. + Diffable bool // Adds extra newlines for more easily diffable output. + + // Field and value options + IncludeUnexported bool // Include unexported fields in output + PrintStringers bool // Call String on a fmt.Stringer + PrintTextMarshalers bool // Call MarshalText on an encoding.TextMarshaler + SkipZeroFields bool // Skip struct fields that have a zero value. + + // Output transforms + ShortList int // Maximum character length for short lists if nonzero. + + // Type-specific overrides + // + // Formatter maps a type to a function that will provide a one-line string + // representation of the input value. Conceptually: + // Formatter[reflect.TypeOf(v)](v) = "v as a string" + // + // Note that the first argument need not explicitly match the type, it must + // merely be callable with it. + // + // When processing an input value, if its type exists as a key in Formatter: + // 1) If the value is nil, no stringification is performed. + // This allows overriding of PrintStringers and PrintTextMarshalers. + // 2) The value will be called with the input as its only argument. + // The function must return a string as its first return value. + // + // In addition to func literals, two common values for this will be: + // fmt.Sprint (function) func Sprint(...interface{}) string + // Type.String (method) func (Type) String() string + // + // Note that neither of these work if the String method is a pointer + // method and the input will be provided as a value. In that case, + // use a function that calls .String on the formal value parameter. + Formatter map[reflect.Type]interface{} + + // If TrackCycles is enabled, pretty will detect and track + // self-referential structures. If a self-referential structure (aka a + // "recursive" value) is detected, numbered placeholders will be emitted. + // + // Pointer tracking is disabled by default for performance reasons. + TrackCycles bool +} + +// Default Config objects +var ( + // DefaultFormatter is the default set of overrides for stringification. + DefaultFormatter = map[reflect.Type]interface{}{ + reflect.TypeOf(time.Time{}): fmt.Sprint, + reflect.TypeOf(net.IP{}): fmt.Sprint, + reflect.TypeOf((*error)(nil)).Elem(): fmt.Sprint, + } + + // CompareConfig is the default configuration used for Compare. + CompareConfig = &Config{ + Diffable: true, + IncludeUnexported: true, + Formatter: DefaultFormatter, + } + + // DefaultConfig is the default configuration used for all other top-level functions. + DefaultConfig = &Config{ + Formatter: DefaultFormatter, + } + + // CycleTracker is a convenience config for formatting and comparing recursive structures. + CycleTracker = &Config{ + Diffable: true, + Formatter: DefaultFormatter, + TrackCycles: true, + } +) + +func (cfg *Config) fprint(buf *bytes.Buffer, vals ...interface{}) { + ref := &reflector{ + Config: cfg, + } + if cfg.TrackCycles { + ref.pointerTracker = new(pointerTracker) + } + for i, val := range vals { + if i > 0 { + buf.WriteByte('\n') + } + newFormatter(cfg, buf).write(ref.val2node(reflect.ValueOf(val))) + } +} + +// Print writes the DefaultConfig representation of the given values to standard output. +func Print(vals ...interface{}) { + DefaultConfig.Print(vals...) +} + +// Print writes the configured presentation of the given values to standard output. +func (cfg *Config) Print(vals ...interface{}) { + fmt.Println(cfg.Sprint(vals...)) +} + +// Sprint returns a string representation of the given value according to the DefaultConfig. +func Sprint(vals ...interface{}) string { + return DefaultConfig.Sprint(vals...) +} + +// Sprint returns a string representation of the given value according to cfg. +func (cfg *Config) Sprint(vals ...interface{}) string { + buf := new(bytes.Buffer) + cfg.fprint(buf, vals...) + return buf.String() +} + +// Fprint writes the representation of the given value to the writer according to the DefaultConfig. +func Fprint(w io.Writer, vals ...interface{}) (n int64, err error) { + return DefaultConfig.Fprint(w, vals...) +} + +// Fprint writes the representation of the given value to the writer according to the cfg. +func (cfg *Config) Fprint(w io.Writer, vals ...interface{}) (n int64, err error) { + buf := new(bytes.Buffer) + cfg.fprint(buf, vals...) + return buf.WriteTo(w) +} + +// Compare returns a string containing a line-by-line unified diff of the +// values in a and b, using the CompareConfig. +// +// Each line in the output is prefixed with '+', '-', or ' ' to indicate which +// side it's from. Lines from the a side are marked with '-', lines from the +// b side are marked with '+' and lines that are the same on both sides are +// marked with ' '. +// +// The comparison is based on the intentionally-untyped output of Print, and as +// such this comparison is pretty forviving. In particular, if the types of or +// types within in a and b are different but have the same representation, +// Compare will not indicate any differences between them. +func Compare(a, b interface{}) string { + return CompareConfig.Compare(a, b) +} + +// Compare returns a string containing a line-by-line unified diff of the +// values in got and want according to the cfg. +// +// Each line in the output is prefixed with '+', '-', or ' ' to indicate which +// side it's from. Lines from the a side are marked with '-', lines from the +// b side are marked with '+' and lines that are the same on both sides are +// marked with ' '. +// +// The comparison is based on the intentionally-untyped output of Print, and as +// such this comparison is pretty forviving. In particular, if the types of or +// types within in a and b are different but have the same representation, +// Compare will not indicate any differences between them. +func (cfg *Config) Compare(a, b interface{}) string { + diffCfg := *cfg + diffCfg.Diffable = true + return diff.Diff(cfg.Sprint(a), cfg.Sprint(b)) +} diff --git a/vendor/github.com/kylelemons/godebug/pretty/reflect.go b/vendor/github.com/kylelemons/godebug/pretty/reflect.go new file mode 100644 index 000000000..5cd30b7f0 --- /dev/null +++ b/vendor/github.com/kylelemons/godebug/pretty/reflect.go @@ -0,0 +1,241 @@ +// Copyright 2013 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pretty + +import ( + "encoding" + "fmt" + "reflect" + "sort" +) + +func isZeroVal(val reflect.Value) bool { + if !val.CanInterface() { + return false + } + z := reflect.Zero(val.Type()).Interface() + return reflect.DeepEqual(val.Interface(), z) +} + +// pointerTracker is a helper for tracking pointer chasing to detect cycles. +type pointerTracker struct { + addrs map[uintptr]int // addr[address] = seen count + + lastID int + ids map[uintptr]int // ids[address] = id +} + +// track tracks following a reference (pointer, slice, map, etc). Every call to +// track should be paired with a call to untrack. +func (p *pointerTracker) track(ptr uintptr) { + if p.addrs == nil { + p.addrs = make(map[uintptr]int) + } + p.addrs[ptr]++ +} + +// untrack registers that we have backtracked over the reference to the pointer. +func (p *pointerTracker) untrack(ptr uintptr) { + p.addrs[ptr]-- + if p.addrs[ptr] == 0 { + delete(p.addrs, ptr) + } +} + +// seen returns whether the pointer was previously seen along this path. +func (p *pointerTracker) seen(ptr uintptr) bool { + _, ok := p.addrs[ptr] + return ok +} + +// keep allocates an ID for the given address and returns it. +func (p *pointerTracker) keep(ptr uintptr) int { + if p.ids == nil { + p.ids = make(map[uintptr]int) + } + if _, ok := p.ids[ptr]; !ok { + p.lastID++ + p.ids[ptr] = p.lastID + } + return p.ids[ptr] +} + +// id returns the ID for the given address. +func (p *pointerTracker) id(ptr uintptr) (int, bool) { + if p.ids == nil { + p.ids = make(map[uintptr]int) + } + id, ok := p.ids[ptr] + return id, ok +} + +// reflector adds local state to the recursive reflection logic. +type reflector struct { + *Config + *pointerTracker +} + +// follow handles following a possiblly-recursive reference to the given value +// from the given ptr address. +func (r *reflector) follow(ptr uintptr, val reflect.Value) node { + if r.pointerTracker == nil { + // Tracking disabled + return r.val2node(val) + } + + // If a parent already followed this, emit a reference marker + if r.seen(ptr) { + id := r.keep(ptr) + return ref{id} + } + + // Track the pointer we're following while on this recursive branch + r.track(ptr) + defer r.untrack(ptr) + n := r.val2node(val) + + // If the recursion used this ptr, wrap it with a target marker + if id, ok := r.id(ptr); ok { + return target{id, n} + } + + // Otherwise, return the node unadulterated + return n +} + +func (r *reflector) val2node(val reflect.Value) node { + if !val.IsValid() { + return rawVal("nil") + } + + if val.CanInterface() { + v := val.Interface() + if formatter, ok := r.Formatter[val.Type()]; ok { + if formatter != nil { + res := reflect.ValueOf(formatter).Call([]reflect.Value{val}) + return rawVal(res[0].Interface().(string)) + } + } else { + if s, ok := v.(fmt.Stringer); ok && r.PrintStringers { + return stringVal(s.String()) + } + if t, ok := v.(encoding.TextMarshaler); ok && r.PrintTextMarshalers { + if raw, err := t.MarshalText(); err == nil { // if NOT an error + return stringVal(string(raw)) + } + } + } + } + + switch kind := val.Kind(); kind { + case reflect.Ptr: + if val.IsNil() { + return rawVal("nil") + } + return r.follow(val.Pointer(), val.Elem()) + case reflect.Interface: + if val.IsNil() { + return rawVal("nil") + } + return r.val2node(val.Elem()) + case reflect.String: + return stringVal(val.String()) + case reflect.Slice: + n := list{} + length := val.Len() + ptr := val.Pointer() + for i := 0; i < length; i++ { + n = append(n, r.follow(ptr, val.Index(i))) + } + return n + case reflect.Array: + n := list{} + length := val.Len() + for i := 0; i < length; i++ { + n = append(n, r.val2node(val.Index(i))) + } + return n + case reflect.Map: + // Extract the keys and sort them for stable iteration + keys := val.MapKeys() + pairs := make([]mapPair, 0, len(keys)) + for _, key := range keys { + pairs = append(pairs, mapPair{ + key: new(formatter).compactString(r.val2node(key)), // can't be cyclic + value: val.MapIndex(key), + }) + } + sort.Sort(byKey(pairs)) + + // Process the keys into the final representation + ptr, n := val.Pointer(), keyvals{} + for _, pair := range pairs { + n = append(n, keyval{ + key: pair.key, + val: r.follow(ptr, pair.value), + }) + } + return n + case reflect.Struct: + n := keyvals{} + typ := val.Type() + fields := typ.NumField() + for i := 0; i < fields; i++ { + sf := typ.Field(i) + if !r.IncludeUnexported && sf.PkgPath != "" { + continue + } + field := val.Field(i) + if r.SkipZeroFields && isZeroVal(field) { + continue + } + n = append(n, keyval{sf.Name, r.val2node(field)}) + } + return n + case reflect.Bool: + if val.Bool() { + return rawVal("true") + } + return rawVal("false") + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return rawVal(fmt.Sprintf("%d", val.Int())) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + return rawVal(fmt.Sprintf("%d", val.Uint())) + case reflect.Uintptr: + return rawVal(fmt.Sprintf("0x%X", val.Uint())) + case reflect.Float32, reflect.Float64: + return rawVal(fmt.Sprintf("%v", val.Float())) + case reflect.Complex64, reflect.Complex128: + return rawVal(fmt.Sprintf("%v", val.Complex())) + } + + // Fall back to the default %#v if we can + if val.CanInterface() { + return rawVal(fmt.Sprintf("%#v", val.Interface())) + } + + return rawVal(val.String()) +} + +type mapPair struct { + key string + value reflect.Value +} + +type byKey []mapPair + +func (v byKey) Len() int { return len(v) } +func (v byKey) Swap(i, j int) { v[i], v[j] = v[j], v[i] } +func (v byKey) Less(i, j int) bool { return v[i].key < v[j].key } diff --git a/vendor/github.com/kylelemons/godebug/pretty/structure.go b/vendor/github.com/kylelemons/godebug/pretty/structure.go new file mode 100644 index 000000000..d876f60ca --- /dev/null +++ b/vendor/github.com/kylelemons/godebug/pretty/structure.go @@ -0,0 +1,223 @@ +// Copyright 2013 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pretty + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" +) + +// a formatter stores stateful formatting information as well as being +// an io.Writer for simplicity. +type formatter struct { + *bufio.Writer + *Config + + // Self-referential structure tracking + tagNumbers map[int]int // tagNumbers[id] = <#n> +} + +// newFormatter creates a new buffered formatter. For the output to be written +// to the given writer, this must be accompanied by a call to write (or Flush). +func newFormatter(cfg *Config, w io.Writer) *formatter { + return &formatter{ + Writer: bufio.NewWriter(w), + Config: cfg, + tagNumbers: make(map[int]int), + } +} + +func (f *formatter) write(n node) { + defer f.Flush() + n.format(f, "") +} + +func (f *formatter) tagFor(id int) int { + if tag, ok := f.tagNumbers[id]; ok { + return tag + } + if f.tagNumbers == nil { + return 0 + } + tag := len(f.tagNumbers) + 1 + f.tagNumbers[id] = tag + return tag +} + +type node interface { + format(f *formatter, indent string) +} + +func (f *formatter) compactString(n node) string { + switch k := n.(type) { + case stringVal: + return string(k) + case rawVal: + return string(k) + } + + buf := new(bytes.Buffer) + f2 := newFormatter(&Config{Compact: true}, buf) + f2.tagNumbers = f.tagNumbers // reuse tagNumbers just in case + f2.write(n) + return buf.String() +} + +type stringVal string + +func (str stringVal) format(f *formatter, indent string) { + f.WriteString(strconv.Quote(string(str))) +} + +type rawVal string + +func (r rawVal) format(f *formatter, indent string) { + f.WriteString(string(r)) +} + +type keyval struct { + key string + val node +} + +type keyvals []keyval + +func (l keyvals) format(f *formatter, indent string) { + f.WriteByte('{') + + switch { + case f.Compact: + // All on one line: + for i, kv := range l { + if i > 0 { + f.WriteByte(',') + } + f.WriteString(kv.key) + f.WriteByte(':') + kv.val.format(f, indent) + } + case f.Diffable: + f.WriteByte('\n') + inner := indent + " " + // Each value gets its own line: + for _, kv := range l { + f.WriteString(inner) + f.WriteString(kv.key) + f.WriteString(": ") + kv.val.format(f, inner) + f.WriteString(",\n") + } + f.WriteString(indent) + default: + keyWidth := 0 + for _, kv := range l { + if kw := len(kv.key); kw > keyWidth { + keyWidth = kw + } + } + alignKey := indent + " " + alignValue := strings.Repeat(" ", keyWidth) + inner := alignKey + alignValue + " " + // First and last line shared with bracket: + for i, kv := range l { + if i > 0 { + f.WriteString(",\n") + f.WriteString(alignKey) + } + f.WriteString(kv.key) + f.WriteString(": ") + f.WriteString(alignValue[len(kv.key):]) + kv.val.format(f, inner) + } + } + + f.WriteByte('}') +} + +type list []node + +func (l list) format(f *formatter, indent string) { + if max := f.ShortList; max > 0 { + short := f.compactString(l) + if len(short) <= max { + f.WriteString(short) + return + } + } + + f.WriteByte('[') + + switch { + case f.Compact: + // All on one line: + for i, v := range l { + if i > 0 { + f.WriteByte(',') + } + v.format(f, indent) + } + case f.Diffable: + f.WriteByte('\n') + inner := indent + " " + // Each value gets its own line: + for _, v := range l { + f.WriteString(inner) + v.format(f, inner) + f.WriteString(",\n") + } + f.WriteString(indent) + default: + inner := indent + " " + // First and last line shared with bracket: + for i, v := range l { + if i > 0 { + f.WriteString(",\n") + f.WriteString(inner) + } + v.format(f, inner) + } + } + + f.WriteByte(']') +} + +type ref struct { + id int +} + +func (r ref) format(f *formatter, indent string) { + fmt.Fprintf(f, "", f.tagFor(r.id)) +} + +type target struct { + id int + value node +} + +func (t target) format(f *formatter, indent string) { + tag := fmt.Sprintf("<#%d> ", f.tagFor(t.id)) + switch { + case f.Diffable, f.Compact: + // no indent changes + default: + indent += strings.Repeat(" ", len(tag)) + } + f.WriteString(tag) + t.value.format(f, indent) +} diff --git a/vendor/github.com/pkg/browser/LICENSE b/vendor/github.com/pkg/browser/LICENSE new file mode 100644 index 000000000..65f78fb62 --- /dev/null +++ b/vendor/github.com/pkg/browser/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2014, Dave Cheney +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pkg/browser/README.md b/vendor/github.com/pkg/browser/README.md new file mode 100644 index 000000000..72b1976e3 --- /dev/null +++ b/vendor/github.com/pkg/browser/README.md @@ -0,0 +1,55 @@ + +# browser + import "github.com/pkg/browser" + +Package browser provides helpers to open files, readers, and urls in a browser window. + +The choice of which browser is started is entirely client dependant. + + + + + +## Variables +``` go +var Stderr io.Writer = os.Stderr +``` +Stderr is the io.Writer to which executed commands write standard error. + +``` go +var Stdout io.Writer = os.Stdout +``` +Stdout is the io.Writer to which executed commands write standard output. + + +## func OpenFile +``` go +func OpenFile(path string) error +``` +OpenFile opens new browser window for the file path. + + +## func OpenReader +``` go +func OpenReader(r io.Reader) error +``` +OpenReader consumes the contents of r and presents the +results in a new browser window. + + +## func OpenURL +``` go +func OpenURL(url string) error +``` +OpenURL opens a new browser window pointing to url. + + + + + + + + + +- - - +Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) diff --git a/vendor/github.com/pkg/browser/browser.go b/vendor/github.com/pkg/browser/browser.go new file mode 100644 index 000000000..d7969d74d --- /dev/null +++ b/vendor/github.com/pkg/browser/browser.go @@ -0,0 +1,57 @@ +// Package browser provides helpers to open files, readers, and urls in a browser window. +// +// The choice of which browser is started is entirely client dependant. +package browser + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" +) + +// Stdout is the io.Writer to which executed commands write standard output. +var Stdout io.Writer = os.Stdout + +// Stderr is the io.Writer to which executed commands write standard error. +var Stderr io.Writer = os.Stderr + +// OpenFile opens new browser window for the file path. +func OpenFile(path string) error { + path, err := filepath.Abs(path) + if err != nil { + return err + } + return OpenURL("file://" + path) +} + +// OpenReader consumes the contents of r and presents the +// results in a new browser window. +func OpenReader(r io.Reader) error { + f, err := ioutil.TempFile("", "browser.*.html") + if err != nil { + return fmt.Errorf("browser: could not create temporary file: %v", err) + } + if _, err := io.Copy(f, r); err != nil { + f.Close() + return fmt.Errorf("browser: caching temporary file failed: %v", err) + } + if err := f.Close(); err != nil { + return fmt.Errorf("browser: caching temporary file failed: %v", err) + } + return OpenFile(f.Name()) +} + +// OpenURL opens a new browser window pointing to url. +func OpenURL(url string) error { + return openBrowser(url) +} + +func runCmd(prog string, args ...string) error { + cmd := exec.Command(prog, args...) + cmd.Stdout = Stdout + cmd.Stderr = Stderr + return cmd.Run() +} diff --git a/vendor/github.com/pkg/browser/browser_darwin.go b/vendor/github.com/pkg/browser/browser_darwin.go new file mode 100644 index 000000000..8507cf7c2 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_darwin.go @@ -0,0 +1,5 @@ +package browser + +func openBrowser(url string) error { + return runCmd("open", url) +} diff --git a/vendor/github.com/pkg/browser/browser_freebsd.go b/vendor/github.com/pkg/browser/browser_freebsd.go new file mode 100644 index 000000000..4fc7ff076 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_freebsd.go @@ -0,0 +1,14 @@ +package browser + +import ( + "errors" + "os/exec" +) + +func openBrowser(url string) error { + err := runCmd("xdg-open", url) + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + return errors.New("xdg-open: command not found - install xdg-utils from ports(8)") + } + return err +} diff --git a/vendor/github.com/pkg/browser/browser_linux.go b/vendor/github.com/pkg/browser/browser_linux.go new file mode 100644 index 000000000..d26cdddf9 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_linux.go @@ -0,0 +1,21 @@ +package browser + +import ( + "os/exec" + "strings" +) + +func openBrowser(url string) error { + providers := []string{"xdg-open", "x-www-browser", "www-browser"} + + // There are multiple possible providers to open a browser on linux + // One of them is xdg-open, another is x-www-browser, then there's www-browser, etc. + // Look for one that exists and run it + for _, provider := range providers { + if _, err := exec.LookPath(provider); err == nil { + return runCmd(provider, url) + } + } + + return &exec.Error{Name: strings.Join(providers, ","), Err: exec.ErrNotFound} +} diff --git a/vendor/github.com/pkg/browser/browser_netbsd.go b/vendor/github.com/pkg/browser/browser_netbsd.go new file mode 100644 index 000000000..65a5e5a29 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_netbsd.go @@ -0,0 +1,14 @@ +package browser + +import ( + "errors" + "os/exec" +) + +func openBrowser(url string) error { + err := runCmd("xdg-open", url) + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + return errors.New("xdg-open: command not found - install xdg-utils from pkgsrc(7)") + } + return err +} diff --git a/vendor/github.com/pkg/browser/browser_openbsd.go b/vendor/github.com/pkg/browser/browser_openbsd.go new file mode 100644 index 000000000..4fc7ff076 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_openbsd.go @@ -0,0 +1,14 @@ +package browser + +import ( + "errors" + "os/exec" +) + +func openBrowser(url string) error { + err := runCmd("xdg-open", url) + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + return errors.New("xdg-open: command not found - install xdg-utils from ports(8)") + } + return err +} diff --git a/vendor/github.com/pkg/browser/browser_unsupported.go b/vendor/github.com/pkg/browser/browser_unsupported.go new file mode 100644 index 000000000..7c5c17d34 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_unsupported.go @@ -0,0 +1,12 @@ +// +build !linux,!windows,!darwin,!openbsd,!freebsd,!netbsd + +package browser + +import ( + "fmt" + "runtime" +) + +func openBrowser(url string) error { + return fmt.Errorf("openBrowser: unsupported operating system: %v", runtime.GOOS) +} diff --git a/vendor/github.com/pkg/browser/browser_windows.go b/vendor/github.com/pkg/browser/browser_windows.go new file mode 100644 index 000000000..63e192959 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_windows.go @@ -0,0 +1,7 @@ +package browser + +import "golang.org/x/sys/windows" + +func openBrowser(url string) error { + return windows.ShellExecute(0, nil, windows.StringToUTF16Ptr(url), nil, nil, windows.SW_SHOWNORMAL) +} diff --git a/vendor/golang.org/x/crypto/pkcs12/bmp-string.go b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go new file mode 100644 index 000000000..233b8b62c --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/bmp-string.go @@ -0,0 +1,50 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs12 + +import ( + "errors" + "unicode/utf16" +) + +// bmpString returns s encoded in UCS-2 with a zero terminator. +func bmpString(s string) ([]byte, error) { + // References: + // https://tools.ietf.org/html/rfc7292#appendix-B.1 + // https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane + // - non-BMP characters are encoded in UTF 16 by using a surrogate pair of 16-bit codes + // EncodeRune returns 0xfffd if the rune does not need special encoding + // - the above RFC provides the info that BMPStrings are NULL terminated. + + ret := make([]byte, 0, 2*len(s)+2) + + for _, r := range s { + if t, _ := utf16.EncodeRune(r); t != 0xfffd { + return nil, errors.New("pkcs12: string contains characters that cannot be encoded in UCS-2") + } + ret = append(ret, byte(r/256), byte(r%256)) + } + + return append(ret, 0, 0), nil +} + +func decodeBMPString(bmpString []byte) (string, error) { + if len(bmpString)%2 != 0 { + return "", errors.New("pkcs12: odd-length BMP string") + } + + // strip terminator if present + if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 { + bmpString = bmpString[:l-2] + } + + s := make([]uint16, 0, len(bmpString)/2) + for len(bmpString) > 0 { + s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1])) + bmpString = bmpString[2:] + } + + return string(utf16.Decode(s)), nil +} diff --git a/vendor/golang.org/x/crypto/pkcs12/crypto.go b/vendor/golang.org/x/crypto/pkcs12/crypto.go new file mode 100644 index 000000000..212538cb5 --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/crypto.go @@ -0,0 +1,131 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs12 + +import ( + "bytes" + "crypto/cipher" + "crypto/des" + "crypto/x509/pkix" + "encoding/asn1" + "errors" + + "golang.org/x/crypto/pkcs12/internal/rc2" +) + +var ( + oidPBEWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) + oidPBEWithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 6}) +) + +// pbeCipher is an abstraction of a PKCS#12 cipher. +type pbeCipher interface { + // create returns a cipher.Block given a key. + create(key []byte) (cipher.Block, error) + // deriveKey returns a key derived from the given password and salt. + deriveKey(salt, password []byte, iterations int) []byte + // deriveIV returns an IV derived from the given password and salt. + deriveIV(salt, password []byte, iterations int) []byte +} + +type shaWithTripleDESCBC struct{} + +func (shaWithTripleDESCBC) create(key []byte) (cipher.Block, error) { + return des.NewTripleDESCipher(key) +} + +func (shaWithTripleDESCBC) deriveKey(salt, password []byte, iterations int) []byte { + return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 24) +} + +func (shaWithTripleDESCBC) deriveIV(salt, password []byte, iterations int) []byte { + return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8) +} + +type shaWith40BitRC2CBC struct{} + +func (shaWith40BitRC2CBC) create(key []byte) (cipher.Block, error) { + return rc2.New(key, len(key)*8) +} + +func (shaWith40BitRC2CBC) deriveKey(salt, password []byte, iterations int) []byte { + return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 5) +} + +func (shaWith40BitRC2CBC) deriveIV(salt, password []byte, iterations int) []byte { + return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8) +} + +type pbeParams struct { + Salt []byte + Iterations int +} + +func pbDecrypterFor(algorithm pkix.AlgorithmIdentifier, password []byte) (cipher.BlockMode, int, error) { + var cipherType pbeCipher + + switch { + case algorithm.Algorithm.Equal(oidPBEWithSHAAnd3KeyTripleDESCBC): + cipherType = shaWithTripleDESCBC{} + case algorithm.Algorithm.Equal(oidPBEWithSHAAnd40BitRC2CBC): + cipherType = shaWith40BitRC2CBC{} + default: + return nil, 0, NotImplementedError("algorithm " + algorithm.Algorithm.String() + " is not supported") + } + + var params pbeParams + if err := unmarshal(algorithm.Parameters.FullBytes, ¶ms); err != nil { + return nil, 0, err + } + + key := cipherType.deriveKey(params.Salt, password, params.Iterations) + iv := cipherType.deriveIV(params.Salt, password, params.Iterations) + + block, err := cipherType.create(key) + if err != nil { + return nil, 0, err + } + + return cipher.NewCBCDecrypter(block, iv), block.BlockSize(), nil +} + +func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error) { + cbc, blockSize, err := pbDecrypterFor(info.Algorithm(), password) + if err != nil { + return nil, err + } + + encrypted := info.Data() + if len(encrypted) == 0 { + return nil, errors.New("pkcs12: empty encrypted data") + } + if len(encrypted)%blockSize != 0 { + return nil, errors.New("pkcs12: input is not a multiple of the block size") + } + decrypted = make([]byte, len(encrypted)) + cbc.CryptBlocks(decrypted, encrypted) + + psLen := int(decrypted[len(decrypted)-1]) + if psLen == 0 || psLen > blockSize { + return nil, ErrDecryption + } + + if len(decrypted) < psLen { + return nil, ErrDecryption + } + ps := decrypted[len(decrypted)-psLen:] + decrypted = decrypted[:len(decrypted)-psLen] + if !bytes.Equal(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) { + return nil, ErrDecryption + } + + return +} + +// decryptable abstracts an object that contains ciphertext. +type decryptable interface { + Algorithm() pkix.AlgorithmIdentifier + Data() []byte +} diff --git a/vendor/golang.org/x/crypto/pkcs12/errors.go b/vendor/golang.org/x/crypto/pkcs12/errors.go new file mode 100644 index 000000000..7377ce6fb --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/errors.go @@ -0,0 +1,23 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs12 + +import "errors" + +var ( + // ErrDecryption represents a failure to decrypt the input. + ErrDecryption = errors.New("pkcs12: decryption error, incorrect padding") + + // ErrIncorrectPassword is returned when an incorrect password is detected. + // Usually, P12/PFX data is signed to be able to verify the password. + ErrIncorrectPassword = errors.New("pkcs12: decryption password incorrect") +) + +// NotImplementedError indicates that the input is not currently supported. +type NotImplementedError string + +func (e NotImplementedError) Error() string { + return "pkcs12: " + string(e) +} diff --git a/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go new file mode 100644 index 000000000..05de9cc2c --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go @@ -0,0 +1,268 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package rc2 implements the RC2 cipher +/* +https://www.ietf.org/rfc/rfc2268.txt +http://people.csail.mit.edu/rivest/pubs/KRRR98.pdf + +This code is licensed under the MIT license. +*/ +package rc2 + +import ( + "crypto/cipher" + "encoding/binary" + "math/bits" +) + +// The rc2 block size in bytes +const BlockSize = 8 + +type rc2Cipher struct { + k [64]uint16 +} + +// New returns a new rc2 cipher with the given key and effective key length t1 +func New(key []byte, t1 int) (cipher.Block, error) { + // TODO(dgryski): error checking for key length + return &rc2Cipher{ + k: expandKey(key, t1), + }, nil +} + +func (*rc2Cipher) BlockSize() int { return BlockSize } + +var piTable = [256]byte{ + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, + 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, + 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82, + 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, + 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03, + 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, + 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec, + 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, + 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9, + 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, + 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad, +} + +func expandKey(key []byte, t1 int) [64]uint16 { + + l := make([]byte, 128) + copy(l, key) + + var t = len(key) + var t8 = (t1 + 7) / 8 + var tm = byte(255 % uint(1<<(8+uint(t1)-8*uint(t8)))) + + for i := len(key); i < 128; i++ { + l[i] = piTable[l[i-1]+l[uint8(i-t)]] + } + + l[128-t8] = piTable[l[128-t8]&tm] + + for i := 127 - t8; i >= 0; i-- { + l[i] = piTable[l[i+1]^l[i+t8]] + } + + var k [64]uint16 + + for i := range k { + k[i] = uint16(l[2*i]) + uint16(l[2*i+1])*256 + } + + return k +} + +func (c *rc2Cipher) Encrypt(dst, src []byte) { + + r0 := binary.LittleEndian.Uint16(src[0:]) + r1 := binary.LittleEndian.Uint16(src[2:]) + r2 := binary.LittleEndian.Uint16(src[4:]) + r3 := binary.LittleEndian.Uint16(src[6:]) + + var j int + + for j <= 16 { + // mix r0 + r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) + r0 = bits.RotateLeft16(r0, 1) + j++ + + // mix r1 + r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) + r1 = bits.RotateLeft16(r1, 2) + j++ + + // mix r2 + r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) + r2 = bits.RotateLeft16(r2, 3) + j++ + + // mix r3 + r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) + r3 = bits.RotateLeft16(r3, 5) + j++ + + } + + r0 = r0 + c.k[r3&63] + r1 = r1 + c.k[r0&63] + r2 = r2 + c.k[r1&63] + r3 = r3 + c.k[r2&63] + + for j <= 40 { + // mix r0 + r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) + r0 = bits.RotateLeft16(r0, 1) + j++ + + // mix r1 + r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) + r1 = bits.RotateLeft16(r1, 2) + j++ + + // mix r2 + r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) + r2 = bits.RotateLeft16(r2, 3) + j++ + + // mix r3 + r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) + r3 = bits.RotateLeft16(r3, 5) + j++ + + } + + r0 = r0 + c.k[r3&63] + r1 = r1 + c.k[r0&63] + r2 = r2 + c.k[r1&63] + r3 = r3 + c.k[r2&63] + + for j <= 60 { + // mix r0 + r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) + r0 = bits.RotateLeft16(r0, 1) + j++ + + // mix r1 + r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) + r1 = bits.RotateLeft16(r1, 2) + j++ + + // mix r2 + r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) + r2 = bits.RotateLeft16(r2, 3) + j++ + + // mix r3 + r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) + r3 = bits.RotateLeft16(r3, 5) + j++ + } + + binary.LittleEndian.PutUint16(dst[0:], r0) + binary.LittleEndian.PutUint16(dst[2:], r1) + binary.LittleEndian.PutUint16(dst[4:], r2) + binary.LittleEndian.PutUint16(dst[6:], r3) +} + +func (c *rc2Cipher) Decrypt(dst, src []byte) { + + r0 := binary.LittleEndian.Uint16(src[0:]) + r1 := binary.LittleEndian.Uint16(src[2:]) + r2 := binary.LittleEndian.Uint16(src[4:]) + r3 := binary.LittleEndian.Uint16(src[6:]) + + j := 63 + + for j >= 44 { + // unmix r3 + r3 = bits.RotateLeft16(r3, 16-5) + r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) + j-- + + // unmix r2 + r2 = bits.RotateLeft16(r2, 16-3) + r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) + j-- + + // unmix r1 + r1 = bits.RotateLeft16(r1, 16-2) + r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) + j-- + + // unmix r0 + r0 = bits.RotateLeft16(r0, 16-1) + r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) + j-- + } + + r3 = r3 - c.k[r2&63] + r2 = r2 - c.k[r1&63] + r1 = r1 - c.k[r0&63] + r0 = r0 - c.k[r3&63] + + for j >= 20 { + // unmix r3 + r3 = bits.RotateLeft16(r3, 16-5) + r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) + j-- + + // unmix r2 + r2 = bits.RotateLeft16(r2, 16-3) + r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) + j-- + + // unmix r1 + r1 = bits.RotateLeft16(r1, 16-2) + r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) + j-- + + // unmix r0 + r0 = bits.RotateLeft16(r0, 16-1) + r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) + j-- + + } + + r3 = r3 - c.k[r2&63] + r2 = r2 - c.k[r1&63] + r1 = r1 - c.k[r0&63] + r0 = r0 - c.k[r3&63] + + for j >= 0 { + // unmix r3 + r3 = bits.RotateLeft16(r3, 16-5) + r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) + j-- + + // unmix r2 + r2 = bits.RotateLeft16(r2, 16-3) + r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) + j-- + + // unmix r1 + r1 = bits.RotateLeft16(r1, 16-2) + r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) + j-- + + // unmix r0 + r0 = bits.RotateLeft16(r0, 16-1) + r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) + j-- + + } + + binary.LittleEndian.PutUint16(dst[0:], r0) + binary.LittleEndian.PutUint16(dst[2:], r1) + binary.LittleEndian.PutUint16(dst[4:], r2) + binary.LittleEndian.PutUint16(dst[6:], r3) +} diff --git a/vendor/golang.org/x/crypto/pkcs12/mac.go b/vendor/golang.org/x/crypto/pkcs12/mac.go new file mode 100644 index 000000000..5f38aa7de --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/mac.go @@ -0,0 +1,45 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs12 + +import ( + "crypto/hmac" + "crypto/sha1" + "crypto/x509/pkix" + "encoding/asn1" +) + +type macData struct { + Mac digestInfo + MacSalt []byte + Iterations int `asn1:"optional,default:1"` +} + +// from PKCS#7: +type digestInfo struct { + Algorithm pkix.AlgorithmIdentifier + Digest []byte +} + +var ( + oidSHA1 = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) +) + +func verifyMac(macData *macData, message, password []byte) error { + if !macData.Mac.Algorithm.Algorithm.Equal(oidSHA1) { + return NotImplementedError("unknown digest algorithm: " + macData.Mac.Algorithm.Algorithm.String()) + } + + key := pbkdf(sha1Sum, 20, 64, macData.MacSalt, password, macData.Iterations, 3, 20) + + mac := hmac.New(sha1.New, key) + mac.Write(message) + expectedMAC := mac.Sum(nil) + + if !hmac.Equal(macData.Mac.Digest, expectedMAC) { + return ErrIncorrectPassword + } + return nil +} diff --git a/vendor/golang.org/x/crypto/pkcs12/pbkdf.go b/vendor/golang.org/x/crypto/pkcs12/pbkdf.go new file mode 100644 index 000000000..5c419d41e --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/pbkdf.go @@ -0,0 +1,170 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs12 + +import ( + "bytes" + "crypto/sha1" + "math/big" +) + +var ( + one = big.NewInt(1) +) + +// sha1Sum returns the SHA-1 hash of in. +func sha1Sum(in []byte) []byte { + sum := sha1.Sum(in) + return sum[:] +} + +// fillWithRepeats returns v*ceiling(len(pattern) / v) bytes consisting of +// repeats of pattern. +func fillWithRepeats(pattern []byte, v int) []byte { + if len(pattern) == 0 { + return nil + } + outputLen := v * ((len(pattern) + v - 1) / v) + return bytes.Repeat(pattern, (outputLen+len(pattern)-1)/len(pattern))[:outputLen] +} + +func pbkdf(hash func([]byte) []byte, u, v int, salt, password []byte, r int, ID byte, size int) (key []byte) { + // implementation of https://tools.ietf.org/html/rfc7292#appendix-B.2 , RFC text verbatim in comments + + // Let H be a hash function built around a compression function f: + + // Z_2^u x Z_2^v -> Z_2^u + + // (that is, H has a chaining variable and output of length u bits, and + // the message input to the compression function of H is v bits). The + // values for u and v are as follows: + + // HASH FUNCTION VALUE u VALUE v + // MD2, MD5 128 512 + // SHA-1 160 512 + // SHA-224 224 512 + // SHA-256 256 512 + // SHA-384 384 1024 + // SHA-512 512 1024 + // SHA-512/224 224 1024 + // SHA-512/256 256 1024 + + // Furthermore, let r be the iteration count. + + // We assume here that u and v are both multiples of 8, as are the + // lengths of the password and salt strings (which we denote by p and s, + // respectively) and the number n of pseudorandom bits required. In + // addition, u and v are of course non-zero. + + // For information on security considerations for MD5 [19], see [25] and + // [1], and on those for MD2, see [18]. + + // The following procedure can be used to produce pseudorandom bits for + // a particular "purpose" that is identified by a byte called "ID". + // This standard specifies 3 different values for the ID byte: + + // 1. If ID=1, then the pseudorandom bits being produced are to be used + // as key material for performing encryption or decryption. + + // 2. If ID=2, then the pseudorandom bits being produced are to be used + // as an IV (Initial Value) for encryption or decryption. + + // 3. If ID=3, then the pseudorandom bits being produced are to be used + // as an integrity key for MACing. + + // 1. Construct a string, D (the "diversifier"), by concatenating v/8 + // copies of ID. + var D []byte + for i := 0; i < v; i++ { + D = append(D, ID) + } + + // 2. Concatenate copies of the salt together to create a string S of + // length v(ceiling(s/v)) bits (the final copy of the salt may be + // truncated to create S). Note that if the salt is the empty + // string, then so is S. + + S := fillWithRepeats(salt, v) + + // 3. Concatenate copies of the password together to create a string P + // of length v(ceiling(p/v)) bits (the final copy of the password + // may be truncated to create P). Note that if the password is the + // empty string, then so is P. + + P := fillWithRepeats(password, v) + + // 4. Set I=S||P to be the concatenation of S and P. + I := append(S, P...) + + // 5. Set c=ceiling(n/u). + c := (size + u - 1) / u + + // 6. For i=1, 2, ..., c, do the following: + A := make([]byte, c*20) + var IjBuf []byte + for i := 0; i < c; i++ { + // A. Set A2=H^r(D||I). (i.e., the r-th hash of D||1, + // H(H(H(... H(D||I)))) + Ai := hash(append(D, I...)) + for j := 1; j < r; j++ { + Ai = hash(Ai) + } + copy(A[i*20:], Ai[:]) + + if i < c-1 { // skip on last iteration + // B. Concatenate copies of Ai to create a string B of length v + // bits (the final copy of Ai may be truncated to create B). + var B []byte + for len(B) < v { + B = append(B, Ai[:]...) + } + B = B[:v] + + // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit + // blocks, where k=ceiling(s/v)+ceiling(p/v), modify I by + // setting I_j=(I_j+B+1) mod 2^v for each j. + { + Bbi := new(big.Int).SetBytes(B) + Ij := new(big.Int) + + for j := 0; j < len(I)/v; j++ { + Ij.SetBytes(I[j*v : (j+1)*v]) + Ij.Add(Ij, Bbi) + Ij.Add(Ij, one) + Ijb := Ij.Bytes() + // We expect Ijb to be exactly v bytes, + // if it is longer or shorter we must + // adjust it accordingly. + if len(Ijb) > v { + Ijb = Ijb[len(Ijb)-v:] + } + if len(Ijb) < v { + if IjBuf == nil { + IjBuf = make([]byte, v) + } + bytesShort := v - len(Ijb) + for i := 0; i < bytesShort; i++ { + IjBuf[i] = 0 + } + copy(IjBuf[bytesShort:], Ijb) + Ijb = IjBuf + } + copy(I[j*v:(j+1)*v], Ijb) + } + } + } + } + // 7. Concatenate A_1, A_2, ..., A_c together to form a pseudorandom + // bit string, A. + + // 8. Use the first n bits of A as the output of this entire process. + return A[:size] + + // If the above process is being used to generate a DES key, the process + // should be used to create 64 random bits, and the key's parity bits + // should be set after the 64 bits have been produced. Similar concerns + // hold for 2-key and 3-key triple-DES keys, for CDMF keys, and for any + // similar keys with parity bits "built into them". +} diff --git a/vendor/golang.org/x/crypto/pkcs12/pkcs12.go b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go new file mode 100644 index 000000000..374d9facf --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/pkcs12.go @@ -0,0 +1,364 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pkcs12 implements some of PKCS#12. +// +// This implementation is distilled from [RFC 7292] and referenced documents. +// It is intended for decoding P12/PFX-stored certificates and keys for use +// with the crypto/tls package. +// +// The pkcs12 package is [frozen] and is not accepting new features. +// If it's missing functionality you need, consider an alternative like +// software.sslmate.com/src/go-pkcs12. +// +// [RFC 7292]: https://datatracker.ietf.org/doc/html/rfc7292 +// [frozen]: https://go.dev/wiki/Frozen +package pkcs12 + +import ( + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + "encoding/hex" + "encoding/pem" + "errors" +) + +var ( + oidDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 1}) + oidEncryptedDataContentType = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 7, 6}) + + oidFriendlyName = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 20}) + oidLocalKeyID = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 21}) + oidMicrosoftCSPName = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 311, 17, 1}) + + errUnknownAttributeOID = errors.New("pkcs12: unknown attribute OID") +) + +type pfxPdu struct { + Version int + AuthSafe contentInfo + MacData macData `asn1:"optional"` +} + +type contentInfo struct { + ContentType asn1.ObjectIdentifier + Content asn1.RawValue `asn1:"tag:0,explicit,optional"` +} + +type encryptedData struct { + Version int + EncryptedContentInfo encryptedContentInfo +} + +type encryptedContentInfo struct { + ContentType asn1.ObjectIdentifier + ContentEncryptionAlgorithm pkix.AlgorithmIdentifier + EncryptedContent []byte `asn1:"tag:0,optional"` +} + +func (i encryptedContentInfo) Algorithm() pkix.AlgorithmIdentifier { + return i.ContentEncryptionAlgorithm +} + +func (i encryptedContentInfo) Data() []byte { return i.EncryptedContent } + +type safeBag struct { + Id asn1.ObjectIdentifier + Value asn1.RawValue `asn1:"tag:0,explicit"` + Attributes []pkcs12Attribute `asn1:"set,optional"` +} + +type pkcs12Attribute struct { + Id asn1.ObjectIdentifier + Value asn1.RawValue `asn1:"set"` +} + +type encryptedPrivateKeyInfo struct { + AlgorithmIdentifier pkix.AlgorithmIdentifier + EncryptedData []byte +} + +func (i encryptedPrivateKeyInfo) Algorithm() pkix.AlgorithmIdentifier { + return i.AlgorithmIdentifier +} + +func (i encryptedPrivateKeyInfo) Data() []byte { + return i.EncryptedData +} + +// PEM block types +const ( + certificateType = "CERTIFICATE" + privateKeyType = "PRIVATE KEY" +) + +// unmarshal calls asn1.Unmarshal, but also returns an error if there is any +// trailing data after unmarshaling. +func unmarshal(in []byte, out interface{}) error { + trailing, err := asn1.Unmarshal(in, out) + if err != nil { + return err + } + if len(trailing) != 0 { + return errors.New("pkcs12: trailing data found") + } + return nil +} + +// ToPEM converts all "safe bags" contained in pfxData to PEM blocks. +// Unknown attributes are discarded. +// +// Note that although the returned PEM blocks for private keys have type +// "PRIVATE KEY", the bytes are not encoded according to PKCS #8, but according +// to PKCS #1 for RSA keys and SEC 1 for ECDSA keys. +func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) { + encodedPassword, err := bmpString(password) + if err != nil { + return nil, ErrIncorrectPassword + } + + bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword) + + if err != nil { + return nil, err + } + + blocks := make([]*pem.Block, 0, len(bags)) + for _, bag := range bags { + block, err := convertBag(&bag, encodedPassword) + if err != nil { + return nil, err + } + blocks = append(blocks, block) + } + + return blocks, nil +} + +func convertBag(bag *safeBag, password []byte) (*pem.Block, error) { + block := &pem.Block{ + Headers: make(map[string]string), + } + + for _, attribute := range bag.Attributes { + k, v, err := convertAttribute(&attribute) + if err == errUnknownAttributeOID { + continue + } + if err != nil { + return nil, err + } + block.Headers[k] = v + } + + switch { + case bag.Id.Equal(oidCertBag): + block.Type = certificateType + certsData, err := decodeCertBag(bag.Value.Bytes) + if err != nil { + return nil, err + } + block.Bytes = certsData + case bag.Id.Equal(oidPKCS8ShroundedKeyBag): + block.Type = privateKeyType + + key, err := decodePkcs8ShroudedKeyBag(bag.Value.Bytes, password) + if err != nil { + return nil, err + } + + switch key := key.(type) { + case *rsa.PrivateKey: + block.Bytes = x509.MarshalPKCS1PrivateKey(key) + case *ecdsa.PrivateKey: + block.Bytes, err = x509.MarshalECPrivateKey(key) + if err != nil { + return nil, err + } + default: + return nil, errors.New("found unknown private key type in PKCS#8 wrapping") + } + default: + return nil, errors.New("don't know how to convert a safe bag of type " + bag.Id.String()) + } + return block, nil +} + +func convertAttribute(attribute *pkcs12Attribute) (key, value string, err error) { + isString := false + + switch { + case attribute.Id.Equal(oidFriendlyName): + key = "friendlyName" + isString = true + case attribute.Id.Equal(oidLocalKeyID): + key = "localKeyId" + case attribute.Id.Equal(oidMicrosoftCSPName): + // This key is chosen to match OpenSSL. + key = "Microsoft CSP Name" + isString = true + default: + return "", "", errUnknownAttributeOID + } + + if isString { + if err := unmarshal(attribute.Value.Bytes, &attribute.Value); err != nil { + return "", "", err + } + if value, err = decodeBMPString(attribute.Value.Bytes); err != nil { + return "", "", err + } + } else { + var id []byte + if err := unmarshal(attribute.Value.Bytes, &id); err != nil { + return "", "", err + } + value = hex.EncodeToString(id) + } + + return key, value, nil +} + +// Decode extracts a certificate and private key from pfxData. This function +// assumes that there is only one certificate and only one private key in the +// pfxData; if there are more use ToPEM instead. +func Decode(pfxData []byte, password string) (privateKey interface{}, certificate *x509.Certificate, err error) { + encodedPassword, err := bmpString(password) + if err != nil { + return nil, nil, err + } + + bags, encodedPassword, err := getSafeContents(pfxData, encodedPassword) + if err != nil { + return nil, nil, err + } + + if len(bags) != 2 { + err = errors.New("pkcs12: expected exactly two safe bags in the PFX PDU") + return + } + + for _, bag := range bags { + switch { + case bag.Id.Equal(oidCertBag): + if certificate != nil { + err = errors.New("pkcs12: expected exactly one certificate bag") + } + + certsData, err := decodeCertBag(bag.Value.Bytes) + if err != nil { + return nil, nil, err + } + certs, err := x509.ParseCertificates(certsData) + if err != nil { + return nil, nil, err + } + if len(certs) != 1 { + err = errors.New("pkcs12: expected exactly one certificate in the certBag") + return nil, nil, err + } + certificate = certs[0] + + case bag.Id.Equal(oidPKCS8ShroundedKeyBag): + if privateKey != nil { + err = errors.New("pkcs12: expected exactly one key bag") + return nil, nil, err + } + + if privateKey, err = decodePkcs8ShroudedKeyBag(bag.Value.Bytes, encodedPassword); err != nil { + return nil, nil, err + } + } + } + + if certificate == nil { + return nil, nil, errors.New("pkcs12: certificate missing") + } + if privateKey == nil { + return nil, nil, errors.New("pkcs12: private key missing") + } + + return +} + +func getSafeContents(p12Data, password []byte) (bags []safeBag, updatedPassword []byte, err error) { + pfx := new(pfxPdu) + if err := unmarshal(p12Data, pfx); err != nil { + return nil, nil, errors.New("pkcs12: error reading P12 data: " + err.Error()) + } + + if pfx.Version != 3 { + return nil, nil, NotImplementedError("can only decode v3 PFX PDU's") + } + + if !pfx.AuthSafe.ContentType.Equal(oidDataContentType) { + return nil, nil, NotImplementedError("only password-protected PFX is implemented") + } + + // unmarshal the explicit bytes in the content for type 'data' + if err := unmarshal(pfx.AuthSafe.Content.Bytes, &pfx.AuthSafe.Content); err != nil { + return nil, nil, err + } + + if len(pfx.MacData.Mac.Algorithm.Algorithm) == 0 { + return nil, nil, errors.New("pkcs12: no MAC in data") + } + + if err := verifyMac(&pfx.MacData, pfx.AuthSafe.Content.Bytes, password); err != nil { + if err == ErrIncorrectPassword && len(password) == 2 && password[0] == 0 && password[1] == 0 { + // some implementations use an empty byte array + // for the empty string password try one more + // time with empty-empty password + password = nil + err = verifyMac(&pfx.MacData, pfx.AuthSafe.Content.Bytes, password) + } + if err != nil { + return nil, nil, err + } + } + + var authenticatedSafe []contentInfo + if err := unmarshal(pfx.AuthSafe.Content.Bytes, &authenticatedSafe); err != nil { + return nil, nil, err + } + + if len(authenticatedSafe) != 2 { + return nil, nil, NotImplementedError("expected exactly two items in the authenticated safe") + } + + for _, ci := range authenticatedSafe { + var data []byte + + switch { + case ci.ContentType.Equal(oidDataContentType): + if err := unmarshal(ci.Content.Bytes, &data); err != nil { + return nil, nil, err + } + case ci.ContentType.Equal(oidEncryptedDataContentType): + var encryptedData encryptedData + if err := unmarshal(ci.Content.Bytes, &encryptedData); err != nil { + return nil, nil, err + } + if encryptedData.Version != 0 { + return nil, nil, NotImplementedError("only version 0 of EncryptedData is supported") + } + if data, err = pbDecrypt(encryptedData.EncryptedContentInfo, password); err != nil { + return nil, nil, err + } + default: + return nil, nil, NotImplementedError("only data and encryptedData content types are supported in authenticated safe") + } + + var safeContents []safeBag + if err := unmarshal(data, &safeContents); err != nil { + return nil, nil, err + } + bags = append(bags, safeContents...) + } + + return bags, password, nil +} diff --git a/vendor/golang.org/x/crypto/pkcs12/safebags.go b/vendor/golang.org/x/crypto/pkcs12/safebags.go new file mode 100644 index 000000000..def1f7b98 --- /dev/null +++ b/vendor/golang.org/x/crypto/pkcs12/safebags.go @@ -0,0 +1,57 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs12 + +import ( + "crypto/x509" + "encoding/asn1" + "errors" +) + +var ( + // see https://tools.ietf.org/html/rfc7292#appendix-D + oidCertTypeX509Certificate = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 22, 1}) + oidPKCS8ShroundedKeyBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 2}) + oidCertBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 3}) +) + +type certBag struct { + Id asn1.ObjectIdentifier + Data []byte `asn1:"tag:0,explicit"` +} + +func decodePkcs8ShroudedKeyBag(asn1Data, password []byte) (privateKey interface{}, err error) { + pkinfo := new(encryptedPrivateKeyInfo) + if err = unmarshal(asn1Data, pkinfo); err != nil { + return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error()) + } + + pkData, err := pbDecrypt(pkinfo, password) + if err != nil { + return nil, errors.New("pkcs12: error decrypting PKCS#8 shrouded key bag: " + err.Error()) + } + + ret := new(asn1.RawValue) + if err = unmarshal(pkData, ret); err != nil { + return nil, errors.New("pkcs12: error unmarshaling decrypted private key: " + err.Error()) + } + + if privateKey, err = x509.ParsePKCS8PrivateKey(pkData); err != nil { + return nil, errors.New("pkcs12: error parsing PKCS#8 private key: " + err.Error()) + } + + return privateKey, nil +} + +func decodeCertBag(asn1Data []byte) (x509Certificates []byte, err error) { + bag := new(certBag) + if err := unmarshal(asn1Data, bag); err != nil { + return nil, errors.New("pkcs12: error decoding cert bag: " + err.Error()) + } + if !bag.Id.Equal(oidCertTypeX509Certificate) { + return nil, NotImplementedError("only X509 certificates are supported") + } + return bag.Data, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7180800cf..56a200d71 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -69,6 +69,75 @@ github.com/Antonboom/testifylint/internal/checkers github.com/Antonboom/testifylint/internal/checkers/printf github.com/Antonboom/testifylint/internal/config github.com/Antonboom/testifylint/internal/testify +# github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 +## explicit; go 1.23.0 +github.com/Azure/azure-sdk-for-go/sdk/azcore +github.com/Azure/azure-sdk-for-go/sdk/azcore/arm +github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource +github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy +github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime +github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/fake +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op +github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared +github.com/Azure/azure-sdk-for-go/sdk/azcore/log +github.com/Azure/azure-sdk-for-go/sdk/azcore/policy +github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime +github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming +github.com/Azure/azure-sdk-for-go/sdk/azcore/to +github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing +# github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 +## explicit; go 1.23.0 +github.com/Azure/azure-sdk-for-go/sdk/azidentity +github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal +# github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 +## explicit; go 1.23.0 +github.com/Azure/azure-sdk-for-go/sdk/internal/diag +github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo +github.com/Azure/azure-sdk-for-go/sdk/internal/exported +github.com/Azure/azure-sdk-for-go/sdk/internal/log +github.com/Azure/azure-sdk-for-go/sdk/internal/poller +github.com/Azure/azure-sdk-for-go/sdk/internal/temporal +github.com/Azure/azure-sdk-for-go/sdk/internal/uuid +# github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 +## explicit; go 1.18 +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 +# github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0 +## explicit; go 1.23.0 +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi +# github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 +## explicit; go 1.18 +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources +# github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 +## explicit; go 1.18 +github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache +github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential +github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/base/storage +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/exported +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/local +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops +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/oauth/ops/internal/comm +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/internal/grant +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/wstrust/defs +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/options +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared +github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version +github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity +github.com/AzureAD/microsoft-authentication-library-for-go/apps/public # github.com/BurntSushi/toml v1.5.0 ## explicit; go 1.18 github.com/BurntSushi/toml @@ -570,6 +639,9 @@ github.com/gogo/protobuf/protoc-gen-gogo/plugin github.com/gogo/protobuf/sortkeys github.com/gogo/protobuf/vanity github.com/gogo/protobuf/vanity/command +# github.com/golang-jwt/jwt/v5 v5.3.0 +## explicit; go 1.21 +github.com/golang-jwt/jwt/v5 # github.com/golang/protobuf v1.5.4 ## explicit; go 1.17 github.com/golang/protobuf/proto @@ -969,6 +1041,7 @@ github.com/kunwardeep/paralleltest/pkg/paralleltest # github.com/kylelemons/godebug v1.1.0 ## explicit; go 1.11 github.com/kylelemons/godebug/diff +github.com/kylelemons/godebug/pretty # github.com/lasiar/canonicalheader v1.1.2 ## explicit; go 1.22.0 github.com/lasiar/canonicalheader @@ -1311,6 +1384,9 @@ github.com/pelletier/go-toml/v2/internal/characters github.com/pelletier/go-toml/v2/internal/danger github.com/pelletier/go-toml/v2/internal/tracker github.com/pelletier/go-toml/v2/unstable +# github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c +## explicit; go 1.14 +github.com/pkg/browser # github.com/pkg/profile v1.7.0 ## explicit; go 1.13 github.com/pkg/profile @@ -1705,6 +1781,8 @@ golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/nacl/secretbox +golang.org/x/crypto/pkcs12 +golang.org/x/crypto/pkcs12/internal/rc2 golang.org/x/crypto/salsa20/salsa golang.org/x/crypto/sha3 # golang.org/x/exp v0.0.0-20250911091902-df9299821621