From 810a15621dbca6622fa5c4a2ae3b05ed8a5440c5 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Fri, 28 Feb 2025 10:38:19 +0100 Subject: [PATCH 1/7] kola: Introduce support for assigning an MSI to spawned VMs For access to Azure resources. Signed-off-by: Jeremi Piotrowski --- cmd/kola/options.go | 1 + platform/api/azure/api.go | 45 +++++++++++++++++++++++++++++++ platform/api/azure/instance.go | 29 +++++++++++++++----- platform/api/azure/options.go | 2 ++ platform/machine/azure/cluster.go | 14 +++++----- platform/machine/azure/flight.go | 16 +++++++++-- 6 files changed, 93 insertions(+), 14 deletions(-) diff --git a/cmd/kola/options.go b/cmd/kola/options.go index c863028d0..f1c897788 100644 --- a/cmd/kola/options.go +++ b/cmd/kola/options.go @@ -125,6 +125,7 @@ func init() { sv(&kola.AzureOptions.ResourceGroup, "azure-resource-group", "", "Deploy resources in an existing resource group") sv(&kola.AzureOptions.AvailabilitySet, "azure-availability-set", "", "Deploy instances with an existing availibity set") sv(&kola.AzureOptions.KolaVnet, "azure-kola-vnet", "", "Pass the vnet/subnet that kola is being ran from to restrict network access to created storage accounts") + sv(&kola.AzureOptions.VMIdentity, "azure-vm-identity", "", "Assign a managed identity to the VM by name (will be looked up for its ID)") // do-specific options sv(&kola.DOOptions.ConfigPath, "do-config-file", "", "DigitalOcean config file (default \"~/"+auth.DOConfigPath+"\")") diff --git a/platform/api/azure/api.go b/platform/api/azure/api.go index f47d5b61e..1844ae974 100644 --- a/platform/api/azure/api.go +++ b/platform/api/azure/api.go @@ -29,6 +29,7 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" @@ -59,6 +60,7 @@ type API struct { ipClient *armnetwork.PublicIPAddressesClient intClient *armnetwork.InterfacesClient accClient *armstorage.AccountsClient + msiClient *armmsi.UserAssignedIdentitiesClient Opts *Options } @@ -194,6 +196,12 @@ func (a *API) SetupClients() error { } a.accClient = scf.NewAccountsClient() + mcf, err := armmsi.NewClientFactory(a.subID, a.creds, opts) + if err != nil { + return err + } + a.msiClient = mcf.NewUserAssignedIdentitiesClient() + return nil } @@ -302,3 +310,40 @@ func (a *API) GC(gracePeriod time.Duration) error { return nil } + +// FindManagedIdentityID searches for a managed identity by name across the subscription +// and returns its resource ID if found +func (a *API) FindManagedIdentityID(identityName string) (string, error) { + ctx := context.TODO() + + // Use NewListBySubscriptionPager to search across the entire subscription + pager := a.msiClient.NewListBySubscriptionPager(nil) + + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return "", fmt.Errorf("failed to list managed identities: %v", err) + } + + // Check each identity for a name match + for _, identity := range page.Value { + if identity.Name != nil && *identity.Name == identityName { + if identity.ID == nil || *identity.ID == "" { + continue + } + + // Extract resource group name from the ID for logging + idParts := strings.Split(*identity.ID, "/") + var resourceGroup string + if len(idParts) >= 5 { + resourceGroup = idParts[4] + } + + plog.Infof("Found managed identity %s in resource group %s", identityName, resourceGroup) + return *identity.ID, nil + } + } + } + + return "", fmt.Errorf("managed identity %q was not found in the subscription", identityName) +} diff --git a/platform/api/azure/instance.go b/platform/api/azure/instance.go index df3fb8768..12119e44d 100644 --- a/platform/api/azure/instance.go +++ b/platform/api/azure/instance.go @@ -53,7 +53,7 @@ func (a *API) getVMRG(rg string) string { return vmrg } -func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata *conf.Conf, ip *armnetwork.PublicIPAddress, nic *armnetwork.Interface) armcompute.VirtualMachine { +func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata *conf.Conf, ip *armnetwork.PublicIPAddress, nic *armnetwork.Interface, managedIdentityID string) armcompute.VirtualMachine { osProfile := armcompute.OSProfile{ AdminUsername: to.Ptr("core"), ComputerName: &name, @@ -113,6 +113,8 @@ func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata * plog.Warningf("failed to get image info: %v; continuing", err) } } + + // Set up the VM configuration vm := armcompute.VirtualMachine{ Name: &name, Location: &a.Opts.Location, @@ -155,6 +157,7 @@ func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata * }, } + // Configure disk controller if specified switch a.Opts.DiskController { case "nvme": vm.Properties.StorageProfile.DiskControllerType = to.Ptr(armcompute.DiskControllerTypesNVMe) @@ -162,8 +165,7 @@ func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata * vm.Properties.StorageProfile.DiskControllerType = to.Ptr(armcompute.DiskControllerTypesSCSI) } - // I don't think it would be an issue to have empty user-data set but better - // to be safe than sorry. + // Configure user data or custom data if ud != "" { if a.Opts.UseUserData && userdata.IsIgnition() { plog.Infof("using user-data") @@ -174,15 +176,29 @@ func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata * } } + // Configure availability set if specified availabilitySetID := a.getAvset() if availabilitySetID != "" { vm.Properties.AvailabilitySet = &armcompute.SubResource{ID: &availabilitySetID} } + // Configure managed identity if specified + if managedIdentityID != "" { + plog.Infof("Assigning managed identity to VM (using pre-looked-up ID)") + + // Configure the VM with the user assigned managed identity + vm.Identity = &armcompute.VirtualMachineIdentity{ + Type: to.Ptr(armcompute.ResourceIdentityTypeUserAssigned), + UserAssignedIdentities: map[string]*armcompute.UserAssignedIdentitiesValue{ + managedIdentityID: {}, + }, + } + } + return vm } -func (a *API) CreateInstance(name, sshkey, resourceGroup, storageAccount string, userdata *conf.Conf, network Network) (*Machine, error) { +func (a *API) CreateInstance(name, sshkey, resourceGroup, storageAccount string, userdata *conf.Conf, network Network, managedIdentityID string) (*Machine, error) { // only VMs are created in the user supplied resource group, kola still manages a resource group // for the gallery and storage account. vmResourceGroup := a.getVMRG(resourceGroup) @@ -204,7 +220,8 @@ func (a *API) CreateInstance(name, sshkey, resourceGroup, storageAccount string, return nil, fmt.Errorf("couldn't get NIC name") } - vmParams := a.getVMParameters(name, sshkey, fmt.Sprintf("https://%s.blob.core.windows.net/", storageAccount), userdata, ip, nic) + // Pass the managedIdentityID to getVMParameters + vmParams := a.getVMParameters(name, sshkey, fmt.Sprintf("https://%s.blob.core.windows.net/", storageAccount), userdata, ip, nic, managedIdentityID) plog.Infof("Creating Instance %s", name) clean := func() { @@ -317,6 +334,7 @@ func (a *API) GetConsoleOutput(name, resourceGroup, storageAccount string) ([]by if err != nil { return nil, err } + var data io.ReadCloser err = util.Retry(6, 10*time.Second, func() error { data, err = GetBlob(client, container, blobname) @@ -331,6 +349,5 @@ func (a *API) GetConsoleOutput(name, resourceGroup, storageAccount string) ([]by if err != nil { return nil, err } - return io.ReadAll(data) } diff --git a/platform/api/azure/options.go b/platform/api/azure/options.go index e95a5bbd5..726b6242c 100644 --- a/platform/api/azure/options.go +++ b/platform/api/azure/options.go @@ -63,4 +63,6 @@ type Options struct { ResourceGroup string // AvailabilitySet is an existing availability set to deploy the instance in. AvailabilitySet string + // VMIdentity is the name of a managed identity to assign to the VM. + VMIdentity string } diff --git a/platform/machine/azure/cluster.go b/platform/machine/azure/cluster.go index 8b91cee6f..ee7a2f2fa 100644 --- a/platform/machine/azure/cluster.go +++ b/platform/machine/azure/cluster.go @@ -27,11 +27,12 @@ import ( type cluster struct { *platform.BaseCluster - flight *flight - sshKey string - ResourceGroup string - StorageAccount string - Network azure.Network + flight *flight + sshKey string + ResourceGroup string + StorageAccount string + Network azure.Network + ManagedIdentityID string // Add managed identity ID field to cluster struct } func (ac *cluster) vmname() string { @@ -48,7 +49,8 @@ func (ac *cluster) NewMachine(userdata *conf.UserData) (platform.Machine, error) return nil, err } - instance, err := ac.flight.Api.CreateInstance(ac.vmname(), ac.sshKey, ac.ResourceGroup, ac.StorageAccount, conf, ac.Network) + // Pass the managed identity ID to the CreateInstance method + instance, err := ac.flight.Api.CreateInstance(ac.vmname(), ac.sshKey, ac.ResourceGroup, ac.StorageAccount, conf, ac.Network, ac.ManagedIdentityID) if err != nil { return nil, err } diff --git a/platform/machine/azure/flight.go b/platform/machine/azure/flight.go index 834a4a7c7..1f1a76d04 100644 --- a/platform/machine/azure/flight.go +++ b/platform/machine/azure/flight.go @@ -41,6 +41,7 @@ type flight struct { ImageResourceGroup string ImageStorageAccount string Network azure.Network + ManagedIdentityID string // Store the managed identity resource ID } // NewFlight creates an instance of a Flight suitable for spawning @@ -79,6 +80,16 @@ func NewFlight(opts *azure.Options) (platform.Flight, error) { return nil, err } + // If a managed identity is specified, look it up across all resource groups + // and fail fast if it can't be found + if opts.VMIdentity != "" { + plog.Infof("Looking up managed identity %q", opts.VMIdentity) + af.ManagedIdentityID, err = api.FindManagedIdentityID(opts.VMIdentity) + if err != nil { + return nil, err + } + } + if opts.BlobURL != "" || opts.ImageFile != "" { imageName := fmt.Sprintf("%v", time.Now().UnixNano()) blobName := imageName + ".vhd" @@ -152,8 +163,9 @@ func (af *flight) NewCluster(rconf *platform.RuntimeConfig) (platform.Cluster, e } ac := &cluster{ - BaseCluster: bc, - flight: af, + BaseCluster: bc, + flight: af, + ManagedIdentityID: af.ManagedIdentityID, } if !rconf.NoSSHKeyInMetadata { From 42cd09fec320cd516ce1b4cfb2767eb42394cd90 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Fri, 28 Feb 2025 10:54:52 +0100 Subject: [PATCH 2/7] go.mod: Vendor new deps Signed-off-by: Jeremi Piotrowski --- go.mod | 1 + go.sum | 2 + .../resourcemanager/msi/armmsi/CHANGELOG.md | 61 ++ .../resourcemanager/msi/armmsi/LICENSE.txt | 21 + .../sdk/resourcemanager/msi/armmsi/README.md | 92 +++ .../resourcemanager/msi/armmsi/autorest.md | 12 + .../sdk/resourcemanager/msi/armmsi/build.go | 7 + .../sdk/resourcemanager/msi/armmsi/ci.yml | 28 + .../msi/armmsi/client_factory.go | 62 ++ .../resourcemanager/msi/armmsi/constants.go | 34 ++ .../federatedidentitycredentials_client.go | 320 ++++++++++ .../sdk/resourcemanager/msi/armmsi/models.go | 212 +++++++ .../msi/armmsi/models_serde.go | 551 ++++++++++++++++++ .../msi/armmsi/operations_client.go | 88 +++ .../sdk/resourcemanager/msi/armmsi/options.go | 85 +++ .../msi/armmsi/response_types.go | 79 +++ .../armmsi/systemassignedidentities_client.go | 92 +++ .../msi/armmsi/time_rfc3339.go | 86 +++ .../armmsi/userassignedidentities_client.go | 417 +++++++++++++ vendor/modules.txt | 3 + 20 files changed, 2253 insertions(+) create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/CHANGELOG.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/LICENSE.txt create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/README.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/autorest.md create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/build.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/ci.yml create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/client_factory.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/constants.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/federatedidentitycredentials_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models_serde.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/operations_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/options.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/response_types.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/systemassignedidentities_client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/time_rfc3339.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/userassignedidentities_client.go diff --git a/go.mod b/go.mod index c5c2231dc..e89647eb7 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.3.0 diff --git a/go.sum b/go.sum index aa0b6a912..4f5460393 100644 --- a/go.sum +++ b/go.sum @@ -53,6 +53,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.0.0 h1:Kb8e github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.0.0/go.mod h1:lYq15QkJyEsNegz5EhI/0SXQ6spvGfgwBH/Qyzkoc/s= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 h1:z4YeiSXxnUI+PqB46Yj6MZA3nwb1CcJIkEMDrzUd8Cs= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0/go.mod h1:rko9SzMxcMk0NJsNAxALEGaTYyy79bNRwxgJfrH0Spw= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0 h1:qBlqTo40ARdI7Pmq+enBiTnejZk2BF+PHgktgG8k3r8= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0/go.mod h1:UmyOatRyQodVpp55Jr5WJmnkmVW4wKfo85uHFmMEjfM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM= 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..9b60a1774 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/CHANGELOG.md @@ -0,0 +1,61 @@ +# Release History + +## 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..abbfe159b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/README.md @@ -0,0 +1,92 @@ +# Azure Managed Service Identity Module for Go + +[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi) + +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/) +- 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 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.NewSystemAssignedIdentitiesClient() +``` + +## 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. \ No newline at end of file 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..9e29b3c26 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/autorest.md @@ -0,0 +1,12 @@ +### AutoRest Configuration + +> see https://aka.ms/autorest + +``` yaml +azure-arm: true +require: +- https://github.com/Azure/azure-rest-api-specs/blob/3d7a3848106b831a4a7f46976fe38aa605c4f44d/specification/msi/resource-manager/readme.md +- https://github.com/Azure/azure-rest-api-specs/blob/3d7a3848106b831a4a7f46976fe38aa605c4f44d/specification/msi/resource-manager/readme.go.md +license-header: MICROSOFT_MIT_NO_VERSION +module-version: 1.2.0 +``` \ 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..e0f6bb372 --- /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..a85eb8577 --- /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/ + +stages: +- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + IncludeRelease: true + ServiceDirectory: 'resourcemanager/msi/armmsi' 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..393276494 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/client_factory.go @@ -0,0 +1,62 @@ +//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 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 + 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 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) { + _, err := arm.NewClient(moduleName, moduleVersion, credential, options) + if err != nil { + return nil, err + } + return &ClientFactory{ + subscriptionID: subscriptionID, credential: credential, + options: options.Clone(), + }, nil +} + +// NewFederatedIdentityCredentialsClient creates a new instance of FederatedIdentityCredentialsClient. +func (c *ClientFactory) NewFederatedIdentityCredentialsClient() *FederatedIdentityCredentialsClient { + subClient, _ := NewFederatedIdentityCredentialsClient(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 +} + +// NewSystemAssignedIdentitiesClient creates a new instance of SystemAssignedIdentitiesClient. +func (c *ClientFactory) NewSystemAssignedIdentitiesClient() *SystemAssignedIdentitiesClient { + subClient, _ := NewSystemAssignedIdentitiesClient(c.credential, c.options) + return subClient +} + +// NewUserAssignedIdentitiesClient creates a new instance of UserAssignedIdentitiesClient. +func (c *ClientFactory) NewUserAssignedIdentitiesClient() *UserAssignedIdentitiesClient { + subClient, _ := NewUserAssignedIdentitiesClient(c.subscriptionID, c.credential, c.options) + return subClient +} 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..2039b18f8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/constants.go @@ -0,0 +1,34 @@ +//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 armmsi + +const ( + moduleName = "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi" + moduleVersion = "v1.2.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, + } +} 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..a08832b71 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/federatedidentitycredentials_client.go @@ -0,0 +1,320 @@ +//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 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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.Top != nil { + reqQP.Set("$top", strconv.FormatInt(int64(*options.Top), 10)) + } + if options != nil && options.Skiptoken != nil { + reqQP.Set("$skiptoken", *options.Skiptoken) + } + reqQP.Set("api-version", "2023-01-31") + 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..2fd87e988 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models.go @@ -0,0 +1,212 @@ +//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 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 { + // 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..7278b8517 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/models_serde.go @@ -0,0 +1,551 @@ +//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 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, "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 "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 { + 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..d5c3e5e09 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/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 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 2023-01-31 +// - 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.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", "2023-01-31") + 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..da98a4195 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/options.go @@ -0,0 +1,85 @@ +//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 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/response_types.go b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/response_types.go new file mode 100644 index 000000000..386557595 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/response_types.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 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..7bd33c632 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/systemassignedidentities_client.go @@ -0,0 +1,92 @@ +//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 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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..521edea20 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/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 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 ( + 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/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..961400e33 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi/userassignedidentities_client.go @@ -0,0 +1,417 @@ +//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 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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 2023-01-31 +// - 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, options *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", "2023-01-31") + 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/modules.txt b/vendor/modules.txt index a7a34e556..b57c2f363 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -56,6 +56,9 @@ github.com/Azure/azure-sdk-for-go/sdk/internal/uuid # github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 ## explicit; go 1.18 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 +# github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 +## explicit; go 1.18 +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi # github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 v5.2.0 ## explicit; go 1.18 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v5 From daadea821db96ddac8bd3afe4f383169cf585eb1 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Wed, 5 Mar 2025 17:52:48 +0100 Subject: [PATCH 3/7] cluster: Comply with NoSSHKeyInUserData even when --keys is passed Signed-off-by: Jeremi Piotrowski --- platform/cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/cluster.go b/platform/cluster.go index e7adfc67b..57b0051c9 100644 --- a/platform/cluster.go +++ b/platform/cluster.go @@ -162,7 +162,7 @@ func (bc *BaseCluster) RenderUserData(userdata *conf.UserData, ignitionVars map[ } } - if bc.bf.AdditionalSshKeys != nil && *bc.bf.AdditionalSshKeys != nil { + if bc.bf.AdditionalSshKeys != nil && *bc.bf.AdditionalSshKeys != nil && !bc.rconf.NoSSHKeyInUserData { userdata = conf.AddSSHKeys(userdata, bc.bf.AdditionalSshKeys) } From 25a29fa589c402418860fdd1b7a81745bbdea0de Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Mon, 5 Aug 2024 10:46:18 +0200 Subject: [PATCH 4/7] azure: Switch to managed boot diagnostics for console This does not require that the user have RBAC permissions to a storage account to fetch, because it uses SAS keys behind the scenes. The previous approach used a kola created storage account has Shared Key Access disabled for security reasons. Signed-off-by: Jeremi Piotrowski --- platform/api/azure/instance.go | 54 ++++++++++++---------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/platform/api/azure/instance.go b/platform/api/azure/instance.go index 12119e44d..6138bfc4c 100644 --- a/platform/api/azure/instance.go +++ b/platform/api/azure/instance.go @@ -19,7 +19,7 @@ import ( "encoding/base64" "fmt" "io" - "regexp" + "net/http" "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" @@ -150,8 +150,7 @@ func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata * }, DiagnosticsProfile: &armcompute.DiagnosticsProfile{ BootDiagnostics: &armcompute.BootDiagnostics{ - Enabled: to.Ptr(true), - StorageURI: &storageAccountURI, + Enabled: to.Ptr(true), }, }, }, @@ -303,51 +302,36 @@ func (a *API) TerminateInstance(machine *Machine, resourceGroup string) error { func (a *API) GetConsoleOutput(name, resourceGroup, storageAccount string) ([]byte, error) { vmResourceGroup := a.getVMRG(resourceGroup) - vm, err := a.compClient.Get(context.TODO(), vmResourceGroup, name, &armcompute.VirtualMachinesClientGetOptions{ - Expand: to.Ptr(armcompute.InstanceViewTypesInstanceView), - }) + param := &armcompute.VirtualMachinesClientRetrieveBootDiagnosticsDataOptions{ + SasURIExpirationTimeInMinutes: to.Ptr[int32](5), + } + resp, err := a.compClient.RetrieveBootDiagnosticsData(context.TODO(), vmResourceGroup, name, param) if err != nil { return nil, fmt.Errorf("could not get VM: %v", err) } - - consoleURI := vm.Properties.InstanceView.BootDiagnostics.SerialConsoleLogBlobURI - if consoleURI == nil { + if resp.SerialConsoleLogBlobURI == nil { return nil, fmt.Errorf("serial console URI is nil") } - // Only the full URI to the logs are present in the virtual machine - // properties. Parse out the container & file name to use the GetBlob - // API call directly. - uri := []byte(*consoleURI) - containerPat := regexp.MustCompile(`bootdiagnostics-[a-z0-9\-]+`) - container := string(containerPat.Find(uri)) - if container == "" { - return nil, fmt.Errorf("could not find container name in URI: %q", *consoleURI) - } - namePat := regexp.MustCompile(`[a-z0-9\-\.]+.serialconsole.log`) - blobname := string(namePat.Find(uri)) - if blobname == "" { - return nil, fmt.Errorf("could not find blob name in URI: %q", *consoleURI) - } - - client, err := a.GetBlobServiceClient(storageAccount) - if err != nil { - return nil, err - } - - var data io.ReadCloser + var output []byte err = util.Retry(6, 10*time.Second, func() error { - data, err = GetBlob(client, container, blobname) + reply, err := http.Get(*resp.SerialConsoleLogBlobURI) if err != nil { - return fmt.Errorf("could not get blob for container %q, blobname %q: %v", container, blobname, err) + return fmt.Errorf("could not GET console output: %v", err) + } + body := reply.Body + defer body.Close() + if reply.StatusCode != 200 { + return fmt.Errorf("unexpected status code: %v", reply.StatusCode) } - if data == nil { - return fmt.Errorf("empty data while getting blob for container %q, blobname %q", container, blobname) + output, err = io.ReadAll(body) + if err != nil { + return fmt.Errorf("could not read console output: %v", err) } return nil }) if err != nil { return nil, err } - return io.ReadAll(data) + return output, nil } From e00f97fa36cd2aa066a9b7a786521b7fca0db71f Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Wed, 5 Mar 2025 18:06:44 +0100 Subject: [PATCH 5/7] azure: Remove unused StorageAccount We switched to managed boot diagnostics, so we no longer require a separate storage account for that purpose. We still need a storage account when uploading images. Signed-off-by: Jeremi Piotrowski --- platform/api/azure/instance.go | 8 ++++---- platform/machine/azure/cluster.go | 3 +-- platform/machine/azure/flight.go | 6 ------ platform/machine/azure/machine.go | 2 +- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/platform/api/azure/instance.go b/platform/api/azure/instance.go index 6138bfc4c..5981abd07 100644 --- a/platform/api/azure/instance.go +++ b/platform/api/azure/instance.go @@ -53,7 +53,7 @@ func (a *API) getVMRG(rg string) string { return vmrg } -func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata *conf.Conf, ip *armnetwork.PublicIPAddress, nic *armnetwork.Interface, managedIdentityID string) armcompute.VirtualMachine { +func (a *API) getVMParameters(name, sshkey string, userdata *conf.Conf, ip *armnetwork.PublicIPAddress, nic *armnetwork.Interface, managedIdentityID string) armcompute.VirtualMachine { osProfile := armcompute.OSProfile{ AdminUsername: to.Ptr("core"), ComputerName: &name, @@ -197,7 +197,7 @@ func (a *API) getVMParameters(name, sshkey, storageAccountURI string, userdata * return vm } -func (a *API) CreateInstance(name, sshkey, resourceGroup, storageAccount string, userdata *conf.Conf, network Network, managedIdentityID string) (*Machine, error) { +func (a *API) CreateInstance(name, sshkey, resourceGroup string, userdata *conf.Conf, network Network, managedIdentityID string) (*Machine, error) { // only VMs are created in the user supplied resource group, kola still manages a resource group // for the gallery and storage account. vmResourceGroup := a.getVMRG(resourceGroup) @@ -220,7 +220,7 @@ func (a *API) CreateInstance(name, sshkey, resourceGroup, storageAccount string, } // Pass the managedIdentityID to getVMParameters - vmParams := a.getVMParameters(name, sshkey, fmt.Sprintf("https://%s.blob.core.windows.net/", storageAccount), userdata, ip, nic, managedIdentityID) + vmParams := a.getVMParameters(name, sshkey, userdata, ip, nic, managedIdentityID) plog.Infof("Creating Instance %s", name) clean := func() { @@ -300,7 +300,7 @@ func (a *API) TerminateInstance(machine *Machine, resourceGroup string) error { return err } -func (a *API) GetConsoleOutput(name, resourceGroup, storageAccount string) ([]byte, error) { +func (a *API) GetConsoleOutput(name, resourceGroup string) ([]byte, error) { vmResourceGroup := a.getVMRG(resourceGroup) param := &armcompute.VirtualMachinesClientRetrieveBootDiagnosticsDataOptions{ SasURIExpirationTimeInMinutes: to.Ptr[int32](5), diff --git a/platform/machine/azure/cluster.go b/platform/machine/azure/cluster.go index ee7a2f2fa..4c534bc3f 100644 --- a/platform/machine/azure/cluster.go +++ b/platform/machine/azure/cluster.go @@ -30,7 +30,6 @@ type cluster struct { flight *flight sshKey string ResourceGroup string - StorageAccount string Network azure.Network ManagedIdentityID string // Add managed identity ID field to cluster struct } @@ -50,7 +49,7 @@ func (ac *cluster) NewMachine(userdata *conf.UserData) (platform.Machine, error) } // Pass the managed identity ID to the CreateInstance method - instance, err := ac.flight.Api.CreateInstance(ac.vmname(), ac.sshKey, ac.ResourceGroup, ac.StorageAccount, conf, ac.Network, ac.ManagedIdentityID) + instance, err := ac.flight.Api.CreateInstance(ac.vmname(), ac.sshKey, ac.ResourceGroup, conf, ac.Network, ac.ManagedIdentityID) if err != nil { return nil, err } diff --git a/platform/machine/azure/flight.go b/platform/machine/azure/flight.go index 1f1a76d04..dc4b1aaee 100644 --- a/platform/machine/azure/flight.go +++ b/platform/machine/azure/flight.go @@ -176,7 +176,6 @@ func (af *flight) NewCluster(rconf *platform.RuntimeConfig) (platform.Cluster, e if af.ImageResourceGroup != "" && af.ImageStorageAccount != "" { ac.ResourceGroup = af.ImageResourceGroup - ac.StorageAccount = af.ImageStorageAccount ac.Network = af.Network } else { ac.ResourceGroup, err = af.Api.CreateResourceGroup("kola-cluster") @@ -184,11 +183,6 @@ func (af *flight) NewCluster(rconf *platform.RuntimeConfig) (platform.Cluster, e return nil, err } - ac.StorageAccount, err = af.Api.CreateStorageAccount(ac.ResourceGroup) - if err != nil { - return nil, err - } - ac.Network, err = af.Api.PrepareNetworkResources(ac.ResourceGroup) if err != nil { ac.Destroy() diff --git a/platform/machine/azure/machine.go b/platform/machine/azure/machine.go index 2470f5dbb..6e41051ec 100644 --- a/platform/machine/azure/machine.go +++ b/platform/machine/azure/machine.go @@ -110,7 +110,7 @@ func (am *machine) ConsoleOutput() string { func (am *machine) saveConsole() error { var err error - am.console, err = am.cluster.flight.Api.GetConsoleOutput(am.ID(), am.ResourceGroup(), am.cluster.StorageAccount) + am.console, err = am.cluster.flight.Api.GetConsoleOutput(am.ID(), am.ResourceGroup()) if err != nil { return err } From 50a88222f6b0e24f0a548490557cad4a442bd87c Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Tue, 6 Aug 2024 09:25:06 +0200 Subject: [PATCH 6/7] kola: spawn: Fix detach option Ignition v3 does not tolerate duplicate ssh keys, which we will often get if we fetch them from ssh-agent and from the filesystem. Implement key deduplication in GetSSHKeys(), which is called when `-t` is passed. Signed-off-by: Jeremi Piotrowski --- cmd/kola/options.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cmd/kola/options.go b/cmd/kola/options.go index f1c897788..1368d01de 100644 --- a/cmd/kola/options.go +++ b/cmd/kola/options.go @@ -417,5 +417,15 @@ func GetSSHKeys(sshKeys []string) ([]agent.Key, error) { allKeys = append(allKeys, key) } + // Ignition v3 does not allow duplicate keys so we need to deduplicate + allUniqueKeys := make(map[string]*agent.Key) + for _, key := range allKeys { + allUniqueKeys[string(key.Blob)] = &key + } + allKeys = []agent.Key{} + for _, value := range allUniqueKeys { + allKeys = append(allKeys, *value) + } + return allKeys, nil } From 4e6606bcd3d3a96a4504d4cc592bcf700aa106c1 Mon Sep 17 00:00:00 2001 From: Jeremi Piotrowski Date: Thu, 8 Aug 2024 14:25:27 +0200 Subject: [PATCH 7/7] retry: Sleep after failure This way if the condition is true in the first iteration we exit immediately. Signed-off-by: Jeremi Piotrowski --- util/retry.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/retry.go b/util/retry.go index 554f6fbe7..8fe43f0ba 100644 --- a/util/retry.go +++ b/util/retry.go @@ -57,8 +57,6 @@ func WaitUntilReady(timeout, delay time.Duration, checkFunction func() (bool, er default: } - time.Sleep(delay) - done, err := checkFunction() if err != nil { return err @@ -67,6 +65,8 @@ func WaitUntilReady(timeout, delay time.Duration, checkFunction func() (bool, er if done { break } + + time.Sleep(delay) } return nil }