From 8c96516231f9a245d22e7d4854bf8221b92353c2 Mon Sep 17 00:00:00 2001 From: mabhi Date: Wed, 27 Sep 2023 10:49:07 +0530 Subject: [PATCH 01/18] Upgrade to new azure-go-sdk and refactor old go-autorest references Signed-off-by: mabhi --- go.mod | 14 +- go.sum | 12 +- pkg/blockstorage/azure/auth.go | 75 +++-- pkg/blockstorage/azure/azuredisk.go | 380 +++++++++++++------------- pkg/blockstorage/azure/client.go | 137 +++++----- pkg/blockstorage/azure/client_test.go | 10 +- pkg/blockstorage/helpers.go | 141 ++++++++++ 7 files changed, 463 insertions(+), 306 deletions(-) diff --git a/go.mod b/go.mod index 068c6a8655..4c1b3dfaef 100644 --- a/go.mod +++ b/go.mod @@ -13,10 +13,12 @@ replace ( // Direct and indirect dependencies are in separate require sections require ( github.com/Azure/azure-sdk-for-go v68.0.0+incompatible + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0 github.com/Azure/go-autorest/autorest v0.11.29 - github.com/Azure/go-autorest/autorest/adal v0.9.23 github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 - github.com/Azure/go-autorest/autorest/to v0.4.0 github.com/Masterminds/semver v1.5.0 github.com/Masterminds/sprig v2.22.0+incompatible github.com/aws/aws-sdk-go v1.47.11 @@ -63,6 +65,7 @@ require ( sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/kustomize/kyaml v0.13.9 sigs.k8s.io/yaml v1.3.0 + ) require ( @@ -71,14 +74,13 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.4 // indirect cloud.google.com/go/storage v1.33.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 // indirect; indirect; github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 // indirect @@ -143,6 +145,7 @@ require ( github.com/klauspost/reedsolomon v1.11.8 // indirect github.com/kopia/htmluibuild v0.0.1-0.20231019063300-75c2a788c7d0 // indirect github.com/kr/fs v0.1.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -216,17 +219,16 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect - github.com/kylelemons/godebug v1.1.0 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect diff --git a/go.sum b/go.sum index a61585c594..280944491e 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,16 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZM github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 h1:TuEMD+E+1aTjjLICGQOW6vLe8UWES7kopac9mUXL56Y= github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 h1:UPeCRD+XY7QlaGQte2EVI2iOcWvUYA2XY8w5T/8v0NQ= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1/go.mod h1:oGV6NlB0cvi1ZbYRR2UN44QHxWFyGk+iylgD0qaMXjA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2/go.mod h1:FbdwsQ2EzwvXxOPcMFYO8ogEc9uMMIj3YkmCdXdAFmk= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.0.0 h1:nBy98uKOIfun5z6wx6jwWLrULcM0+cjBalBFZlEZ7CA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.0.0/go.mod h1:243D9iHbcQXoFUtgHJwL7gl2zx1aDuDMjvBZVGr2uW0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0 h1:Pmy0+3ox1IC3sp6musv87BFPIdQbqyPFjn7I8I0o2Js= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0/go.mod h1:ThfyMjs6auYrWPnYJjI3H4H++oVPrz01pizpu8lfl3A= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 h1:gggzg0SUMs6SQbEw+3LoSsYf9YMjkupeAnHMX8O9mmY= @@ -68,8 +78,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9A github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index 524330f7bb..a1e0cf8138 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -2,13 +2,16 @@ package azure import ( "context" - - "github.com/Azure/go-autorest/autorest/adal" - "github.com/Azure/go-autorest/autorest/azure/auth" + _ "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/pkg/errors" ) +const ActiveDirectory = "activeDirectory" + // currently avaialble types: https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authorization // to be available with azidentity: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#readme-credential-types // determine if the combination of creds are client secret creds @@ -25,6 +28,28 @@ func isMSICredsAvailable(config map[string]string) bool { config[blockstorage.AzureClientSecret] == "") } +type ClientCredentialsConfig struct { + ClientID string + ClientSecret string + TenantID string + AuxTenants []string + AADEndpoint string + Resource string +} + +// Defaults to Public Cloud and Resource Manager Endpoint. +func NewClientCredentialsConfig(clientID string, clientSecret string, tenantID string) ClientCredentialsConfig { + return ClientCredentialsConfig{ + ClientID: clientID, + ClientSecret: clientSecret, + TenantID: tenantID, + Resource: cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint, + //Todo: find a replacement for the AADEndpoint in the new azure sdk + AADEndpoint: cloud.AzurePublic.Services[ActiveDirectory].Endpoint, + //azure.PublicCloud.ActiveDirectoryEndpoint, + } +} + // Public interface to authenticate with different Azure credentials type type AzureAuthenticator interface { Authenticate(creds map[string]string) error @@ -46,22 +71,21 @@ type MsiAuthenticator struct{} func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { // check if MSI endpoint is available - if !adal.MSIAvailable(context.Background(), nil) { - return errors.New("MSI endpoint is not supported") - } - // create a service principal token - msiConfig := auth.NewMSIConfig() - if clientID, ok := creds[blockstorage.AzureClientID]; ok && clientID != "" { - msiConfig.ClientID = clientID + + clientID, ok := creds[blockstorage.AzureClientID] + if !ok || clientID == "" { + return errors.New("Failed to fetch azure clientID") } - spt, err := msiConfig.ServicePrincipalToken() + azClientID := azidentity.ClientID(clientID) + opts := azidentity.ManagedIdentityCredentialOptions{ID: azClientID} + cred, err := azidentity.NewManagedIdentityCredential(&opts) if err != nil { - return errors.Wrap(err, "Failed to create a service principal token") + return errors.Wrap(err, "Failed to create a identity credential") } - // network call to check for token - err = spt.Refresh() + _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) + if err != nil { - return errors.Wrap(err, "Failed to refresh token") + return errors.Wrap(err, "Failed to create a service principal token") } // creds passed authentication return nil @@ -75,36 +99,35 @@ func (c *ClientSecretAuthenticator) Authenticate(creds map[string]string) error if err != nil { return errors.Wrap(err, "Failed to get Client Secret config") } - // create a service principal token - spt, err := credConfig.ServicePrincipalToken() + cred, err := azidentity.NewClientSecretCredential(credConfig.TenantID, credConfig.ClientID, credConfig.ClientSecret, nil) if err != nil { - return errors.Wrap(err, "Failed to create a service principal token") + return errors.Wrap(err, "Failed to create a identity credential") } - // network call to check for token - err = spt.Refresh() + _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) + if err != nil { - return errors.Wrap(err, "Failed to refresh token") + return errors.Wrap(err, "Failed to create a service principal token") } // creds passed authentication return nil } -func getCredConfigForAuth(config map[string]string) (auth.ClientCredentialsConfig, error) { +func getCredConfigForAuth(config map[string]string) (ClientCredentialsConfig, error) { tenantID, ok := config[blockstorage.AzureTenantID] if !ok { - return auth.ClientCredentialsConfig{}, errors.New("Cannot get tenantID from config") + return ClientCredentialsConfig{}, errors.New("Cannot get tenantID from config") } clientID, ok := config[blockstorage.AzureClientID] if !ok { - return auth.ClientCredentialsConfig{}, errors.New("Cannot get clientID from config") + return ClientCredentialsConfig{}, errors.New("Cannot get clientID from config") } clientSecret, ok := config[blockstorage.AzureClientSecret] if !ok { - return auth.ClientCredentialsConfig{}, errors.New("Cannot get clientSecret from config") + return ClientCredentialsConfig{}, errors.New("Cannot get clientSecret from config") } - credConfig := auth.NewClientCredentialsConfig(clientID, clientSecret, tenantID) + credConfig := NewClientCredentialsConfig(clientID, clientSecret, tenantID) return credConfig, nil } diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index c5051b26ee..01a7765685 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -7,16 +7,15 @@ package azure import ( "context" "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" "regexp" "strings" "time" - "github.com/Azure/azure-sdk-for-go/profiles/latest/compute/mgmt/skus" - "github.com/Azure/azure-sdk-for-go/profiles/latest/resources/mgmt/subscriptions" - azcompute "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute" + azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/storage" - azto "github.com/Azure/go-autorest/autorest/to" - uuid "github.com/gofrs/uuid" + "github.com/gofrs/uuid" "github.com/pkg/errors" "github.com/kanisterio/kanister/pkg/blockstorage" @@ -25,7 +24,6 @@ import ( "github.com/kanisterio/kanister/pkg/field" "github.com/kanisterio/kanister/pkg/kube" "github.com/kanisterio/kanister/pkg/log" - "github.com/kanisterio/kanister/pkg/poll" ) var _ blockstorage.Provider = (*AdStorage)(nil) @@ -39,6 +37,8 @@ const ( copyBlobName = "copy-blob-%s.vhd" ) +type LocationZoneMap map[string]struct{} + // AdStorage describes the azure storage client type AdStorage struct { azCli *Client @@ -63,11 +63,11 @@ func (s *AdStorage) VolumeGet(ctx context.Context, id string, zone string) (*blo return nil, errors.Wrapf(err, "Failed to get info for volume with ID %s", id) } - disk, err := s.azCli.DisksClient.Get(ctx, rg, name) + diskResponse, err := s.azCli.DisksClient.Get(ctx, rg, name, nil) if err != nil { return nil, errors.Wrapf(err, "Failed to get volume, volumeID: %s", id) } - return s.VolumeParse(ctx, disk) + return s.VolumeParse(ctx, diskResponse.Disk) } func (s *AdStorage) VolumeCreate(ctx context.Context, volume blockstorage.Volume) (*blockstorage.Volume, error) { @@ -77,43 +77,40 @@ func (s *AdStorage) VolumeCreate(ctx context.Context, volume blockstorage.Volume return nil, errors.Wrap(err, "Failed to create UUID") } diskName := fmt.Sprintf(volumeNameFmt, diskId.String()) - diskProperties := &azcompute.DiskProperties{ - DiskSizeGB: azto.Int32Ptr(int32(blockstorage.SizeInGi(volume.SizeInBytes))), - CreationData: &azcompute.CreationData{ - CreateOption: azcompute.DiskCreateOption(azcompute.DiskCreateOptionTypesEmpty), + + diskProperties := &armcompute.DiskProperties{ + CreationData: &armcompute.CreationData{ + CreateOption: azto.Ptr(armcompute.DiskCreateOptionEmpty), }, + DiskSizeGB: blockstorage.Int32Ptr(int32(blockstorage.SizeInGi(volume.SizeInBytes))), } region, id, err := getLocationInfo(volume.Az) if err != nil { return nil, errors.Wrapf(err, "Could not get region from zone %s", volume.Az) } // TODO(ilya): figure out how to create SKUed disks - createDisk := azcompute.Disk{ - Name: azto.StringPtr(diskName), - Tags: *azto.StringMapPtr(tags), - Location: azto.StringPtr(region), - DiskProperties: diskProperties, + createdDisk := armcompute.Disk{ + Name: blockstorage.StringPtr(diskName), + Tags: *blockstorage.StringMapPtr(tags), + Location: blockstorage.StringPtr(region), + Properties: diskProperties, + SKU: &armcompute.DiskSKU{ + Name: azto.Ptr(armcompute.DiskStorageAccountTypesStandardLRS), + }, } if id != "" { - createDisk.Zones = azto.StringSlicePtr([]string{id}) - } - result, err := s.azCli.DisksClient.CreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createDisk) - if err != nil { - return nil, err + createdDisk.Zones = blockstorage.SliceStringPtr([]string{id}) } - err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client) + + pollerResp, err := s.azCli.DisksClient.BeginCreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createdDisk, nil) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "Could not create volume %s", diskName) } - disk, err := result.Result(*s.azCli.DisksClient) + resp, err := pollerResp.PollUntilDone(ctx, nil) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "Volume create %s polling error", diskName) } - - // Even though the 'CreateOrUpdate' call above returns a 'Disk' model, this is incomplete and - // requires a GET to populate correctly. - // See https://github.com/Azure/azure-sdk-for-go/issues/326 for the explanation why - return s.VolumeGet(ctx, azto.String(disk.ID), volume.Az) + return s.VolumeGet(ctx, blockstorage.String(resp.ID), volume.Az) } func (s *AdStorage) VolumeDelete(ctx context.Context, volume *blockstorage.Volume) error { @@ -121,11 +118,11 @@ func (s *AdStorage) VolumeDelete(ctx context.Context, volume *blockstorage.Volum if err != nil { return errors.Wrapf(err, "Error in deleting Volume with ID %s", volume.ID) } - result, err := s.azCli.DisksClient.Delete(ctx, rg, name) + poller, err := s.azCli.DisksClient.BeginDelete(ctx, rg, name, nil) if err != nil { return errors.Wrapf(err, "Error in deleting Volume with ID %s", volume.ID) } - err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client) + _, err = poller.PollUntilDone(ctx, nil) return errors.Wrapf(err, "Error in deleting Volume with ID %s", volume.ID) } @@ -154,38 +151,27 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. if err != nil { return nil, errors.Wrapf(err, "SnapshotsClient.Copy: Failure in parsing snapshot ID %s", from.ID) } - _, err = s.azCli.SnapshotsClient.Get(ctx, rg, name) + _, err = s.azCli.SnapshotsClient.Get(ctx, rg, name, nil) if err != nil { return nil, errors.Wrapf(err, "SnapshotsClient.Copy: Failed to get snapshot with ID %s", from.ID) } duration := int32(3600) - gad := azcompute.GrantAccessData{ - Access: azcompute.Read, + gad := armcompute.GrantAccessData{ + Access: azto.Ptr(armcompute.AccessLevelRead), DurationInSeconds: &duration, } - snapshotsGrantAccessFuture, err := s.azCli.SnapshotsClient.GrantAccess(ctx, rg, name, gad) + snapshotsGrantAccessPoller, err := s.azCli.SnapshotsClient.BeginGrantAccess(ctx, rg, name, gad, nil) if err != nil { return nil, errors.Wrapf(err, "Failed to grant read access to snapshot: %s", from.ID) } defer s.revokeAccess(ctx, rg, name, from.ID) - - err = poll.Wait(ctx, func(ctx context.Context) (bool, error) { - _, err := snapshotsGrantAccessFuture.Result(*s.azCli.SnapshotsClient) - if err != nil { - if strings.Contains(err.Error(), "asynchronous operation has not completed") { - return false, nil - } - return false, err - } - return true, nil - }) + snapshotGrantRes, err := snapshotsGrantAccessPoller.PollUntilDone(ctx, nil) if err != nil { - return nil, errors.Wrap(err, "SnapshotsClient.Copy failure to grant snapshot access") + return nil, errors.Wrap(err, "SnapshotsClient.Copy failure to grant snapshot access. Snapshot grant access poller failed to pull the result") } - accessURI, err := snapshotsGrantAccessFuture.Result(*s.azCli.SnapshotsClient) if err != nil { return nil, errors.Wrap(err, "SnapshotsClient.Copy failure to grant snapshot access") } @@ -209,7 +195,7 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. Timeout: uint(time), } } - err = blob.Copy(*accessURI.AccessSAS, copyOptions) + err = blob.Copy(*snapshotGrantRes.AccessSAS, copyOptions) if err != nil { return nil, errors.Wrapf(err, "Failed to copy disk to blob") } @@ -228,15 +214,15 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. } tags = blockstorage.SanitizeTags(ktags.GetTags(tags)) - createSnap := azcompute.Snapshot{ - Name: azto.StringPtr(snapName), - Location: azto.StringPtr(to.Region), - Tags: *azto.StringMapPtr(tags), - SnapshotProperties: &azcompute.SnapshotProperties{ - CreationData: &azcompute.CreationData{ - CreateOption: azcompute.Import, - StorageAccountID: azto.StringPtr(storageAccountID), - SourceURI: azto.StringPtr(blobURI), + createSnap := armcompute.Snapshot{ + Name: blockstorage.StringPtr(snapName), + Location: blockstorage.StringPtr(to.Region), + Tags: *blockstorage.StringMapPtr(tags), + Properties: &armcompute.SnapshotProperties{ + CreationData: &armcompute.CreationData{ + CreateOption: azto.Ptr(armcompute.DiskCreateOptionImport), + StorageAccountID: blockstorage.StringPtr(storageAccountID), + SourceURI: blockstorage.StringPtr(blobURI), }, }, } @@ -245,20 +231,15 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. if val, ok := args[blockstorage.AzureMigrateResourceGroup]; ok && val != "" { migrateResourceGroup = val } - result, err := s.azCli.SnapshotsClient.CreateOrUpdate(ctx, migrateResourceGroup, snapName, createSnap) + createSnapshotPoller, err := s.azCli.SnapshotsClient.BeginCreateOrUpdate(ctx, migrateResourceGroup, snapName, createSnap, nil) if err != nil { return nil, errors.Wrapf(err, "Failed to copy snapshot from source snapshot %v", from) } - err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) + createSnapRes, err := createSnapshotPoller.PollUntilDone(ctx, nil) if err != nil { - return nil, errors.Wrapf(err, "Failed to copy snapshot from source snapshot %v", from) + return nil, errors.Wrap(err, "Poller failed to retrieve snapshot") } - rs, err := result.Result(*s.azCli.SnapshotsClient) - if err != nil { - return nil, errors.Wrapf(err, "Error in getting result of Snapshot copy operation, snaphotName %s", snapName) - } - - snap, err := s.SnapshotGet(ctx, azto.String(rs.ID)) + snap, err := s.SnapshotGet(ctx, blockstorage.String(createSnapRes.ID)) if err != nil { return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) } @@ -271,7 +252,15 @@ func isMigrateStorageAccountorKey(migrateStorageAccount, migrateStorageKey strin } func (s *AdStorage) revokeAccess(ctx context.Context, rg, name, ID string) { - _, err := s.azCli.SnapshotsClient.RevokeAccess(ctx, rg, name) + poller, err := s.azCli.SnapshotsClient.BeginRevokeAccess(ctx, rg, name, nil) + if err != nil { + log.Print("Failed to finish the revoke request", field.M{"error": err.Error()}) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + log.Print("failed to pull the result", field.M{"error": err.Error()}) + } + if err != nil { log.Print("Failed to revoke access from snapshot", field.M{"snapshot": ID}) } @@ -295,36 +284,28 @@ func (s *AdStorage) SnapshotCreate(ctx context.Context, volume blockstorage.Volu if err != nil { return nil, errors.Wrapf(err, "Could not get region from zone %s", volume.Az) } - createSnap := azcompute.Snapshot{ - Name: azto.StringPtr(snapName), - Location: azto.StringPtr(region), - Tags: *azto.StringMapPtr(tags), - SnapshotProperties: &azcompute.SnapshotProperties{ - CreationData: &azcompute.CreationData{ - CreateOption: azcompute.Copy, - SourceResourceID: azto.StringPtr(volume.ID), + createSnap := armcompute.Snapshot{ + Name: blockstorage.StringPtr(snapName), + Location: blockstorage.StringPtr(region), + Tags: *blockstorage.StringMapPtr(tags), + Properties: &armcompute.SnapshotProperties{ + CreationData: &armcompute.CreationData{ + CreateOption: azto.Ptr(armcompute.DiskCreateOptionCopy), + SourceResourceID: blockstorage.StringPtr(volume.ID), }, }, } - result, err := s.azCli.SnapshotsClient.CreateOrUpdate(ctx, s.azCli.ResourceGroup, snapName, createSnap) + pollerResp, err := s.azCli.SnapshotsClient.BeginCreateOrUpdate(ctx, s.azCli.ResourceGroup, snapName, createSnap, nil) if err != nil { return nil, errors.Wrapf(err, "Failed to create snapshot for volume %v", volume) } - err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) - if err != nil { - return nil, errors.Wrapf(err, "Failed to create snapshot for volume %v", volume) - } - rs, err := result.Result(*s.azCli.SnapshotsClient) - if err != nil { - return nil, errors.Wrapf(err, "Error in getting result of Snapshot create operation, snaphotName %s", snapName) - } - - snap, err := s.SnapshotGet(ctx, azto.String(rs.ID)) + resp, err := pollerResp.PollUntilDone(ctx, nil) + blockSnapshot := s.snapshotParse(ctx, resp.Snapshot) if err != nil { return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) } - snap.Volume = &volume - return snap, nil + blockSnapshot.Volume = &volume + return blockSnapshot, nil } func (s *AdStorage) SnapshotCreateWaitForCompletion(ctx context.Context, snap *blockstorage.Snapshot) error { @@ -362,12 +343,11 @@ func (s *AdStorage) SnapshotDelete(ctx context.Context, snapshot *blockstorage.S if err != nil { return errors.Wrapf(err, "SnapshotClient.Delete: Failure in parsing snapshot ID %s", snapshot.ID) } - result, err := s.azCli.SnapshotsClient.Delete(ctx, rg, name) + poller, err := s.azCli.SnapshotsClient.BeginDelete(ctx, rg, name, nil) if err != nil { return errors.Wrapf(err, "SnapshotClient.Delete: Failed to delete snapshot with ID %s", snapshot.ID) } - err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) - + _, err = poller.PollUntilDone(ctx, nil) return errors.Wrapf(err, "SnapshotClient.Delete: Error while waiting for snapshot with ID %s to get deleted", snapshot.ID) } @@ -376,78 +356,78 @@ func (s *AdStorage) SnapshotGet(ctx context.Context, id string) (*blockstorage.S if err != nil { return nil, errors.Wrapf(err, "SnapshotsClient.Get: Failure in parsing snapshot ID %s", id) } - snap, err := s.azCli.SnapshotsClient.Get(ctx, rg, name) + snapRes, err := s.azCli.SnapshotsClient.Get(ctx, rg, name, nil) if err != nil { return nil, errors.Wrapf(err, "SnapshotsClient.Get: Failed to get snapshot with ID %s", id) } - return s.snapshotParse(ctx, snap), nil + return s.snapshotParse(ctx, snapRes.Snapshot), nil } func (s *AdStorage) VolumeParse(ctx context.Context, volume interface{}) (*blockstorage.Volume, error) { - vol, ok := volume.(azcompute.Disk) + vol, ok := volume.(armcompute.Disk) if !ok { - return nil, errors.New(fmt.Sprintf("Volume is not of type *azcompute.Disk, volume: %v", volume)) + return nil, errors.New(fmt.Sprintf("Volume is not of type *armcompute.Disk, volume: %v", volume)) } encrypted := false - if vol.DiskProperties.EncryptionSettingsCollection != nil && - vol.DiskProperties.EncryptionSettingsCollection.Enabled != nil { - encrypted = *vol.DiskProperties.EncryptionSettingsCollection.Enabled + if vol.Properties.EncryptionSettingsCollection != nil && + vol.Properties.EncryptionSettingsCollection.Enabled != nil { + encrypted = *vol.Properties.EncryptionSettingsCollection.Enabled } tags := map[string]string{"": ""} if vol.Tags != nil { - tags = azto.StringMap(vol.Tags) + tags = blockstorage.StringMap(vol.Tags) } - az := azto.String(vol.Location) - if z := azto.StringSlice(vol.Zones); len(z) > 0 { - az = az + "-" + z[0] + az := blockstorage.String(vol.Location) + if z := vol.Zones; len(z) > 0 { + az = az + "-" + *(z[0]) } return &blockstorage.Volume{ Type: s.Type(), - ID: azto.String(vol.ID), + ID: blockstorage.String(vol.ID), Encrypted: encrypted, - SizeInBytes: azto.Int64(vol.DiskSizeBytes), + SizeInBytes: blockstorage.Int64(vol.Properties.DiskSizeBytes), Az: az, Tags: blockstorage.MapToKeyValue(tags), - VolumeType: string(vol.Sku.Name), - CreationTime: blockstorage.TimeStamp(vol.DiskProperties.TimeCreated.ToTime()), - Attributes: map[string]string{"Users": azto.String(vol.ManagedBy)}, + VolumeType: string(*vol.SKU.Name), + CreationTime: blockstorage.TimeStamp(*vol.Properties.TimeCreated), + Attributes: map[string]string{"Users": blockstorage.String(vol.ManagedBy)}, }, nil } func (s *AdStorage) SnapshotParse(ctx context.Context, snapshot interface{}) (*blockstorage.Snapshot, error) { - if snap, ok := snapshot.(azcompute.Snapshot); ok { + if snap, ok := snapshot.(armcompute.Snapshot); ok { return s.snapshotParse(ctx, snap), nil } - return nil, errors.New(fmt.Sprintf("Snapshot is not of type *azcompute.Snapshot, snapshot: %v", snapshot)) + return nil, errors.New(fmt.Sprintf("Snapshot is not of type *armcompute.Snapshot, snapshot: %v", snapshot)) } -func (s *AdStorage) snapshotParse(ctx context.Context, snap azcompute.Snapshot) *blockstorage.Snapshot { +func (s *AdStorage) snapshotParse(ctx context.Context, snap armcompute.Snapshot) *blockstorage.Snapshot { vol := &blockstorage.Volume{ Type: s.Type(), - ID: azto.String(snap.SnapshotProperties.CreationData.SourceResourceID), + ID: *snap.Properties.CreationData.SourceResourceID, } - snapCreationTime := *snap.TimeCreated + snapCreationTime := *snap.Properties.TimeCreated encrypted := false - if snap.SnapshotProperties.EncryptionSettingsCollection != nil && - snap.SnapshotProperties.EncryptionSettingsCollection.Enabled != nil { - encrypted = *snap.SnapshotProperties.EncryptionSettingsCollection.Enabled + if snap.Properties.EncryptionSettingsCollection != nil && + snap.Properties.EncryptionSettingsCollection.Enabled != nil { + encrypted = *snap.Properties.EncryptionSettingsCollection.Enabled } tags := map[string]string{} if snap.Tags != nil { - tags = azto.StringMap(snap.Tags) + tags = blockstorage.StringMap(snap.Tags) } return &blockstorage.Snapshot{ Encrypted: encrypted, - ID: azto.String(snap.ID), - Region: azto.String(snap.Location), - SizeInBytes: azto.Int64(snap.SnapshotProperties.DiskSizeBytes), + ID: *snap.ID, + Region: *snap.Location, + SizeInBytes: *snap.Properties.DiskSizeBytes, Tags: blockstorage.MapToKeyValue(tags), Type: s.Type(), Volume: vol, - CreationTime: blockstorage.TimeStamp(snapCreationTime.ToTime()), + CreationTime: blockstorage.TimeStamp(snapCreationTime), } } @@ -455,16 +435,19 @@ func (s *AdStorage) VolumesList(ctx context.Context, tags map[string]string, zon var vols []*blockstorage.Volume // (ilya): It looks like azure doesn't support search by tags // List does listing per Subscription - for diskList, err := s.azCli.DisksClient.ListComplete(ctx); diskList.NotDone(); err = diskList.Next() { + pager := s.azCli.DisksClient.NewListPager(nil) + for pager.More() { + page, err := pager.NextPage(ctx) if err != nil { return nil, errors.Wrap(err, "DisksClient.List in VolumesList") } - disk := diskList.Value() - vol, err := s.VolumeParse(ctx, disk) - if err != nil { - return nil, errors.Wrap(err, "DisksClient.List in VolumesList, failure in parsing Volume") + for _, disk := range page.Value { + vol, err := s.VolumeParse(ctx, disk) + if err != nil { + return nil, errors.Wrap(err, "DisksClient.List in VolumesList, failure in parsing Volume") + } + vols = append(vols, vol) } - vols = append(vols, vol) } return vols, nil } @@ -473,17 +456,20 @@ func (s *AdStorage) SnapshotsList(ctx context.Context, tags map[string]string) ( var snaps []*blockstorage.Snapshot // (ilya): It looks like azure doesn't support search by tags // List does listing per Subscription - for snapList, err := s.azCli.SnapshotsClient.ListComplete(ctx); snapList.NotDone(); err = snapList.Next() { + pager := s.azCli.SnapshotsClient.NewListPager(nil) + for pager.More() { + page, err := pager.NextPage(ctx) if err != nil { return nil, errors.Wrap(err, "SnapshotsClient.List in SnapshotsList") } - snap := snapList.Value() - k10Snap, err := s.SnapshotParse(ctx, snap) - if err != nil { - log.WithError(err).Print("Incorrect Snaphost type", field.M{"SnapshotID": snap.ID}) - continue + for _, snap := range page.Value { + k10Snap, err := s.SnapshotParse(ctx, snap) + if err != nil { + log.WithError(err).Print("Incorrect Snaphost type", field.M{"SnapshotID": snap.ID}) + continue + } + snaps = append(snaps, k10Snap) } - snaps = append(snaps, k10Snap) } snaps = blockstorage.FilterSnapshotsWithTags(snaps, blockstorage.SanitizeTags(tags)) return snaps, nil @@ -509,39 +495,36 @@ func (s *AdStorage) VolumeCreateFromSnapshot(ctx context.Context, snapshot block } diskName := fmt.Sprintf(volumeNameFmt, diskId.String()) tags = blockstorage.SanitizeTags(tags) - createDisk := azcompute.Disk{ - Name: azto.StringPtr(diskName), - Tags: *azto.StringMapPtr(tags), - Location: azto.StringPtr(region), - DiskProperties: &azcompute.DiskProperties{ - CreationData: &azcompute.CreationData{ - CreateOption: azcompute.Copy, - SourceResourceID: azto.StringPtr(snapshot.ID), + createDisk := armcompute.Disk{ + Name: blockstorage.StringPtr(diskName), + Tags: *blockstorage.StringMapPtr(tags), + Location: blockstorage.StringPtr(region), + Properties: &armcompute.DiskProperties{ + CreationData: &armcompute.CreationData{ + CreateOption: azto.Ptr(armcompute.DiskCreateOptionCopy), + SourceResourceID: blockstorage.StringPtr(snapshot.ID), }, }, } if id != "" { - createDisk.Zones = azto.StringSlicePtr([]string{id}) + createDisk.Zones = blockstorage.SliceStringPtr([]string{id}) } - for _, saType := range azcompute.PossibleDiskStorageAccountTypesValues() { + for _, saType := range armcompute.PossibleDiskStorageAccountTypesValues() { if string(saType) == snapshot.Volume.VolumeType { - createDisk.Sku = &azcompute.DiskSku{ - Name: saType, + createDisk.SKU = &armcompute.DiskSKU{ + Name: azto.Ptr(saType), } } } - result, err := s.azCli.DisksClient.CreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createDisk) + poller, err := s.azCli.DisksClient.BeginCreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createDisk, nil) if err != nil { return nil, errors.Wrapf(err, "DiskCLient.CreateOrUpdate in VolumeCreateFromSnapshot, diskName: %s, snapshotID: %s", diskName, snapshot.ID) } - if err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client); err != nil { - return nil, errors.Wrapf(err, "DiskCLient.CreateOrUpdate in VolumeCreateFromSnapshot, diskName: %s, snapshotID: %s", diskName, snapshot.ID) - } - disk, err := result.Result(*s.azCli.DisksClient) + resp, err := poller.PollUntilDone(ctx, nil) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "DiskCLient.CreateOrUpdate in VolumeCreateFromSnapshot, diskName: %s, snapshotID: %s", diskName, snapshot.ID) } - return s.VolumeGet(ctx, azto.String(disk.ID), snapshot.Volume.Az) + return s.VolumeGet(ctx, blockstorage.String(resp.ID), snapshot.Volume.Az) } func (s *AdStorage) getRegionAndZoneID(ctx context.Context, sourceRegion, volAz string) (string, string, error) { @@ -594,19 +577,19 @@ func (s *AdStorage) SetTags(ctx context.Context, resource interface{}, tags map[ if err != nil { return err } - snap, err := s.azCli.SnapshotsClient.Get(ctx, rg, name) + snap, err := s.azCli.SnapshotsClient.Get(ctx, rg, name, nil) if err != nil { return errors.Wrapf(err, "SnapshotsClient.Get in SetTags, snapshotID: %s", res.ID) } - tags = ktags.AddMissingTags(azto.StringMap(snap.Tags), ktags.GetTags(tags)) - snapProperties := azcompute.SnapshotUpdate{ - Tags: *azto.StringMapPtr(blockstorage.SanitizeTags(tags)), + tags = ktags.AddMissingTags(blockstorage.StringMap(snap.Tags), ktags.GetTags(tags)) + snapProperties := armcompute.SnapshotUpdate{ + Tags: *blockstorage.StringMapPtr(blockstorage.SanitizeTags(tags)), } - result, err := s.azCli.SnapshotsClient.Update(ctx, rg, name, snapProperties) + poller, err := s.azCli.SnapshotsClient.BeginUpdate(ctx, rg, name, snapProperties, nil) if err != nil { return errors.Wrapf(err, "SnapshotsClient.Update in SetTags, snapshotID: %s", name) } - err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) + _, err = poller.PollUntilDone(ctx, nil) return errors.Wrapf(err, "SnapshotsClient.Update in SetTags, snapshotID: %s", name) } case *blockstorage.Volume: @@ -615,20 +598,20 @@ func (s *AdStorage) SetTags(ctx context.Context, resource interface{}, tags map[ if err != nil { return err } - vol, err := s.azCli.DisksClient.Get(ctx, rg, volID) + vol, err := s.azCli.DisksClient.Get(ctx, rg, volID, nil) if err != nil { return errors.Wrapf(err, "DiskClient.Get in SetTags, volumeID: %s", volID) } - tags = ktags.AddMissingTags(azto.StringMap(vol.Tags), ktags.GetTags(tags)) + tags = ktags.AddMissingTags(blockstorage.StringMap(vol.Tags), ktags.GetTags(tags)) - diskProperties := azcompute.DiskUpdate{ - Tags: *azto.StringMapPtr(blockstorage.SanitizeTags(tags)), + diskProperties := armcompute.DiskUpdate{ + Tags: *blockstorage.StringMapPtr(blockstorage.SanitizeTags(tags)), } - result, err := s.azCli.DisksClient.Update(ctx, rg, volID, diskProperties) + poller, err := s.azCli.DisksClient.BeginUpdate(ctx, rg, volID, diskProperties, nil) if err != nil { return errors.Wrapf(err, "DiskClient.Update in SetTags, volumeID: %s", volID) } - err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client) + _, err = poller.PollUntilDone(ctx, nil) return errors.Wrapf(err, "DiskClient.Update in SetTags, volumeID: %s", volID) } default: @@ -678,39 +661,34 @@ func (s *AdStorage) SnapshotRestoreTargets(ctx context.Context, snapshot *blocks // dynamicRegionMapAzure derives a mapping from Regions to zones for Azure. Depends on subscriptionID func (s *AdStorage) dynamicRegionMapAzure(ctx context.Context) (map[string][]string, error) { - subscriptionsCLient := subscriptions.NewClientWithBaseURI(s.azCli.BaseURI) - subscriptionsCLient.Authorizer = s.azCli.Authorizer - llResp, err := subscriptionsCLient.ListLocations(ctx, s.azCli.SubscriptionID, nil) - if err != nil { - return nil, err - } - regionMap := make(map[string]map[string]struct{}) - for _, location := range *llResp.Value { - regionMap[*location.Name] = make(map[string]struct{}) - } + subscriptionsClient := s.azCli.SubscriptionsClient + regionMap := make(map[string]LocationZoneMap) - skuClient := skus.NewResourceSkusClientWithBaseURI(s.azCli.BaseURI, s.azCli.SubscriptionID) - skuClient.Authorizer = s.azCli.Authorizer - skuResults, err := skuClient.ListComplete(ctx) - if err != nil { - return nil, err - } - for skuResults.Value().Name != nil { - if skuResults.Value().ResourceType != nil && *skuResults.Value().ResourceType == "disks" { - for _, location := range *skuResults.Value().LocationInfo { - if val, ok := regionMap[*location.Location]; ok { - for _, zone := range *location.Zones { - val[zone] = struct{}{} - } - regionMap[*location.Location] = val - } - } + locationsPager := subscriptionsClient.NewListLocationsPager(s.azCli.SubscriptionID, &armsubscriptions.ClientListLocationsOptions{IncludeExtendedLocations: nil}) + for locationsPager.More() { + page, err := locationsPager.NextPage(ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to advance page") } - if err = skuResults.NextWithContext(ctx); err != nil { - return nil, err + for _, location := range page.Value { + regionMap[*location.Name] = make(LocationZoneMap) } } + skusClient := s.azCli.SKUsClient + skusPager := skusClient.NewListPager(&armcompute.ResourceSKUsClientListOptions{Filter: nil, + IncludeExtendedLocations: nil}) + for skusPager.More() { + skuResults, err := skusPager.NextPage(ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to advance page") + } + for _, skuResult := range skuResults.Value { + if skuResult.Name != nil && skuResult.ResourceType != nil && *skuResult.ResourceType == "disks" { + s.mapLocationToZone(skuResult, ®ionMap) + } + } + } // convert to map of []string regionMapResult := make(map[string][]string) for region, zoneSet := range regionMap { @@ -722,3 +700,15 @@ func (s *AdStorage) dynamicRegionMapAzure(ctx context.Context) (map[string][]str } return regionMapResult, nil } + +func (s *AdStorage) mapLocationToZone(skuResult *armcompute.ResourceSKU, regionMap *map[string]LocationZoneMap) { + var rm = *regionMap + for _, locationInfo := range skuResult.LocationInfo { + if val, ok := rm[*locationInfo.Location]; ok { + for _, zone := range locationInfo.Zones { + val[*zone] = struct{}{} + } + rm[*locationInfo.Location] = val + } + } +} diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 86589b8af6..0e2fe0cd4b 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -20,11 +20,10 @@ package azure import ( "context" - - "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute" - "github.com/Azure/go-autorest/autorest" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/kanisterio/kanister/pkg/log" "github.com/pkg/errors" @@ -32,15 +31,26 @@ import ( // Client is a wrapper for Client client type Client struct { - SubscriptionID string - ResourceGroup string - BaseURI string - Authorizer *autorest.BearerAuthorizer - DisksClient *compute.DisksClient - SnapshotsClient *compute.SnapshotsClient + Cred *azidentity.DefaultAzureCredential + SubscriptionID string + ResourceGroup string + BaseURI string + //https://github.com/Azure-Samples/azure-sdk-for-go-samples/blob/main/sdk/resourcemanager/compute/disk/main.go + //https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/arm/compute#DisksClient + DisksClient *armcompute.DisksClient + //https://github.com/Azure-Samples/azure-sdk-for-go-samples/blob/main/sdk/resourcemanager/compute/snapshot/main.go + //https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/arm/compute#SnapshotsClient + SnapshotsClient *armcompute.SnapshotsClient + SKUsClient *armcompute.ResourceSKUsClient + SubscriptionsClient *armsubscriptions.Client } // NewClient returns a Client struct +var ( + computeClientFactory *armcompute.ClientFactory + subscriptionsClientFactory *armsubscriptions.ClientFactory +) + func NewClient(ctx context.Context, config map[string]string) (*Client, error) { var resourceGroup string var subscriptionID string @@ -64,87 +74,70 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { return nil, errors.Wrap(err, "Cannot get subscriptionID from instance metadata") } } + /* + if id, ok := config[blockstorage.AzureCloudEnvironmentID]; !ok || id == "" { + config[blockstorage.AzureCloudEnvironmentID] = azure.PublicCloud.Name + } + */ + /* + env, err := azure.EnvironmentFromName(config[blockstorage.AzureCloudEnvironmentID]) + if err != nil { + return nil, errors.Wrap(err, "Failed to fetch the cloud environment.") + } - if id, ok := config[blockstorage.AzureCloudEnvironmentID]; !ok || id == "" { - config[blockstorage.AzureCloudEnvironmentID] = azure.PublicCloud.Name - } + authorizer, err := getAuthorizer(env, config) + if err != nil { + return nil, err + } - env, err := azure.EnvironmentFromName(config[blockstorage.AzureCloudEnvironmentID]) + _, ok = config[blockstorage.AzureResurceMgrEndpoint] + if !ok { + config[blockstorage.AzureResurceMgrEndpoint] = env.ResourceManagerEndpoint + } + */ + cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { - return nil, errors.Wrap(err, "Failed to fetch the cloud environment.") + return nil, err } - - authorizer, err := getAuthorizer(env, config) + computeClientFactory, err = armcompute.NewClientFactory(subscriptionID, cred, nil) if err != nil { return nil, err } - _, ok = config[blockstorage.AzureResurceMgrEndpoint] - if !ok { - config[blockstorage.AzureResurceMgrEndpoint] = env.ResourceManagerEndpoint - } - - disksClient := compute.NewDisksClientWithBaseURI(config[blockstorage.AzureResurceMgrEndpoint], subscriptionID) - disksClient.Authorizer = authorizer - - snapshotsClient := compute.NewSnapshotsClientWithBaseURI(config[blockstorage.AzureResurceMgrEndpoint], subscriptionID) - snapshotsClient.Authorizer = authorizer - - return &Client{ - BaseURI: config[blockstorage.AzureResurceMgrEndpoint], - SubscriptionID: subscriptionID, - Authorizer: authorizer, - DisksClient: &disksClient, - SnapshotsClient: &snapshotsClient, - ResourceGroup: resourceGroup, - }, nil -} - -//nolint:unparam -func getAuthorizer(env azure.Environment, config map[string]string) (*autorest.BearerAuthorizer, error) { - if isClientCredsAvailable(config) { - return getClientCredsAuthorizer(env, config) - } else if isMSICredsAvailable(config) { - return getMSIsAuthorizer(config) - } - return nil, errors.New("Missing credentials, or credential type not supported") -} + subscriptionsClientFactory, err = armsubscriptions.NewClientFactory(cred, nil) -func getClientCredsAuthorizer(env azure.Environment, config map[string]string) (*autorest.BearerAuthorizer, error) { - credConfig, err := getCredConfig(env, config) if err != nil { - return nil, errors.Wrap(err, "Failed to get Azure Client Credentials Config") - } - a, err := credConfig.Authorizer() - if err != nil { - return nil, errors.Wrap(err, "Failed to get Azure Client Credentials authorizer") - } - ba, ok := a.(*autorest.BearerAuthorizer) - if !ok { - return nil, errors.New("Failed to get Azure authorizer") + return nil, err } - return ba, nil -} -func getMSIsAuthorizer(config map[string]string) (*autorest.BearerAuthorizer, error) { - msiConfig := auth.NewMSIConfig() - msiConfig.ClientID = config[blockstorage.AzureClientID] - a, err := msiConfig.Authorizer() + disksClient := computeClientFactory.NewDisksClient() + snapshotsClient := computeClientFactory.NewSnapshotsClient() + skusClient := computeClientFactory.NewResourceSKUsClient() + subscriptionsClient := subscriptionsClientFactory.NewClient() + if err != nil { - return nil, errors.Wrap(err, "Failed to get Azure MSI authorizer") - } - ba, ok := a.(*autorest.BearerAuthorizer) - if !ok { - return nil, errors.New("Failed to get Azure authorizer") + return nil, err } - return ba, nil + + return &Client{ + Cred: cred, + BaseURI: config[blockstorage.AzureResurceMgrEndpoint], + SubscriptionID: subscriptionID, + DisksClient: disksClient, + SnapshotsClient: snapshotsClient, + SKUsClient: skusClient, + SubscriptionsClient: subscriptionsClient, + ResourceGroup: resourceGroup, + }, nil } -func getCredConfig(env azure.Environment, config map[string]string) (auth.ClientCredentialsConfig, error) { +func getCredConfig(env azure.Environment, config map[string]string) (ClientCredentialsConfig, error) { credConfig, err := getCredConfigForAuth(config) if err != nil { - return auth.ClientCredentialsConfig{}, err + return ClientCredentialsConfig{}, err } + + //Todo: Find alternatives to azure.Environment var ok bool if credConfig.AADEndpoint, ok = config[blockstorage.AzureActiveDirEndpoint]; !ok || credConfig.AADEndpoint == "" { credConfig.AADEndpoint = env.ActiveDirectoryEndpoint diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index a49c1be597..e486ff73f8 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -17,14 +17,13 @@ package azure import ( "context" "fmt" - "strings" - "testing" - "github.com/Azure/go-autorest/autorest/azure" "github.com/Azure/go-autorest/autorest/azure/auth" "github.com/kanisterio/kanister/pkg/blockstorage" envconfig "github.com/kanisterio/kanister/pkg/config" . "gopkg.in/check.v1" + "strings" + "testing" ) // Hook up gocheck into the "go test" runner. @@ -50,10 +49,11 @@ func (s *ClientSuite) TestClient(c *C) { c.Assert(err, IsNil) c.Assert(azCli.SubscriptionID, NotNil) - c.Assert(azCli.Authorizer, NotNil) c.Assert(azCli.DisksClient, NotNil) c.Assert(azCli.SnapshotsClient, NotNil) - _, err = azCli.DisksClient.List(context.Background()) + c.Assert(azCli.DisksClient.NewListPager(nil), NotNil) + c.Assert(azCli.SKUsClient, NotNil) + c.Assert(azCli.SubscriptionsClient, NotNil) c.Assert(err, IsNil) } diff --git a/pkg/blockstorage/helpers.go b/pkg/blockstorage/helpers.go index 20ea680d19..da1ea4d96d 100644 --- a/pkg/blockstorage/helpers.go +++ b/pkg/blockstorage/helpers.go @@ -16,6 +16,7 @@ package blockstorage import ( "bytes" + azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" ktags "github.com/kanisterio/kanister/pkg/blockstorage/tags" ) @@ -105,3 +106,143 @@ func FilterSnapshotsWithTags(snapshots []*Snapshot, tags map[string]string) []*S } return result } + +// utility functions equivalent to old functions from package `go-autorest/autorest/to` + +// StringMapPtr returns a pointer to a map of string pointers built from the passed map of strings. +func StringMapPtr(ms map[string]string) *map[string]*string { + msp := make(map[string]*string, len(ms)) + for k, s := range ms { + msp[k] = azto.Ptr(s) + } + return &msp +} + +// StringMap returns a map of strings built from the map of string pointers. The empty string is +// used for nil pointers. +func StringMap(msp map[string]*string) map[string]string { + ms := make(map[string]string, len(msp)) + for k, sp := range msp { + if sp != nil { + ms[k] = *sp + } else { + ms[k] = "" + } + } + return ms +} + +// StringSlice returns a string slice value for the passed string slice pointer. It returns a nil +// slice if the pointer is nil. +func StringSlice(s *[]string) []string { + if s != nil { + return *s + } + return nil +} + +// StringSlicePtr returns a pointer to the passed string slice. +func StringSlicePtr(s []string) *[]string { + return azto.Ptr(s) +} + +// SliceStringPtr returns a slice of string pointers from the passed string slice. +func SliceStringPtr(s []string) []*string { + ms := make([]*string, len(s)) + for k, sp := range s { + ms[k] = azto.Ptr(sp) + } + return ms +} + +// Bool returns a bool value for the passed bool pointer. It returns false if the pointer is nil. +func Bool(b *bool) bool { + if b != nil { + return *b + } + return false +} + +// BoolPtr returns a pointer to the passed bool. +func BoolPtr(b bool) *bool { + return &b +} + +// Int returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int(i *int) int { + if i != nil { + return *i + } + return 0 +} + +// IntPtr returns a pointer to the passed int. +func IntPtr(i int) *int { + return &i +} + +// Int32 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int32(i *int32) int32 { + if i != nil { + return *i + } + return 0 +} + +// Int32Ptr returns a pointer to the passed int32. +func Int32Ptr(i int32) *int32 { + return &i +} + +// Int64 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. +func Int64(i *int64) int64 { + if i != nil { + return *i + } + return 0 +} + +// Int64Ptr returns a pointer to the passed int64. +func Int64Ptr(i int64) *int64 { + return &i +} + +// Float32 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +func Float32(i *float32) float32 { + if i != nil { + return *i + } + return 0.0 +} + +// Float32Ptr returns a pointer to the passed float32. +func Float32Ptr(i float32) *float32 { + return &i +} + +// Float64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +func Float64(i *float64) float64 { + if i != nil { + return *i + } + return 0.0 +} + +// Float64Ptr returns a pointer to the passed float64. +func Float64Ptr(i float64) *float64 { + return &i +} + +// String returns a string value for the passed string pointer. It returns the empty string if the +// pointer is nil. +func String(s *string) string { + if s != nil { + return *s + } + return "" +} + +// StringPtr returns a pointer to the passed string. +func StringPtr(s string) *string { + return &s +} From eaeb58728f72161fa1daa5ccf2adbc9ca6350979 Mon Sep 17 00:00:00 2001 From: mabhi Date: Tue, 3 Oct 2023 11:55:32 +0530 Subject: [PATCH 02/18] Updated test cases Signed-off-by: mabhi --- go.mod | 8 +----- go.sum | 18 ++---------- pkg/blockstorage/azure/client.go | 8 +++--- pkg/blockstorage/azure/client_test.go | 40 +++++++++++++++------------ 4 files changed, 31 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index 4c1b3dfaef..1d649dc218 100644 --- a/go.mod +++ b/go.mod @@ -17,8 +17,6 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0 - github.com/Azure/go-autorest/autorest v0.11.29 - github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 github.com/Masterminds/semver v1.5.0 github.com/Masterminds/sprig v2.22.0+incompatible github.com/aws/aws-sdk-go v1.47.11 @@ -78,9 +76,6 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 // indirect; indirect; github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect - github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 // indirect @@ -96,7 +91,6 @@ require ( github.com/chmduquesne/rollinghash v4.0.0+incompatible // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dimchansky/utfbom v1.1.1 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect @@ -154,7 +148,6 @@ require ( github.com/minio/minio-go/v7 v7.0.63 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/moby/spdystream v0.2.0 // indirect @@ -167,6 +160,7 @@ require ( github.com/oklog/ulid v1.3.1 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/profile v1.7.0 // indirect github.com/pkg/sftp v1.13.6 // indirect github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 // indirect diff --git a/go.sum b/go.sum index 280944491e..1c4eeef3e6 100644 --- a/go.sum +++ b/go.sum @@ -53,19 +53,12 @@ github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= -github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= -github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= +github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= +github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/adal v0.9.18 h1:kLnPsRjzZZUF3K5REu/Kc+qMQrvuza2bwSnNdhmzLfQ= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= -github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= -github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 h1:0W/yGmFdTIT77fvdlGZ0LMISoLHFJ7Tx4U0yeB+uFs4= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= @@ -147,8 +140,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= @@ -425,8 +416,6 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -533,7 +522,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/studio-b12/gowebdav v0.9.0 h1:1j1sc9gQnNxbXXM4M/CebPOX4aXYtr7MojAVcN4dHjU= diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 0e2fe0cd4b..1b34cdc65f 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -20,10 +20,10 @@ package azure import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" - "github.com/Azure/go-autorest/autorest/azure" "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/kanisterio/kanister/pkg/log" "github.com/pkg/errors" @@ -131,7 +131,7 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { }, nil } -func getCredConfig(env azure.Environment, config map[string]string) (ClientCredentialsConfig, error) { +func getCredConfig(conf cloud.Configuration, config map[string]string) (ClientCredentialsConfig, error) { credConfig, err := getCredConfigForAuth(config) if err != nil { return ClientCredentialsConfig{}, err @@ -140,12 +140,12 @@ func getCredConfig(env azure.Environment, config map[string]string) (ClientCrede //Todo: Find alternatives to azure.Environment var ok bool if credConfig.AADEndpoint, ok = config[blockstorage.AzureActiveDirEndpoint]; !ok || credConfig.AADEndpoint == "" { - credConfig.AADEndpoint = env.ActiveDirectoryEndpoint + credConfig.AADEndpoint = conf.ActiveDirectoryAuthorityHost config[blockstorage.AzureActiveDirEndpoint] = credConfig.AADEndpoint } if credConfig.Resource, ok = config[blockstorage.AzureActiveDirResourceID]; !ok || credConfig.Resource == "" { - credConfig.Resource = env.ResourceManagerEndpoint + credConfig.Resource = conf.Services[cloud.ResourceManager].Endpoint config[blockstorage.AzureActiveDirResourceID] = credConfig.Resource } diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index e486ff73f8..2cfc2da4d9 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -17,8 +17,7 @@ package azure import ( "context" "fmt" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/azure/auth" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/kanisterio/kanister/pkg/blockstorage" envconfig "github.com/kanisterio/kanister/pkg/config" . "gopkg.in/check.v1" @@ -87,13 +86,15 @@ func (s ClientSuite) TestGetRegions(c *C) { func (s *ClientSuite) TestGetCredConfig(c *C) { for _, tc := range []struct { - env azure.Environment + name string + env cloud.Configuration config map[string]string errChecker Checker - expCCC auth.ClientCredentialsConfig + expCCC ClientCredentialsConfig }{ { - env: azure.PublicCloud, + name: "TC1", + env: cloud.AzurePublic, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -101,7 +102,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { blockstorage.AzureActiveDirEndpoint: "aade", blockstorage.AzureActiveDirResourceID: "aadrid", }, - expCCC: auth.ClientCredentialsConfig{ + expCCC: ClientCredentialsConfig{ ClientID: "acid", ClientSecret: "acs", TenantID: "atid", @@ -111,23 +112,25 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: IsNil, }, { - env: azure.PublicCloud, + name: "TC2", + env: cloud.AzurePublic, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", blockstorage.AzureClientSecret: "acs", }, - expCCC: auth.ClientCredentialsConfig{ + expCCC: ClientCredentialsConfig{ ClientID: "acid", ClientSecret: "acs", TenantID: "atid", - Resource: azure.PublicCloud.ResourceManagerEndpoint, - AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, + Resource: cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint, + AADEndpoint: cloud.AzurePublic.ActiveDirectoryAuthorityHost, }, errChecker: IsNil, }, { - env: azure.USGovernmentCloud, + name: "TC3", + env: cloud.AzureGovernment, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -135,17 +138,18 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { blockstorage.AzureActiveDirEndpoint: "", blockstorage.AzureActiveDirResourceID: "", }, - expCCC: auth.ClientCredentialsConfig{ + expCCC: ClientCredentialsConfig{ ClientID: "acid", ClientSecret: "acs", TenantID: "atid", - Resource: azure.USGovernmentCloud.ResourceManagerEndpoint, - AADEndpoint: azure.USGovernmentCloud.ActiveDirectoryEndpoint, + Resource: cloud.AzureGovernment.Services[cloud.ResourceManager].Endpoint, + AADEndpoint: cloud.AzureGovernment.ActiveDirectoryAuthorityHost, }, errChecker: IsNil, }, { - env: azure.USGovernmentCloud, + name: "TC4", + env: cloud.AzureGovernment, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -153,14 +157,16 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: NotNil, }, { - env: azure.USGovernmentCloud, + name: "TC5", + env: cloud.AzureGovernment, config: map[string]string{ blockstorage.AzureTenantID: "atid", }, errChecker: NotNil, }, { - env: azure.USGovernmentCloud, + name: "TC6", + env: cloud.AzureGovernment, config: map[string]string{}, errChecker: NotNil, }, From ebc0818cc1a2c35cca40c10e83cde249bfdc3dc4 Mon Sep 17 00:00:00 2001 From: mabhi Date: Thu, 5 Oct 2023 12:03:03 +0530 Subject: [PATCH 03/18] Added environment struct for azure soverign cloud Signed-off-by: mabhi --- pkg/blockstorage/azure/client.go | 6 +- pkg/blockstorage/azure/client_test.go | 14 ++-- pkg/blockstorage/azure/environments.go | 84 +++++++++++++++++++++++ pkg/kopia/command/storage/secret_utils.go | 5 +- 4 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 pkg/blockstorage/azure/environments.go diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 1b34cdc65f..921f103222 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -131,7 +131,7 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { }, nil } -func getCredConfig(conf cloud.Configuration, config map[string]string) (ClientCredentialsConfig, error) { +func getCredConfig(env Environment, config map[string]string) (ClientCredentialsConfig, error) { credConfig, err := getCredConfigForAuth(config) if err != nil { return ClientCredentialsConfig{}, err @@ -140,12 +140,12 @@ func getCredConfig(conf cloud.Configuration, config map[string]string) (ClientCr //Todo: Find alternatives to azure.Environment var ok bool if credConfig.AADEndpoint, ok = config[blockstorage.AzureActiveDirEndpoint]; !ok || credConfig.AADEndpoint == "" { - credConfig.AADEndpoint = conf.ActiveDirectoryAuthorityHost + credConfig.AADEndpoint = env.Configuration.ActiveDirectoryAuthorityHost config[blockstorage.AzureActiveDirEndpoint] = credConfig.AADEndpoint } if credConfig.Resource, ok = config[blockstorage.AzureActiveDirResourceID]; !ok || credConfig.Resource == "" { - credConfig.Resource = conf.Services[cloud.ResourceManager].Endpoint + credConfig.Resource = env.Configuration.Services[cloud.ResourceManager].Endpoint config[blockstorage.AzureActiveDirResourceID] = credConfig.Resource } diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index 2cfc2da4d9..33ecdaf1d9 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -87,14 +87,14 @@ func (s ClientSuite) TestGetRegions(c *C) { func (s *ClientSuite) TestGetCredConfig(c *C) { for _, tc := range []struct { name string - env cloud.Configuration + env Environment config map[string]string errChecker Checker expCCC ClientCredentialsConfig }{ { name: "TC1", - env: cloud.AzurePublic, + env: PublicCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -113,7 +113,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { }, { name: "TC2", - env: cloud.AzurePublic, + env: PublicCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -130,7 +130,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { }, { name: "TC3", - env: cloud.AzureGovernment, + env: USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -149,7 +149,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { }, { name: "TC4", - env: cloud.AzureGovernment, + env: USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -158,7 +158,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { }, { name: "TC5", - env: cloud.AzureGovernment, + env: USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", }, @@ -166,7 +166,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { }, { name: "TC6", - env: cloud.AzureGovernment, + env: USGovernmentCloud, config: map[string]string{}, errChecker: NotNil, }, diff --git a/pkg/blockstorage/azure/environments.go b/pkg/blockstorage/azure/environments.go new file mode 100644 index 0000000000..36aeaf1add --- /dev/null +++ b/pkg/blockstorage/azure/environments.go @@ -0,0 +1,84 @@ +package azure + +import ( + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + "strings" +) + +const ( + // NotAvailable is used for endpoints and resource IDs that are not available for a given cloud. + NotAvailable = "N/A" +) + +var environments = map[string]Environment{ + "AZURECHINACLOUD": ChinaCloud, + "AZUREGERMANCLOUD": GermanCloud, + "AZURECLOUD": PublicCloud, + "AZUREPUBLICCLOUD": PublicCloud, + "AZUREUSGOVERNMENT": USGovernmentCloud, + "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, +} + +// Environment represents a set of endpoints for each of Azure's Clouds. +type Environment struct { + Name string `json:"name"` + ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` + ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` + StorageEndpointSuffix string `json:"storageEndpointSuffix"` + Configuration cloud.Configuration +} + +var ( + // PublicCloud is the default public Azure cloud environment + //Ref: https://github.com/Azure/azure-sdk-for-go/blob/sdk/storage/azblob/v0.4.0/eng/common/TestResources/clouds/AzureCloud.json + PublicCloud = Environment{ + Name: "AzurePublicCloud", + ResourceManagerEndpoint: "https://management.azure.com/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", + StorageEndpointSuffix: "core.windows.net", + Configuration: cloud.AzurePublic, + } + + // USGovernmentCloud is the cloud environment for the US Government + //Ref: https://github.com/Azure/azure-sdk-for-go/blob/sdk/storage/azblob/v0.4.0/eng/common/TestResources/clouds/AzureUSGovernment.json + USGovernmentCloud = Environment{ + Name: "AzureUSGovernmentCloud", + ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", + ActiveDirectoryEndpoint: "https://login.microsoftonline.us/", + StorageEndpointSuffix: "core.usgovcloudapi.net", + Configuration: cloud.AzureGovernment, + } + + // ChinaCloud is the cloud environment operated in China + //Ref: https://github.com/Azure/azure-sdk-for-go/blob/sdk/storage/azblob/v0.4.0/eng/common/TestResources/clouds/AzureChinaCloud.json + ChinaCloud = Environment{ + Name: "AzureChinaCloud", + ResourceManagerEndpoint: "https://management.chinacloudapi.cn/", + ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/", + StorageEndpointSuffix: "core.chinacloudapi.cn", + Configuration: cloud.AzureChina, + } + + // GermanCloud is the cloud environment operated in Germany has been deprecated + // Ref: https://learn.microsoft.com/en-us/previous-versions/azure/germany/germany-welcome + GermanCloud = Environment{ + Name: "AzureGermanCloud", + ResourceManagerEndpoint: NotAvailable, + ActiveDirectoryEndpoint: NotAvailable, + StorageEndpointSuffix: NotAvailable, + Configuration: cloud.Configuration{}, + } +) + +// EnvironmentFromName returns an Environment based on the common name specified. +func EnvironmentFromName(name string) (Environment, error) { + + name = strings.ToUpper(name) + env, ok := environments[name] + if !ok { + return env, fmt.Errorf("environment/azure: There is no cloud environment matching the name %q", name) + } + + return env, nil +} diff --git a/pkg/kopia/command/storage/secret_utils.go b/pkg/kopia/command/storage/secret_utils.go index 1935f7354b..71fa20183c 100644 --- a/pkg/kopia/command/storage/secret_utils.go +++ b/pkg/kopia/command/storage/secret_utils.go @@ -16,11 +16,10 @@ package storage import ( "context" - "time" - - "github.com/Azure/go-autorest/autorest/azure" + "github.com/kanisterio/kanister/pkg/blockstorage/azure" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" + "time" "github.com/kanisterio/kanister/pkg/apis/cr/v1alpha1" "github.com/kanisterio/kanister/pkg/aws" From cedfb077b48e77e856545776bead4609cb9754ad Mon Sep 17 00:00:00 2001 From: mabhi Date: Thu, 5 Oct 2023 12:15:15 +0530 Subject: [PATCH 04/18] Removed unused code comments Signed-off-by: mabhi --- go.mod | 1 + pkg/blockstorage/azure/client.go | 20 -------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 1d649dc218..81f9bc498a 100644 --- a/go.mod +++ b/go.mod @@ -229,4 +229,5 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect + github.com/Azure/go-autorest/autorest v0.11.27 // indirect ) diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 921f103222..50880b53f8 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -74,27 +74,7 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { return nil, errors.Wrap(err, "Cannot get subscriptionID from instance metadata") } } - /* - if id, ok := config[blockstorage.AzureCloudEnvironmentID]; !ok || id == "" { - config[blockstorage.AzureCloudEnvironmentID] = azure.PublicCloud.Name - } - */ - /* - env, err := azure.EnvironmentFromName(config[blockstorage.AzureCloudEnvironmentID]) - if err != nil { - return nil, errors.Wrap(err, "Failed to fetch the cloud environment.") - } - authorizer, err := getAuthorizer(env, config) - if err != nil { - return nil, err - } - - _, ok = config[blockstorage.AzureResurceMgrEndpoint] - if !ok { - config[blockstorage.AzureResurceMgrEndpoint] = env.ResourceManagerEndpoint - } - */ cred, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { return nil, err From a7bbd4344e06276aba2494c4eadd3d38e3bcf798 Mon Sep 17 00:00:00 2001 From: mabhi Date: Thu, 5 Oct 2023 16:45:45 +0530 Subject: [PATCH 05/18] Lint error fix Signed-off-by: mabhi --- go.mod | 9 ++++++++- pkg/blockstorage/azure/environments.go | 1 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 81f9bc498a..7dedc29b7a 100644 --- a/go.mod +++ b/go.mod @@ -79,6 +79,8 @@ require ( github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect + github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/alecthomas/kingpin/v2 v2.3.2 // indirect @@ -213,7 +215,6 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - ) require ( @@ -230,4 +231,10 @@ require ( go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect github.com/Azure/go-autorest/autorest v0.11.27 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.27 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect ) diff --git a/pkg/blockstorage/azure/environments.go b/pkg/blockstorage/azure/environments.go index 36aeaf1add..5fdc460a14 100644 --- a/pkg/blockstorage/azure/environments.go +++ b/pkg/blockstorage/azure/environments.go @@ -73,7 +73,6 @@ var ( // EnvironmentFromName returns an Environment based on the common name specified. func EnvironmentFromName(name string) (Environment, error) { - name = strings.ToUpper(name) env, ok := environments[name] if !ok { From 15cc66d8b52b11f56e7170b75487ff367997c6e6 Mon Sep 17 00:00:00 2001 From: mabhi Date: Fri, 13 Oct 2023 23:25:09 +0530 Subject: [PATCH 06/18] Refactor the azure credential, make it explicit Signed-off-by: mabhi --- pkg/blockstorage/azure/auth.go | 74 ++++++++++++++++++++++----- pkg/blockstorage/azure/auth_test.go | 8 +-- pkg/blockstorage/azure/client.go | 25 ++++----- pkg/blockstorage/azure/client_test.go | 2 +- 4 files changed, 79 insertions(+), 30 deletions(-) diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index a1e0cf8138..e10509fd2a 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -2,7 +2,7 @@ package azure import ( "context" - _ "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" @@ -16,16 +16,23 @@ const ActiveDirectory = "activeDirectory" // to be available with azidentity: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#readme-credential-types // determine if the combination of creds are client secret creds func isClientCredsAvailable(config map[string]string) bool { - return (config[blockstorage.AzureTenantID] != "" && + return config[blockstorage.AzureTenantID] != "" && config[blockstorage.AzureClientID] != "" && - config[blockstorage.AzureClientSecret] != "") + config[blockstorage.AzureClientSecret] != "" } // determine if the combination of creds are MSI creds func isMSICredsAvailable(config map[string]string) bool { _, clientIDok := config[blockstorage.AzureClientID] - return (clientIDok && config[blockstorage.AzureTenantID] == "" && - config[blockstorage.AzureClientSecret] == "") + return clientIDok && config[blockstorage.AzureTenantID] == "" && + config[blockstorage.AzureClientSecret] == "" +} + +func isDefaultCredsAvailable(config map[string]string) bool { + _, clientIDok := config[blockstorage.AzureClientID] + _, tenantIDok := config[blockstorage.AzureTenantID] + _, clientSecretOk := config[blockstorage.AzureClientSecret] + return !clientIDok && !tenantIDok && !clientSecretOk } type ClientCredentialsConfig struct { @@ -53,22 +60,58 @@ func NewClientCredentialsConfig(clientID string, clientSecret string, tenantID s // Public interface to authenticate with different Azure credentials type type AzureAuthenticator interface { Authenticate(creds map[string]string) error + GetTokenCredential() azcore.TokenCredential } func NewAzureAuthenticator(config map[string]string) (AzureAuthenticator, error) { + // NewAzureAuthenticator opens up the possibility to Auth with: + //1. Env variables + //2. Managed Identity + //3. Workload Identity + //4. AzureCli switch { case isMSICredsAvailable(config): return &MsiAuthenticator{}, nil case isClientCredsAvailable(config): return &ClientSecretAuthenticator{}, nil + case isDefaultCredsAvailable(config): + return &DefaultAuthenticator{}, nil default: return nil, errors.New("Fail to get an authenticator for provided creds combination") } } +// authenticate with default credential +type DefaultAuthenticator struct { + azcore.TokenCredential +} + +func (d *DefaultAuthenticator) GetTokenCredential() azcore.TokenCredential { + return d.TokenCredential +} + +func (d *DefaultAuthenticator) Authenticate(creds map[string]string) error { + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + return errors.Wrap(err, "Failed to create an Azure Default Identity credential") + } + _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) + if err != nil { + return errors.Wrap(err, "Failed to create an access token") + } + d.TokenCredential = cred + // creds passed authentication + return nil +} + // authenticate with MSI creds -type MsiAuthenticator struct{} +type MsiAuthenticator struct { + azcore.TokenCredential +} +func (m *MsiAuthenticator) GetTokenCredential() azcore.TokenCredential { + return m.TokenCredential +} func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { // check if MSI endpoint is available @@ -80,20 +123,25 @@ func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { opts := azidentity.ManagedIdentityCredentialOptions{ID: azClientID} cred, err := azidentity.NewManagedIdentityCredential(&opts) if err != nil { - return errors.Wrap(err, "Failed to create a identity credential") + return errors.Wrap(err, "Failed to create an Azure Managed Identity credential") } _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) - if err != nil { - return errors.Wrap(err, "Failed to create a service principal token") + return errors.Wrap(err, "Failed to create an access token") } + m.TokenCredential = cred // creds passed authentication return nil } // authenticate with client secret creds -type ClientSecretAuthenticator struct{} +type ClientSecretAuthenticator struct { + azcore.TokenCredential +} +func (c *ClientSecretAuthenticator) GetTokenCredential() azcore.TokenCredential { + return c.TokenCredential +} func (c *ClientSecretAuthenticator) Authenticate(creds map[string]string) error { credConfig, err := getCredConfigForAuth(creds) if err != nil { @@ -101,13 +149,13 @@ func (c *ClientSecretAuthenticator) Authenticate(creds map[string]string) error } cred, err := azidentity.NewClientSecretCredential(credConfig.TenantID, credConfig.ClientID, credConfig.ClientSecret, nil) if err != nil { - return errors.Wrap(err, "Failed to create a identity credential") + return errors.Wrap(err, "Failed to create an Azure Client Secret credential") } _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) - if err != nil { - return errors.Wrap(err, "Failed to create a service principal token") + return errors.Wrap(err, "Failed to create an access token") } + c.TokenCredential = cred // creds passed authentication return nil } diff --git a/pkg/blockstorage/azure/auth_test.go b/pkg/blockstorage/azure/auth_test.go index 20573892dc..55c6e15ed1 100644 --- a/pkg/blockstorage/azure/auth_test.go +++ b/pkg/blockstorage/azure/auth_test.go @@ -72,7 +72,7 @@ func (s *AuthSuite) TestIsMSICredsAvailable(c *C) { c.Assert(isMSICredsAvailable(config), Equals, false) } -func (s *AuthSuite) TestNewAzureAutheticator(c *C) { +func (s *AuthSuite) TestNewAzureAuthenticator(c *C) { // successful with client secret creds config := map[string]string{ blockstorage.AzureTenantID: "some-tenant-id", @@ -101,11 +101,11 @@ func (s *AuthSuite) TestNewAzureAutheticator(c *C) { c.Assert(err, IsNil) c.Assert(authenticator, NotNil) - // unsuccessful with no creds + // successful with no creds, but uses azure default credential config = map[string]string{} authenticator, err = NewAzureAuthenticator(config) - c.Assert(err, NotNil) - c.Assert(authenticator, IsNil) + c.Assert(err, IsNil) + c.Assert(authenticator, NotNil) // unsuccessful with an undefined combo of credss config = map[string]string{ diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 50880b53f8..2263edb183 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -20,8 +20,8 @@ package azure import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" "github.com/kanisterio/kanister/pkg/blockstorage" @@ -29,17 +29,13 @@ import ( "github.com/pkg/errors" ) -// Client is a wrapper for Client client +// Client is a wrapper type Client struct { - Cred *azidentity.DefaultAzureCredential - SubscriptionID string - ResourceGroup string - BaseURI string - //https://github.com/Azure-Samples/azure-sdk-for-go-samples/blob/main/sdk/resourcemanager/compute/disk/main.go - //https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/arm/compute#DisksClient - DisksClient *armcompute.DisksClient - //https://github.com/Azure-Samples/azure-sdk-for-go-samples/blob/main/sdk/resourcemanager/compute/snapshot/main.go - //https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/arm/compute#SnapshotsClient + Cred azcore.TokenCredential + SubscriptionID string + ResourceGroup string + BaseURI string + DisksClient *armcompute.DisksClient SnapshotsClient *armcompute.SnapshotsClient SKUsClient *armcompute.ResourceSKUsClient SubscriptionsClient *armsubscriptions.Client @@ -75,10 +71,15 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { } } - cred, err := azidentity.NewDefaultAzureCredential(nil) + authenticator, err := NewAzureAuthenticator(config) if err != nil { return nil, err } + err = authenticator.Authenticate(config) + if err != nil { + return nil, err + } + cred := authenticator.GetTokenCredential() computeClientFactory, err = armcompute.NewClientFactory(subscriptionID, cred, nil) if err != nil { return nil, err diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index 33ecdaf1d9..ac8383747d 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -46,7 +46,7 @@ func (s *ClientSuite) TestClient(c *C) { config[blockstorage.AzureCloudEnvironmentID] = envconfig.GetEnvOrSkip(c, blockstorage.AzureCloudEnvironmentID) azCli, err := NewClient(context.Background(), config) c.Assert(err, IsNil) - + c.Assert(azCli.Cred, NotNil) c.Assert(azCli.SubscriptionID, NotNil) c.Assert(azCli.DisksClient, NotNil) c.Assert(azCli.SnapshotsClient, NotNil) From 144666b58ba4d10e67ee31095b6dd3691fe21375 Mon Sep 17 00:00:00 2001 From: mabhi Date: Sat, 14 Oct 2023 10:41:52 +0530 Subject: [PATCH 07/18] Addressed review changes Signed-off-by: mabhi --- pkg/blockstorage/azure/auth.go | 8 ++++---- pkg/blockstorage/azure/azuredisk.go | 2 +- pkg/blockstorage/azure/client.go | 2 +- pkg/blockstorage/azure/client_test.go | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index e10509fd2a..a9d252a641 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -60,7 +60,7 @@ func NewClientCredentialsConfig(clientID string, clientSecret string, tenantID s // Public interface to authenticate with different Azure credentials type type AzureAuthenticator interface { Authenticate(creds map[string]string) error - GetTokenCredential() azcore.TokenCredential + GetAuthorizer() azcore.TokenCredential } func NewAzureAuthenticator(config map[string]string) (AzureAuthenticator, error) { @@ -86,7 +86,7 @@ type DefaultAuthenticator struct { azcore.TokenCredential } -func (d *DefaultAuthenticator) GetTokenCredential() azcore.TokenCredential { +func (d *DefaultAuthenticator) GetAuthorizer() azcore.TokenCredential { return d.TokenCredential } @@ -109,7 +109,7 @@ type MsiAuthenticator struct { azcore.TokenCredential } -func (m *MsiAuthenticator) GetTokenCredential() azcore.TokenCredential { +func (m *MsiAuthenticator) GetAuthorizer() azcore.TokenCredential { return m.TokenCredential } func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { @@ -139,7 +139,7 @@ type ClientSecretAuthenticator struct { azcore.TokenCredential } -func (c *ClientSecretAuthenticator) GetTokenCredential() azcore.TokenCredential { +func (c *ClientSecretAuthenticator) GetAuthorizer() azcore.TokenCredential { return c.TokenCredential } func (c *ClientSecretAuthenticator) Authenticate(creds map[string]string) error { diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 01a7765685..861ce70cb9 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -110,7 +110,7 @@ func (s *AdStorage) VolumeCreate(ctx context.Context, volume blockstorage.Volume if err != nil { return nil, errors.Wrapf(err, "Volume create %s polling error", diskName) } - return s.VolumeGet(ctx, blockstorage.String(resp.ID), volume.Az) + return s.VolumeParse(ctx, resp.Disk) } func (s *AdStorage) VolumeDelete(ctx context.Context, volume *blockstorage.Volume) error { diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 2263edb183..c7ae40e2d6 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -79,7 +79,7 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { if err != nil { return nil, err } - cred := authenticator.GetTokenCredential() + cred := authenticator.GetAuthorizer() computeClientFactory, err = armcompute.NewClientFactory(subscriptionID, cred, nil) if err != nil { return nil, err diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index ac8383747d..539d71e721 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -93,7 +93,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { expCCC ClientCredentialsConfig }{ { - name: "TC1", + name: "Test with all attributes in configuration", env: PublicCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", @@ -112,7 +112,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: IsNil, }, { - name: "TC2", + name: "Test with client credential in configuration", env: PublicCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", @@ -129,7 +129,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: IsNil, }, { - name: "TC3", + name: "Test without AD in configuration", env: USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", @@ -148,7 +148,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: IsNil, }, { - name: "TC4", + name: "Test with tenantid and clientid in configuration", env: USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", @@ -157,7 +157,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: NotNil, }, { - name: "TC5", + name: "Test with tenantid in configuration", env: USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", @@ -165,7 +165,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: NotNil, }, { - name: "TC6", + name: "Test with nil configuration", env: USGovernmentCloud, config: map[string]string{}, errChecker: NotNil, From 5a1585ca2488b9089e7ef5fd228ad1f3052a01f9 Mon Sep 17 00:00:00 2001 From: mabhi Date: Sun, 15 Oct 2023 10:05:17 +0530 Subject: [PATCH 08/18] Removed explicit token fetch Signed-off-by: mabhi --- pkg/blockstorage/azure/auth.go | 14 -------------- pkg/blockstorage/helper_test.go | 1 + 2 files changed, 1 insertion(+), 14 deletions(-) create mode 100644 pkg/blockstorage/helper_test.go diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index a9d252a641..a8d1f9f7b7 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -1,10 +1,8 @@ package azure import ( - "context" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/pkg/errors" @@ -95,10 +93,6 @@ func (d *DefaultAuthenticator) Authenticate(creds map[string]string) error { if err != nil { return errors.Wrap(err, "Failed to create an Azure Default Identity credential") } - _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) - if err != nil { - return errors.Wrap(err, "Failed to create an access token") - } d.TokenCredential = cred // creds passed authentication return nil @@ -125,10 +119,6 @@ func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { if err != nil { return errors.Wrap(err, "Failed to create an Azure Managed Identity credential") } - _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) - if err != nil { - return errors.Wrap(err, "Failed to create an access token") - } m.TokenCredential = cred // creds passed authentication return nil @@ -151,10 +141,6 @@ func (c *ClientSecretAuthenticator) Authenticate(creds map[string]string) error if err != nil { return errors.Wrap(err, "Failed to create an Azure Client Secret credential") } - _, err = cred.GetToken(context.Background(), policy.TokenRequestOptions{}) - if err != nil { - return errors.Wrap(err, "Failed to create an access token") - } c.TokenCredential = cred // creds passed authentication return nil diff --git a/pkg/blockstorage/helper_test.go b/pkg/blockstorage/helper_test.go new file mode 100644 index 0000000000..5ee1af48c8 --- /dev/null +++ b/pkg/blockstorage/helper_test.go @@ -0,0 +1 @@ +package blockstorage From be7d906fc13b4542b0a2562c64b8665c4c74d54a Mon Sep 17 00:00:00 2001 From: mabhi Date: Mon, 16 Oct 2023 21:25:11 +0530 Subject: [PATCH 09/18] Added test cases for helper methods Signed-off-by: mabhi --- pkg/blockstorage/helper_test.go | 83 +++++++++++++++++++++++++++++++++ pkg/blockstorage/helpers.go | 2 +- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/pkg/blockstorage/helper_test.go b/pkg/blockstorage/helper_test.go index 5ee1af48c8..6dcbef9079 100644 --- a/pkg/blockstorage/helper_test.go +++ b/pkg/blockstorage/helper_test.go @@ -1 +1,84 @@ package blockstorage + +import ( + . "gopkg.in/check.v1" +) + +type HelperSuite struct{} + +var _ = Suite(&HelperSuite{}) + +func (s *HelperSuite) SetUpSuite(c *C) { +} + +func (h *HelperSuite) TestStringSlice(c *C) { + source := []string{"test1", "test2"} + target := StringSlice(&source) + c.Assert(target[0], Equals, source[0]) + c.Assert(target[1], Equals, source[1]) +} + +func (s *HelperSuite) TestStringSlicePtr(c *C) { + source := []string{"test1", "test2"} + res := StringSlicePtr(source) + target := *res + c.Assert(target[0], Equals, source[0]) + c.Assert(target[1], Equals, source[1]) +} + +func (s *HelperSuite) TestSliceStringPtr(c *C) { + source := []string{"test1", "test2"} + res := SliceStringPtr(source) + for i, elePtr := range res { + var target = *elePtr + c.Assert(target, Equals, source[i]) + } +} + +func (s *HelperSuite) TestBoolFromPtr(c *C) { + source := true + target := Bool(&source) + c.Assert(target, Equals, source) +} + +func (s *HelperSuite) TestBoolToPtr(c *C) { + source := true + target := BoolPtr(source) + c.Assert(*target, Equals, source) +} + +func (s *HelperSuite) TestIntFromPtr(c *C) { + source := 1 + target := Int(&source) + c.Assert(target, Equals, source) +} + +func (s *HelperSuite) TestIntToPtr(c *C) { + source := 1 + target := IntPtr(source) + c.Assert(*target, Equals, source) +} + +func (s *HelperSuite) TestFloat32FromPtr(c *C) { + source := float32(1) + target := Float32(&source) + c.Assert(target, Equals, source) +} + +func (s *HelperSuite) TestFloat32ToPtr(c *C) { + source := float32(1) + target := Float32Ptr(source) + c.Assert(*target, Equals, source) +} + +func (s *HelperSuite) TestStringFromPtr(c *C) { + source := "test" + target := String(&source) + c.Assert(target, Equals, source) +} + +func (s *HelperSuite) TestStringToPtr(c *C) { + source := "test" + target := StringPtr(source) + c.Assert(*target, Equals, source) +} diff --git a/pkg/blockstorage/helpers.go b/pkg/blockstorage/helpers.go index da1ea4d96d..74c7c10256 100644 --- a/pkg/blockstorage/helpers.go +++ b/pkg/blockstorage/helpers.go @@ -220,7 +220,7 @@ func Float32Ptr(i float32) *float32 { return &i } -// Float64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. +// ToFloat64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. func Float64(i *float64) float64 { if i != nil { return *i From b09e17c20471077b1f81b45ac523a155db858343 Mon Sep 17 00:00:00 2001 From: mabhi Date: Tue, 17 Oct 2023 19:38:30 +0530 Subject: [PATCH 10/18] Use deferenced disk pointer during volume list Signed-off-by: mabhi --- pkg/blockstorage/azure/azuredisk.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 861ce70cb9..8c2689cdb8 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -442,7 +442,7 @@ func (s *AdStorage) VolumesList(ctx context.Context, tags map[string]string, zon return nil, errors.Wrap(err, "DisksClient.List in VolumesList") } for _, disk := range page.Value { - vol, err := s.VolumeParse(ctx, disk) + vol, err := s.VolumeParse(ctx, *disk) if err != nil { return nil, errors.Wrap(err, "DisksClient.List in VolumesList, failure in parsing Volume") } @@ -524,7 +524,7 @@ func (s *AdStorage) VolumeCreateFromSnapshot(ctx context.Context, snapshot block if err != nil { return nil, errors.Wrapf(err, "DiskCLient.CreateOrUpdate in VolumeCreateFromSnapshot, diskName: %s, snapshotID: %s", diskName, snapshot.ID) } - return s.VolumeGet(ctx, blockstorage.String(resp.ID), snapshot.Volume.Az) + return s.VolumeParse(ctx, resp.Disk) } func (s *AdStorage) getRegionAndZoneID(ctx context.Context, sourceRegion, volAz string) (string, string, error) { From 8e6af5f5a0828b1934b7aabc5d5842a04d9aa27a Mon Sep 17 00:00:00 2001 From: mabhi Date: Tue, 17 Oct 2023 21:09:46 +0530 Subject: [PATCH 11/18] Update snapshot deference during listing Signed-off-by: mabhi --- pkg/blockstorage/azure/azuredisk.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 8c2689cdb8..af55955817 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -7,12 +7,13 @@ package azure import ( "context" "fmt" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" "regexp" "strings" "time" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" + azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/storage" "github.com/gofrs/uuid" @@ -463,7 +464,7 @@ func (s *AdStorage) SnapshotsList(ctx context.Context, tags map[string]string) ( return nil, errors.Wrap(err, "SnapshotsClient.List in SnapshotsList") } for _, snap := range page.Value { - k10Snap, err := s.SnapshotParse(ctx, snap) + k10Snap, err := s.SnapshotParse(ctx, *snap) if err != nil { log.WithError(err).Print("Incorrect Snaphost type", field.M{"SnapshotID": snap.ID}) continue From 4f1fa7ca67431927c99fd9a4cd40d214a947ace0 Mon Sep 17 00:00:00 2001 From: mabhi Date: Wed, 18 Oct 2023 10:42:03 +0530 Subject: [PATCH 12/18] Fix nil pointer exception during snapshot-id fetch Signed-off-by: mabhi --- pkg/blockstorage/azure/azuredisk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index af55955817..1b773f3896 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -407,7 +407,7 @@ func (s *AdStorage) SnapshotParse(ctx context.Context, snapshot interface{}) (*b func (s *AdStorage) snapshotParse(ctx context.Context, snap armcompute.Snapshot) *blockstorage.Snapshot { vol := &blockstorage.Volume{ Type: s.Type(), - ID: *snap.Properties.CreationData.SourceResourceID, + ID: *snap.ID, } snapCreationTime := *snap.Properties.TimeCreated From 67e1035ea5522f30938cdff48bf63916caf8d0a5 Mon Sep 17 00:00:00 2001 From: Abhijit Mukherjee Date: Wed, 25 Oct 2023 12:55:01 +0530 Subject: [PATCH 13/18] Reverted azure-default-credential handling Signed-off-by: Abhijit Mukherjee --- pkg/blockstorage/azure/auth.go | 35 +++-------------------------- pkg/blockstorage/azure/auth_test.go | 6 ++--- 2 files changed, 6 insertions(+), 35 deletions(-) diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index a8d1f9f7b7..415ee9c707 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -26,13 +26,6 @@ func isMSICredsAvailable(config map[string]string) bool { config[blockstorage.AzureClientSecret] == "" } -func isDefaultCredsAvailable(config map[string]string) bool { - _, clientIDok := config[blockstorage.AzureClientID] - _, tenantIDok := config[blockstorage.AzureTenantID] - _, clientSecretOk := config[blockstorage.AzureClientSecret] - return !clientIDok && !tenantIDok && !clientSecretOk -} - type ClientCredentialsConfig struct { ClientID string ClientSecret string @@ -72,32 +65,11 @@ func NewAzureAuthenticator(config map[string]string) (AzureAuthenticator, error) return &MsiAuthenticator{}, nil case isClientCredsAvailable(config): return &ClientSecretAuthenticator{}, nil - case isDefaultCredsAvailable(config): - return &DefaultAuthenticator{}, nil default: return nil, errors.New("Fail to get an authenticator for provided creds combination") } } -// authenticate with default credential -type DefaultAuthenticator struct { - azcore.TokenCredential -} - -func (d *DefaultAuthenticator) GetAuthorizer() azcore.TokenCredential { - return d.TokenCredential -} - -func (d *DefaultAuthenticator) Authenticate(creds map[string]string) error { - cred, err := azidentity.NewDefaultAzureCredential(nil) - if err != nil { - return errors.Wrap(err, "Failed to create an Azure Default Identity credential") - } - d.TokenCredential = cred - // creds passed authentication - return nil -} - // authenticate with MSI creds type MsiAuthenticator struct { azcore.TokenCredential @@ -106,10 +78,9 @@ type MsiAuthenticator struct { func (m *MsiAuthenticator) GetAuthorizer() azcore.TokenCredential { return m.TokenCredential } -func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { +func (m *MsiAuthenticator) Authenticate(config map[string]string) error { // check if MSI endpoint is available - - clientID, ok := creds[blockstorage.AzureClientID] + clientID, ok := config[blockstorage.AzureClientID] if !ok || clientID == "" { return errors.New("Failed to fetch azure clientID") } @@ -120,7 +91,7 @@ func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { return errors.Wrap(err, "Failed to create an Azure Managed Identity credential") } m.TokenCredential = cred - // creds passed authentication + // config passed authentication return nil } diff --git a/pkg/blockstorage/azure/auth_test.go b/pkg/blockstorage/azure/auth_test.go index 55c6e15ed1..543412edb7 100644 --- a/pkg/blockstorage/azure/auth_test.go +++ b/pkg/blockstorage/azure/auth_test.go @@ -101,11 +101,11 @@ func (s *AuthSuite) TestNewAzureAuthenticator(c *C) { c.Assert(err, IsNil) c.Assert(authenticator, NotNil) - // successful with no creds, but uses azure default credential + // unsuccessful with no creds config = map[string]string{} authenticator, err = NewAzureAuthenticator(config) - c.Assert(err, IsNil) - c.Assert(authenticator, NotNil) + c.Assert(err, NotNil) + c.Assert(authenticator, IsNil) // unsuccessful with an undefined combo of credss config = map[string]string{ From 91ee666758ff2c0746c75f26adeb4ca428c68951 Mon Sep 17 00:00:00 2001 From: Abhijit Mukherjee Date: Wed, 1 Nov 2023 20:10:02 +0530 Subject: [PATCH 14/18] Updated changes from master Signed-off-by: Abhijit Mukherjee --- go.mod | 15 ++++----------- go.sum | 4 ---- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 7dedc29b7a..e9e6ec9719 100644 --- a/go.mod +++ b/go.mod @@ -78,9 +78,8 @@ require ( github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect - github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 // indirect + github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/alecthomas/kingpin/v2 v2.3.2 // indirect @@ -218,23 +217,17 @@ require ( ) require ( - github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect + github.com/Azure/go-autorest/autorest v0.11.27 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect - github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect - github.com/Azure/go-autorest/autorest v0.11.27 // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.27 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect ) diff --git a/go.sum b/go.sum index 1c4eeef3e6..e8e23fee04 100644 --- a/go.sum +++ b/go.sum @@ -596,9 +596,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -685,7 +683,6 @@ golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -696,7 +693,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From c4323c5c576574aa0021223241188dc69badd011 Mon Sep 17 00:00:00 2001 From: Abhijit Mukherjee Date: Wed, 8 Nov 2023 19:42:16 +0530 Subject: [PATCH 15/18] Addressing review comments Signed-off-by: Abhijit Mukherjee --- pkg/blockstorage/azure/auth.go | 5 --- pkg/blockstorage/azure/azuredisk.go | 8 ++--- pkg/blockstorage/helper_test.go | 38 --------------------- pkg/blockstorage/helpers.go | 51 +---------------------------- 4 files changed, 5 insertions(+), 97 deletions(-) diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index 415ee9c707..2d34693179 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -55,11 +55,6 @@ type AzureAuthenticator interface { } func NewAzureAuthenticator(config map[string]string) (AzureAuthenticator, error) { - // NewAzureAuthenticator opens up the possibility to Auth with: - //1. Env variables - //2. Managed Identity - //3. Workload Identity - //4. AzureCli switch { case isMSICredsAvailable(config): return &MsiAuthenticator{}, nil diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 1b773f3896..a9feeb9e7b 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -240,7 +240,7 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. if err != nil { return nil, errors.Wrap(err, "Poller failed to retrieve snapshot") } - snap, err := s.SnapshotGet(ctx, blockstorage.String(createSnapRes.ID)) + snap, err := s.SnapshotGet(ctx, blockstorage.StringFromPtr(createSnapRes.ID)) if err != nil { return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) } @@ -379,21 +379,21 @@ func (s *AdStorage) VolumeParse(ctx context.Context, volume interface{}) (*block if vol.Tags != nil { tags = blockstorage.StringMap(vol.Tags) } - az := blockstorage.String(vol.Location) + az := blockstorage.StringFromPtr(vol.Location) if z := vol.Zones; len(z) > 0 { az = az + "-" + *(z[0]) } return &blockstorage.Volume{ Type: s.Type(), - ID: blockstorage.String(vol.ID), + ID: blockstorage.StringFromPtr(vol.ID), Encrypted: encrypted, SizeInBytes: blockstorage.Int64(vol.Properties.DiskSizeBytes), Az: az, Tags: blockstorage.MapToKeyValue(tags), VolumeType: string(*vol.SKU.Name), CreationTime: blockstorage.TimeStamp(*vol.Properties.TimeCreated), - Attributes: map[string]string{"Users": blockstorage.String(vol.ManagedBy)}, + Attributes: map[string]string{"Users": blockstorage.StringFromPtr(vol.ManagedBy)}, }, nil } diff --git a/pkg/blockstorage/helper_test.go b/pkg/blockstorage/helper_test.go index 6dcbef9079..2097c86eec 100644 --- a/pkg/blockstorage/helper_test.go +++ b/pkg/blockstorage/helper_test.go @@ -18,14 +18,6 @@ func (h *HelperSuite) TestStringSlice(c *C) { c.Assert(target[1], Equals, source[1]) } -func (s *HelperSuite) TestStringSlicePtr(c *C) { - source := []string{"test1", "test2"} - res := StringSlicePtr(source) - target := *res - c.Assert(target[0], Equals, source[0]) - c.Assert(target[1], Equals, source[1]) -} - func (s *HelperSuite) TestSliceStringPtr(c *C) { source := []string{"test1", "test2"} res := SliceStringPtr(source) @@ -35,18 +27,6 @@ func (s *HelperSuite) TestSliceStringPtr(c *C) { } } -func (s *HelperSuite) TestBoolFromPtr(c *C) { - source := true - target := Bool(&source) - c.Assert(target, Equals, source) -} - -func (s *HelperSuite) TestBoolToPtr(c *C) { - source := true - target := BoolPtr(source) - c.Assert(*target, Equals, source) -} - func (s *HelperSuite) TestIntFromPtr(c *C) { source := 1 target := Int(&source) @@ -59,24 +39,6 @@ func (s *HelperSuite) TestIntToPtr(c *C) { c.Assert(*target, Equals, source) } -func (s *HelperSuite) TestFloat32FromPtr(c *C) { - source := float32(1) - target := Float32(&source) - c.Assert(target, Equals, source) -} - -func (s *HelperSuite) TestFloat32ToPtr(c *C) { - source := float32(1) - target := Float32Ptr(source) - c.Assert(*target, Equals, source) -} - -func (s *HelperSuite) TestStringFromPtr(c *C) { - source := "test" - target := String(&source) - c.Assert(target, Equals, source) -} - func (s *HelperSuite) TestStringToPtr(c *C) { source := "test" target := StringPtr(source) diff --git a/pkg/blockstorage/helpers.go b/pkg/blockstorage/helpers.go index 74c7c10256..104295d22e 100644 --- a/pkg/blockstorage/helpers.go +++ b/pkg/blockstorage/helpers.go @@ -141,11 +141,6 @@ func StringSlice(s *[]string) []string { return nil } -// StringSlicePtr returns a pointer to the passed string slice. -func StringSlicePtr(s []string) *[]string { - return azto.Ptr(s) -} - // SliceStringPtr returns a slice of string pointers from the passed string slice. func SliceStringPtr(s []string) []*string { ms := make([]*string, len(s)) @@ -155,19 +150,6 @@ func SliceStringPtr(s []string) []*string { return ms } -// Bool returns a bool value for the passed bool pointer. It returns false if the pointer is nil. -func Bool(b *bool) bool { - if b != nil { - return *b - } - return false -} - -// BoolPtr returns a pointer to the passed bool. -func BoolPtr(b bool) *bool { - return &b -} - // Int returns an int value for the passed int pointer. It returns 0 if the pointer is nil. func Int(i *int) int { if i != nil { @@ -202,40 +184,9 @@ func Int64(i *int64) int64 { return 0 } -// Int64Ptr returns a pointer to the passed int64. -func Int64Ptr(i int64) *int64 { - return &i -} - -// Float32 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. -func Float32(i *float32) float32 { - if i != nil { - return *i - } - return 0.0 -} - -// Float32Ptr returns a pointer to the passed float32. -func Float32Ptr(i float32) *float32 { - return &i -} - -// ToFloat64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. -func Float64(i *float64) float64 { - if i != nil { - return *i - } - return 0.0 -} - -// Float64Ptr returns a pointer to the passed float64. -func Float64Ptr(i float64) *float64 { - return &i -} - // String returns a string value for the passed string pointer. It returns the empty string if the // pointer is nil. -func String(s *string) string { +func StringFromPtr(s *string) string { if s != nil { return *s } From 6b2bdc6ad7b91adf0a9f7063434760aa47cd232d Mon Sep 17 00:00:00 2001 From: Abhijit Mukherjee Date: Tue, 14 Nov 2023 12:21:27 +0530 Subject: [PATCH 16/18] Addressed review comments on nil pointers Signed-off-by: Abhijit Mukherjee --- pkg/blockstorage/azure/azuredisk.go | 100 +++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 18 deletions(-) diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index a9feeb9e7b..8a08eb218b 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -301,10 +301,14 @@ func (s *AdStorage) SnapshotCreate(ctx context.Context, volume blockstorage.Volu return nil, errors.Wrapf(err, "Failed to create snapshot for volume %v", volume) } resp, err := pollerResp.PollUntilDone(ctx, nil) - blockSnapshot := s.snapshotParse(ctx, resp.Snapshot) if err != nil { return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) } + blockSnapshot, err := s.snapshotParse(ctx, resp.Snapshot) + if err != nil { + return nil, errors.Wrapf(err, "Failed to Parse Snapshot, snaphotName %s", snapName) + } + blockSnapshot.Volume = &volume return blockSnapshot, nil } @@ -362,7 +366,7 @@ func (s *AdStorage) SnapshotGet(ctx context.Context, id string) (*blockstorage.S return nil, errors.Wrapf(err, "SnapshotsClient.Get: Failed to get snapshot with ID %s", id) } - return s.snapshotParse(ctx, snapRes.Snapshot), nil + return s.snapshotParse(ctx, snapRes.Snapshot) } func (s *AdStorage) VolumeParse(ctx context.Context, volume interface{}) (*blockstorage.Volume, error) { @@ -383,34 +387,73 @@ func (s *AdStorage) VolumeParse(ctx context.Context, volume interface{}) (*block if z := vol.Zones; len(z) > 0 { az = az + "-" + *(z[0]) } + volumeType := "" + if vol.SKU != nil && + vol.SKU.Name != nil { + volumeType = string(*vol.SKU.Name) + } else { + return nil, errors.New("Volume type is not available") + } + + volId := "" + if vol.ID != nil { + volId = blockstorage.StringFromPtr(vol.ID) + } else { + return nil, errors.New("Volume Id is not available") + } + diskSize := int64(0) + if vol.Properties != nil && + vol.Properties.DiskSizeBytes != nil { + diskSize = blockstorage.Int64(vol.Properties.DiskSizeBytes) + } + + var creationTime = time.Now() + if vol.Properties != nil && vol.Properties.TimeCreated != nil { + creationTime = *vol.Properties.TimeCreated + } + + var managedBy = "N.A." + if vol.ManagedBy != nil { + managedBy = blockstorage.StringFromPtr(vol.ManagedBy) + } return &blockstorage.Volume{ Type: s.Type(), - ID: blockstorage.StringFromPtr(vol.ID), + ID: volId, Encrypted: encrypted, - SizeInBytes: blockstorage.Int64(vol.Properties.DiskSizeBytes), + SizeInBytes: diskSize, Az: az, Tags: blockstorage.MapToKeyValue(tags), - VolumeType: string(*vol.SKU.Name), - CreationTime: blockstorage.TimeStamp(*vol.Properties.TimeCreated), - Attributes: map[string]string{"Users": blockstorage.StringFromPtr(vol.ManagedBy)}, + VolumeType: volumeType, + CreationTime: blockstorage.TimeStamp(creationTime), + Attributes: map[string]string{"Users": managedBy}, }, nil } func (s *AdStorage) SnapshotParse(ctx context.Context, snapshot interface{}) (*blockstorage.Snapshot, error) { if snap, ok := snapshot.(armcompute.Snapshot); ok { - return s.snapshotParse(ctx, snap), nil + return s.snapshotParse(ctx, snap) } return nil, errors.New(fmt.Sprintf("Snapshot is not of type *armcompute.Snapshot, snapshot: %v", snapshot)) } -func (s *AdStorage) snapshotParse(ctx context.Context, snap armcompute.Snapshot) *blockstorage.Snapshot { +func (s *AdStorage) snapshotParse(ctx context.Context, snap armcompute.Snapshot) (*blockstorage.Snapshot, error) { + snapId := "" + if snap.ID != nil { + snapId = *snap.ID + } else { + return nil, errors.New("Snapshot ID is missing") + } vol := &blockstorage.Volume{ Type: s.Type(), - ID: *snap.ID, + ID: snapId, + } + + snapCreationTime := time.Now() + if snap.Properties != nil && snap.Properties.TimeCreated != nil { + snapCreationTime = *snap.Properties.TimeCreated } - snapCreationTime := *snap.Properties.TimeCreated encrypted := false if snap.Properties.EncryptionSettingsCollection != nil && snap.Properties.EncryptionSettingsCollection.Enabled != nil { @@ -420,16 +463,27 @@ func (s *AdStorage) snapshotParse(ctx context.Context, snap armcompute.Snapshot) if snap.Tags != nil { tags = blockstorage.StringMap(snap.Tags) } + + diskSize := azto.Ptr(int64(0)) + if snap.Properties != nil && + snap.Properties.DiskSizeBytes != nil { + diskSize = snap.Properties.DiskSizeBytes + } + + region := "" + if snap.Location != nil { + region = *snap.Location + } return &blockstorage.Snapshot{ Encrypted: encrypted, - ID: *snap.ID, - Region: *snap.Location, - SizeInBytes: *snap.Properties.DiskSizeBytes, + ID: snapId, + Region: region, + SizeInBytes: blockstorage.Int64(diskSize), Tags: blockstorage.MapToKeyValue(tags), Type: s.Type(), Volume: vol, CreationTime: blockstorage.TimeStamp(snapCreationTime), - } + }, nil } func (s *AdStorage) VolumesList(ctx context.Context, tags map[string]string, zone string) ([]*blockstorage.Volume, error) { @@ -672,7 +726,11 @@ func (s *AdStorage) dynamicRegionMapAzure(ctx context.Context) (map[string][]str return nil, errors.Wrap(err, "failed to advance page") } for _, location := range page.Value { - regionMap[*location.Name] = make(LocationZoneMap) + if location != nil && location.Name != nil { + regionMap[*location.Name] = make(LocationZoneMap) + } else { + continue + } } } @@ -705,11 +763,17 @@ func (s *AdStorage) dynamicRegionMapAzure(ctx context.Context) (map[string][]str func (s *AdStorage) mapLocationToZone(skuResult *armcompute.ResourceSKU, regionMap *map[string]LocationZoneMap) { var rm = *regionMap for _, locationInfo := range skuResult.LocationInfo { - if val, ok := rm[*locationInfo.Location]; ok { + location := "" + if locationInfo.Location != nil { + location = *locationInfo.Location + } else { + continue + } + if val, ok := rm[location]; ok { for _, zone := range locationInfo.Zones { val[*zone] = struct{}{} } - rm[*locationInfo.Location] = val + rm[location] = val } } } From 45c924917e29d92c97f818d80cee44c51de8f026 Mon Sep 17 00:00:00 2001 From: Abhijit Mukherjee Date: Tue, 14 Nov 2023 14:37:40 +0530 Subject: [PATCH 17/18] Addressed import grouping Signed-off-by: Abhijit Mukherjee --- pkg/blockstorage/azure/auth.go | 3 ++- pkg/blockstorage/azure/auth_test.go | 3 ++- pkg/blockstorage/azure/azuredisk.go | 3 +-- pkg/blockstorage/azure/client.go | 4 +++- pkg/blockstorage/azure/client_test.go | 8 +++++--- pkg/blockstorage/azure/environments.go | 3 ++- pkg/blockstorage/helpers.go | 1 + 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index 2d34693179..a43a2d3ad1 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -4,8 +4,9 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" - "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/pkg/errors" + + "github.com/kanisterio/kanister/pkg/blockstorage" ) const ActiveDirectory = "activeDirectory" diff --git a/pkg/blockstorage/azure/auth_test.go b/pkg/blockstorage/azure/auth_test.go index 543412edb7..e156e7c303 100644 --- a/pkg/blockstorage/azure/auth_test.go +++ b/pkg/blockstorage/azure/auth_test.go @@ -15,8 +15,9 @@ package azure import ( - "github.com/kanisterio/kanister/pkg/blockstorage" . "gopkg.in/check.v1" + + "github.com/kanisterio/kanister/pkg/blockstorage" ) type AuthSuite struct{} diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 8a08eb218b..199b0363da 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -11,10 +11,9 @@ import ( "strings" "time" + azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" - - azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/storage" "github.com/gofrs/uuid" "github.com/pkg/errors" diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index c7ae40e2d6..79c5413f7d 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -20,13 +20,15 @@ package azure import ( "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions" + "github.com/pkg/errors" + "github.com/kanisterio/kanister/pkg/blockstorage" "github.com/kanisterio/kanister/pkg/log" - "github.com/pkg/errors" ) // Client is a wrapper diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index 539d71e721..72970dc6f5 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -17,12 +17,14 @@ package azure import ( "context" "fmt" + "strings" + "testing" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" + . "gopkg.in/check.v1" + "github.com/kanisterio/kanister/pkg/blockstorage" envconfig "github.com/kanisterio/kanister/pkg/config" - . "gopkg.in/check.v1" - "strings" - "testing" ) // Hook up gocheck into the "go test" runner. diff --git a/pkg/blockstorage/azure/environments.go b/pkg/blockstorage/azure/environments.go index 5fdc460a14..6ef72ac997 100644 --- a/pkg/blockstorage/azure/environments.go +++ b/pkg/blockstorage/azure/environments.go @@ -2,8 +2,9 @@ package azure import ( "fmt" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" ) const ( diff --git a/pkg/blockstorage/helpers.go b/pkg/blockstorage/helpers.go index 104295d22e..ae28929b2f 100644 --- a/pkg/blockstorage/helpers.go +++ b/pkg/blockstorage/helpers.go @@ -16,6 +16,7 @@ package blockstorage import ( "bytes" + azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" ktags "github.com/kanisterio/kanister/pkg/blockstorage/tags" From 0ad1e5fade383ba205341c1dfacf5c3a0e04ca1c Mon Sep 17 00:00:00 2001 From: Abhijit Mukherjee Date: Wed, 22 Nov 2023 16:27:47 +0530 Subject: [PATCH 18/18] Added license information Signed-off-by: Abhijit Mukherjee --- pkg/blockstorage/azure/azuredisk.go | 1 + pkg/blockstorage/azure/environments.go | 14 ++++++++++++++ pkg/blockstorage/helper_test.go | 14 ++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index 199b0363da..cad8c53098 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -2,6 +2,7 @@ // Related Ticket- https://github.com/kanisterio/kanister/issues/1684 // //nolint:staticcheck + package azure import ( diff --git a/pkg/blockstorage/azure/environments.go b/pkg/blockstorage/azure/environments.go index 6ef72ac997..181c8b45c5 100644 --- a/pkg/blockstorage/azure/environments.go +++ b/pkg/blockstorage/azure/environments.go @@ -1,3 +1,17 @@ +// Copyright 2019 The Kanister Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package azure import ( diff --git a/pkg/blockstorage/helper_test.go b/pkg/blockstorage/helper_test.go index 2097c86eec..f3db25f422 100644 --- a/pkg/blockstorage/helper_test.go +++ b/pkg/blockstorage/helper_test.go @@ -1,3 +1,17 @@ +// Copyright 2019 The Kanister Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package blockstorage import (