From 2931c5b35bda3ceed20e662a90fac6bcfe085ab4 Mon Sep 17 00:00:00 2001 From: Prasad Ghangal Date: Thu, 23 Nov 2023 01:55:45 +0530 Subject: [PATCH] Revert "Upgrade to new azure-go-sdk and refactor old go-autorest references (#2368)" (#2490) This reverts commit 94ac01a46d2c09f79a92583a1781a11f8b336b1e. --- go.mod | 25 +- go.sum | 34 +- pkg/blockstorage/azure/auth.go | 102 ++--- pkg/blockstorage/azure/auth_test.go | 5 +- pkg/blockstorage/azure/azuredisk.go | 445 ++++++++++------------ pkg/blockstorage/azure/client.go | 128 ++++--- pkg/blockstorage/azure/client_test.go | 50 +-- pkg/blockstorage/azure/environments.go | 98 ----- pkg/blockstorage/helper_test.go | 60 --- pkg/blockstorage/helpers.go | 93 ----- pkg/kopia/command/storage/secret_utils.go | 5 +- 11 files changed, 371 insertions(+), 674 deletions(-) delete mode 100644 pkg/blockstorage/azure/environments.go delete mode 100644 pkg/blockstorage/helper_test.go diff --git a/go.mod b/go.mod index e9e6ec9719..068c6a8655 100644 --- a/go.mod +++ b/go.mod @@ -13,10 +13,10 @@ 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,7 +63,6 @@ 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 ( @@ -72,13 +71,16 @@ 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/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/AzureAD/microsoft-authentication-library-for-go v1.2.0 // 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 @@ -92,6 +94,7 @@ 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 @@ -140,7 +143,6 @@ 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 @@ -149,6 +151,7 @@ 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 @@ -161,7 +164,6 @@ 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 @@ -217,15 +219,16 @@ require ( ) require ( - 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/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 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect go.opentelemetry.io/otel/metric v1.19.0 // indirect diff --git a/go.sum b/go.sum index e8e23fee04..a61585c594 100644 --- a/go.sum +++ b/go.sum @@ -31,16 +31,6 @@ 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= @@ -53,12 +43,19 @@ 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.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= +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/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= @@ -71,6 +68,8 @@ 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= @@ -140,6 +139,8 @@ 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= @@ -416,6 +417,8 @@ 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= @@ -522,6 +525,7 @@ 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= @@ -596,7 +600,9 @@ 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= @@ -683,6 +689,7 @@ 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= @@ -693,6 +700,7 @@ 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= diff --git a/pkg/blockstorage/azure/auth.go b/pkg/blockstorage/azure/auth.go index a43a2d3ad1..524330f7bb 100644 --- a/pkg/blockstorage/azure/auth.go +++ b/pkg/blockstorage/azure/auth.go @@ -1,58 +1,33 @@ package azure 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/pkg/errors" + "context" + "github.com/Azure/go-autorest/autorest/adal" + "github.com/Azure/go-autorest/autorest/azure/auth" "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 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] == "" -} - -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, - } + return (clientIDok && config[blockstorage.AzureTenantID] == "" && + config[blockstorage.AzureClientSecret] == "") } // Public interface to authenticate with different Azure credentials type type AzureAuthenticator interface { Authenticate(creds map[string]string) error - GetAuthorizer() azcore.TokenCredential } func NewAzureAuthenticator(config map[string]string) (AzureAuthenticator, error) { @@ -67,68 +42,69 @@ func NewAzureAuthenticator(config map[string]string) (AzureAuthenticator, error) } // authenticate with MSI creds -type MsiAuthenticator struct { - azcore.TokenCredential -} +type MsiAuthenticator struct{} -func (m *MsiAuthenticator) GetAuthorizer() azcore.TokenCredential { - return m.TokenCredential -} -func (m *MsiAuthenticator) Authenticate(config map[string]string) error { +func (m *MsiAuthenticator) Authenticate(creds map[string]string) error { // check if MSI endpoint is available - clientID, ok := config[blockstorage.AzureClientID] - if !ok || clientID == "" { - return errors.New("Failed to fetch azure clientID") + 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 } - azClientID := azidentity.ClientID(clientID) - opts := azidentity.ManagedIdentityCredentialOptions{ID: azClientID} - cred, err := azidentity.NewManagedIdentityCredential(&opts) + spt, err := msiConfig.ServicePrincipalToken() if err != nil { - return errors.Wrap(err, "Failed to create an Azure Managed Identity credential") + return errors.Wrap(err, "Failed to create a service principal token") } - m.TokenCredential = cred - // config passed authentication + // network call to check for token + err = spt.Refresh() + if err != nil { + return errors.Wrap(err, "Failed to refresh token") + } + // creds passed authentication return nil } // authenticate with client secret creds -type ClientSecretAuthenticator struct { - azcore.TokenCredential -} +type ClientSecretAuthenticator struct{} -func (c *ClientSecretAuthenticator) GetAuthorizer() azcore.TokenCredential { - return c.TokenCredential -} func (c *ClientSecretAuthenticator) Authenticate(creds map[string]string) error { credConfig, err := getCredConfigForAuth(creds) if err != nil { return errors.Wrap(err, "Failed to get Client Secret config") } - cred, err := azidentity.NewClientSecretCredential(credConfig.TenantID, credConfig.ClientID, credConfig.ClientSecret, nil) + // create a service principal token + spt, err := credConfig.ServicePrincipalToken() + if err != nil { + return errors.Wrap(err, "Failed to create a service principal token") + } + // network call to check for token + err = spt.Refresh() if err != nil { - return errors.Wrap(err, "Failed to create an Azure Client Secret credential") + return errors.Wrap(err, "Failed to refresh token") } - c.TokenCredential = cred // creds passed authentication return nil } -func getCredConfigForAuth(config map[string]string) (ClientCredentialsConfig, error) { +func getCredConfigForAuth(config map[string]string) (auth.ClientCredentialsConfig, error) { tenantID, ok := config[blockstorage.AzureTenantID] if !ok { - return ClientCredentialsConfig{}, errors.New("Cannot get tenantID from config") + return auth.ClientCredentialsConfig{}, errors.New("Cannot get tenantID from config") } clientID, ok := config[blockstorage.AzureClientID] if !ok { - return ClientCredentialsConfig{}, errors.New("Cannot get clientID from config") + return auth.ClientCredentialsConfig{}, errors.New("Cannot get clientID from config") } clientSecret, ok := config[blockstorage.AzureClientSecret] if !ok { - return ClientCredentialsConfig{}, errors.New("Cannot get clientSecret from config") + return auth.ClientCredentialsConfig{}, errors.New("Cannot get clientSecret from config") } - credConfig := NewClientCredentialsConfig(clientID, clientSecret, tenantID) + credConfig := auth.NewClientCredentialsConfig(clientID, clientSecret, tenantID) return credConfig, nil } diff --git a/pkg/blockstorage/azure/auth_test.go b/pkg/blockstorage/azure/auth_test.go index e156e7c303..20573892dc 100644 --- a/pkg/blockstorage/azure/auth_test.go +++ b/pkg/blockstorage/azure/auth_test.go @@ -15,9 +15,8 @@ package azure import ( - . "gopkg.in/check.v1" - "github.com/kanisterio/kanister/pkg/blockstorage" + . "gopkg.in/check.v1" ) type AuthSuite struct{} @@ -73,7 +72,7 @@ func (s *AuthSuite) TestIsMSICredsAvailable(c *C) { c.Assert(isMSICredsAvailable(config), Equals, false) } -func (s *AuthSuite) TestNewAzureAuthenticator(c *C) { +func (s *AuthSuite) TestNewAzureAutheticator(c *C) { // successful with client secret creds config := map[string]string{ blockstorage.AzureTenantID: "some-tenant-id", diff --git a/pkg/blockstorage/azure/azuredisk.go b/pkg/blockstorage/azure/azuredisk.go index cad8c53098..c5051b26ee 100644 --- a/pkg/blockstorage/azure/azuredisk.go +++ b/pkg/blockstorage/azure/azuredisk.go @@ -2,7 +2,6 @@ // Related Ticket- https://github.com/kanisterio/kanister/issues/1684 // //nolint:staticcheck - package azure import ( @@ -12,11 +11,12 @@ 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" + "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" "github.com/Azure/azure-sdk-for-go/storage" - "github.com/gofrs/uuid" + azto "github.com/Azure/go-autorest/autorest/to" + uuid "github.com/gofrs/uuid" "github.com/pkg/errors" "github.com/kanisterio/kanister/pkg/blockstorage" @@ -25,6 +25,7 @@ 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) @@ -38,8 +39,6 @@ const ( copyBlobName = "copy-blob-%s.vhd" ) -type LocationZoneMap map[string]struct{} - // AdStorage describes the azure storage client type AdStorage struct { azCli *Client @@ -64,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) } - diskResponse, err := s.azCli.DisksClient.Get(ctx, rg, name, nil) + disk, err := s.azCli.DisksClient.Get(ctx, rg, name) if err != nil { return nil, errors.Wrapf(err, "Failed to get volume, volumeID: %s", id) } - return s.VolumeParse(ctx, diskResponse.Disk) + return s.VolumeParse(ctx, disk) } func (s *AdStorage) VolumeCreate(ctx context.Context, volume blockstorage.Volume) (*blockstorage.Volume, error) { @@ -78,40 +77,43 @@ 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 := &armcompute.DiskProperties{ - CreationData: &armcompute.CreationData{ - CreateOption: azto.Ptr(armcompute.DiskCreateOptionEmpty), + diskProperties := &azcompute.DiskProperties{ + DiskSizeGB: azto.Int32Ptr(int32(blockstorage.SizeInGi(volume.SizeInBytes))), + CreationData: &azcompute.CreationData{ + CreateOption: azcompute.DiskCreateOption(azcompute.DiskCreateOptionTypesEmpty), }, - 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 - 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), - }, + createDisk := azcompute.Disk{ + Name: azto.StringPtr(diskName), + Tags: *azto.StringMapPtr(tags), + Location: azto.StringPtr(region), + DiskProperties: diskProperties, } if id != "" { - createdDisk.Zones = blockstorage.SliceStringPtr([]string{id}) + createDisk.Zones = azto.StringSlicePtr([]string{id}) } - - pollerResp, err := s.azCli.DisksClient.BeginCreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createdDisk, nil) + result, err := s.azCli.DisksClient.CreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createDisk) if err != nil { - return nil, errors.Wrapf(err, "Could not create volume %s", diskName) + return nil, err } - resp, err := pollerResp.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client) if err != nil { - return nil, errors.Wrapf(err, "Volume create %s polling error", diskName) + return nil, err } - return s.VolumeParse(ctx, resp.Disk) + disk, err := result.Result(*s.azCli.DisksClient) + if err != nil { + return nil, err + } + + // 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) } func (s *AdStorage) VolumeDelete(ctx context.Context, volume *blockstorage.Volume) error { @@ -119,11 +121,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) } - poller, err := s.azCli.DisksClient.BeginDelete(ctx, rg, name, nil) + result, err := s.azCli.DisksClient.Delete(ctx, rg, name) if err != nil { return errors.Wrapf(err, "Error in deleting Volume with ID %s", volume.ID) } - _, err = poller.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client) return errors.Wrapf(err, "Error in deleting Volume with ID %s", volume.ID) } @@ -152,27 +154,38 @@ 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, nil) + _, err = s.azCli.SnapshotsClient.Get(ctx, rg, name) if err != nil { return nil, errors.Wrapf(err, "SnapshotsClient.Copy: Failed to get snapshot with ID %s", from.ID) } duration := int32(3600) - gad := armcompute.GrantAccessData{ - Access: azto.Ptr(armcompute.AccessLevelRead), + gad := azcompute.GrantAccessData{ + Access: azcompute.Read, DurationInSeconds: &duration, } - snapshotsGrantAccessPoller, err := s.azCli.SnapshotsClient.BeginGrantAccess(ctx, rg, name, gad, nil) + snapshotsGrantAccessFuture, err := s.azCli.SnapshotsClient.GrantAccess(ctx, rg, name, gad) 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) - snapshotGrantRes, err := snapshotsGrantAccessPoller.PollUntilDone(ctx, nil) + + 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 + }) if err != nil { - return nil, errors.Wrap(err, "SnapshotsClient.Copy failure to grant snapshot access. Snapshot grant access poller failed to pull the result") + return nil, errors.Wrap(err, "SnapshotsClient.Copy failure to grant snapshot access") } + accessURI, err := snapshotsGrantAccessFuture.Result(*s.azCli.SnapshotsClient) if err != nil { return nil, errors.Wrap(err, "SnapshotsClient.Copy failure to grant snapshot access") } @@ -196,7 +209,7 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. Timeout: uint(time), } } - err = blob.Copy(*snapshotGrantRes.AccessSAS, copyOptions) + err = blob.Copy(*accessURI.AccessSAS, copyOptions) if err != nil { return nil, errors.Wrapf(err, "Failed to copy disk to blob") } @@ -215,15 +228,15 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. } tags = blockstorage.SanitizeTags(ktags.GetTags(tags)) - 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), + 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), }, }, } @@ -232,15 +245,20 @@ func (s *AdStorage) SnapshotCopyWithArgs(ctx context.Context, from blockstorage. if val, ok := args[blockstorage.AzureMigrateResourceGroup]; ok && val != "" { migrateResourceGroup = val } - createSnapshotPoller, err := s.azCli.SnapshotsClient.BeginCreateOrUpdate(ctx, migrateResourceGroup, snapName, createSnap, nil) + result, err := s.azCli.SnapshotsClient.CreateOrUpdate(ctx, migrateResourceGroup, snapName, createSnap) if err != nil { return nil, errors.Wrapf(err, "Failed to copy snapshot from source snapshot %v", from) } - createSnapRes, err := createSnapshotPoller.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) if err != nil { - return nil, errors.Wrap(err, "Poller failed to retrieve snapshot") + return nil, errors.Wrapf(err, "Failed to copy snapshot from source snapshot %v", from) } - snap, err := s.SnapshotGet(ctx, blockstorage.StringFromPtr(createSnapRes.ID)) + 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)) if err != nil { return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) } @@ -253,15 +271,7 @@ func isMigrateStorageAccountorKey(migrateStorageAccount, migrateStorageKey strin } func (s *AdStorage) revokeAccess(ctx context.Context, rg, name, ID string) { - 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()}) - } - + _, err := s.azCli.SnapshotsClient.RevokeAccess(ctx, rg, name) if err != nil { log.Print("Failed to revoke access from snapshot", field.M{"snapshot": ID}) } @@ -285,32 +295,36 @@ 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 := 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), + 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), }, }, } - pollerResp, err := s.azCli.SnapshotsClient.BeginCreateOrUpdate(ctx, s.azCli.ResourceGroup, snapName, createSnap, nil) + result, err := s.azCli.SnapshotsClient.CreateOrUpdate(ctx, s.azCli.ResourceGroup, snapName, createSnap) if err != nil { return nil, errors.Wrapf(err, "Failed to create snapshot for volume %v", volume) } - resp, err := pollerResp.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) if err != nil { - return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) + return nil, errors.Wrapf(err, "Failed to create snapshot for volume %v", volume) } - blockSnapshot, err := s.snapshotParse(ctx, resp.Snapshot) + rs, err := result.Result(*s.azCli.SnapshotsClient) if err != nil { - return nil, errors.Wrapf(err, "Failed to Parse Snapshot, snaphotName %s", snapName) + return nil, errors.Wrapf(err, "Error in getting result of Snapshot create operation, snaphotName %s", snapName) } - blockSnapshot.Volume = &volume - return blockSnapshot, nil + snap, err := s.SnapshotGet(ctx, azto.String(rs.ID)) + if err != nil { + return nil, errors.Wrapf(err, "Failed to Get Snapshot after create, snaphotName %s", snapName) + } + snap.Volume = &volume + return snap, nil } func (s *AdStorage) SnapshotCreateWaitForCompletion(ctx context.Context, snap *blockstorage.Snapshot) error { @@ -348,11 +362,12 @@ 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) } - poller, err := s.azCli.SnapshotsClient.BeginDelete(ctx, rg, name, nil) + result, err := s.azCli.SnapshotsClient.Delete(ctx, rg, name) if err != nil { return errors.Wrapf(err, "SnapshotClient.Delete: Failed to delete snapshot with ID %s", snapshot.ID) } - _, err = poller.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) + return errors.Wrapf(err, "SnapshotClient.Delete: Error while waiting for snapshot with ID %s to get deleted", snapshot.ID) } @@ -361,148 +376,95 @@ 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) } - snapRes, err := s.azCli.SnapshotsClient.Get(ctx, rg, name, nil) + snap, err := s.azCli.SnapshotsClient.Get(ctx, rg, name) if err != nil { return nil, errors.Wrapf(err, "SnapshotsClient.Get: Failed to get snapshot with ID %s", id) } - return s.snapshotParse(ctx, snapRes.Snapshot) + return s.snapshotParse(ctx, snap), nil } func (s *AdStorage) VolumeParse(ctx context.Context, volume interface{}) (*blockstorage.Volume, error) { - vol, ok := volume.(armcompute.Disk) + vol, ok := volume.(azcompute.Disk) if !ok { - return nil, errors.New(fmt.Sprintf("Volume is not of type *armcompute.Disk, volume: %v", volume)) + return nil, errors.New(fmt.Sprintf("Volume is not of type *azcompute.Disk, volume: %v", volume)) } encrypted := false - if vol.Properties.EncryptionSettingsCollection != nil && - vol.Properties.EncryptionSettingsCollection.Enabled != nil { - encrypted = *vol.Properties.EncryptionSettingsCollection.Enabled + if vol.DiskProperties.EncryptionSettingsCollection != nil && + vol.DiskProperties.EncryptionSettingsCollection.Enabled != nil { + encrypted = *vol.DiskProperties.EncryptionSettingsCollection.Enabled } tags := map[string]string{"": ""} if vol.Tags != nil { - tags = blockstorage.StringMap(vol.Tags) + tags = azto.StringMap(vol.Tags) } - az := blockstorage.StringFromPtr(vol.Location) - 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) + az := azto.String(vol.Location) + if z := azto.StringSlice(vol.Zones); len(z) > 0 { + az = az + "-" + z[0] } return &blockstorage.Volume{ Type: s.Type(), - ID: volId, + ID: azto.String(vol.ID), Encrypted: encrypted, - SizeInBytes: diskSize, + SizeInBytes: azto.Int64(vol.DiskSizeBytes), Az: az, Tags: blockstorage.MapToKeyValue(tags), - VolumeType: volumeType, - CreationTime: blockstorage.TimeStamp(creationTime), - Attributes: map[string]string{"Users": managedBy}, + VolumeType: string(vol.Sku.Name), + CreationTime: blockstorage.TimeStamp(vol.DiskProperties.TimeCreated.ToTime()), + Attributes: map[string]string{"Users": azto.String(vol.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) + if snap, ok := snapshot.(azcompute.Snapshot); ok { + return s.snapshotParse(ctx, snap), nil } - return nil, errors.New(fmt.Sprintf("Snapshot is not of type *armcompute.Snapshot, snapshot: %v", snapshot)) + return nil, errors.New(fmt.Sprintf("Snapshot is not of type *azcompute.Snapshot, snapshot: %v", 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") - } +func (s *AdStorage) snapshotParse(ctx context.Context, snap azcompute.Snapshot) *blockstorage.Snapshot { vol := &blockstorage.Volume{ Type: s.Type(), - ID: snapId, - } - - snapCreationTime := time.Now() - if snap.Properties != nil && snap.Properties.TimeCreated != nil { - snapCreationTime = *snap.Properties.TimeCreated + ID: azto.String(snap.SnapshotProperties.CreationData.SourceResourceID), } + snapCreationTime := *snap.TimeCreated encrypted := false - if snap.Properties.EncryptionSettingsCollection != nil && - snap.Properties.EncryptionSettingsCollection.Enabled != nil { - encrypted = *snap.Properties.EncryptionSettingsCollection.Enabled + if snap.SnapshotProperties.EncryptionSettingsCollection != nil && + snap.SnapshotProperties.EncryptionSettingsCollection.Enabled != nil { + encrypted = *snap.SnapshotProperties.EncryptionSettingsCollection.Enabled } tags := map[string]string{} 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 + tags = azto.StringMap(snap.Tags) } return &blockstorage.Snapshot{ Encrypted: encrypted, - ID: snapId, - Region: region, - SizeInBytes: blockstorage.Int64(diskSize), + ID: azto.String(snap.ID), + Region: azto.String(snap.Location), + SizeInBytes: azto.Int64(snap.SnapshotProperties.DiskSizeBytes), Tags: blockstorage.MapToKeyValue(tags), Type: s.Type(), Volume: vol, - CreationTime: blockstorage.TimeStamp(snapCreationTime), - }, nil + CreationTime: blockstorage.TimeStamp(snapCreationTime.ToTime()), + } } func (s *AdStorage) VolumesList(ctx context.Context, tags map[string]string, zone string) ([]*blockstorage.Volume, error) { var vols []*blockstorage.Volume // (ilya): It looks like azure doesn't support search by tags // List does listing per Subscription - pager := s.azCli.DisksClient.NewListPager(nil) - for pager.More() { - page, err := pager.NextPage(ctx) + for diskList, err := s.azCli.DisksClient.ListComplete(ctx); diskList.NotDone(); err = diskList.Next() { if err != nil { return nil, errors.Wrap(err, "DisksClient.List in VolumesList") } - 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) + 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") } + vols = append(vols, vol) } return vols, nil } @@ -511,20 +473,17 @@ 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 - pager := s.azCli.SnapshotsClient.NewListPager(nil) - for pager.More() { - page, err := pager.NextPage(ctx) + for snapList, err := s.azCli.SnapshotsClient.ListComplete(ctx); snapList.NotDone(); err = snapList.Next() { if err != nil { return nil, errors.Wrap(err, "SnapshotsClient.List in SnapshotsList") } - 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) + 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 } + snaps = append(snaps, k10Snap) } snaps = blockstorage.FilterSnapshotsWithTags(snaps, blockstorage.SanitizeTags(tags)) return snaps, nil @@ -550,36 +509,39 @@ func (s *AdStorage) VolumeCreateFromSnapshot(ctx context.Context, snapshot block } diskName := fmt.Sprintf(volumeNameFmt, diskId.String()) tags = blockstorage.SanitizeTags(tags) - 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), + 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), }, }, } if id != "" { - createDisk.Zones = blockstorage.SliceStringPtr([]string{id}) + createDisk.Zones = azto.StringSlicePtr([]string{id}) } - for _, saType := range armcompute.PossibleDiskStorageAccountTypesValues() { + for _, saType := range azcompute.PossibleDiskStorageAccountTypesValues() { if string(saType) == snapshot.Volume.VolumeType { - createDisk.SKU = &armcompute.DiskSKU{ - Name: azto.Ptr(saType), + createDisk.Sku = &azcompute.DiskSku{ + Name: saType, } } } - poller, err := s.azCli.DisksClient.BeginCreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createDisk, nil) + result, err := s.azCli.DisksClient.CreateOrUpdate(ctx, s.azCli.ResourceGroup, diskName, createDisk) if err != nil { return nil, errors.Wrapf(err, "DiskCLient.CreateOrUpdate in VolumeCreateFromSnapshot, diskName: %s, snapshotID: %s", diskName, snapshot.ID) } - resp, err := poller.PollUntilDone(ctx, nil) - if err != nil { + 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) } - return s.VolumeParse(ctx, resp.Disk) + disk, err := result.Result(*s.azCli.DisksClient) + if err != nil { + return nil, err + } + return s.VolumeGet(ctx, azto.String(disk.ID), snapshot.Volume.Az) } func (s *AdStorage) getRegionAndZoneID(ctx context.Context, sourceRegion, volAz string) (string, string, error) { @@ -632,19 +594,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, nil) + snap, err := s.azCli.SnapshotsClient.Get(ctx, rg, name) if err != nil { return errors.Wrapf(err, "SnapshotsClient.Get in SetTags, snapshotID: %s", res.ID) } - tags = ktags.AddMissingTags(blockstorage.StringMap(snap.Tags), ktags.GetTags(tags)) - snapProperties := armcompute.SnapshotUpdate{ - Tags: *blockstorage.StringMapPtr(blockstorage.SanitizeTags(tags)), + tags = ktags.AddMissingTags(azto.StringMap(snap.Tags), ktags.GetTags(tags)) + snapProperties := azcompute.SnapshotUpdate{ + Tags: *azto.StringMapPtr(blockstorage.SanitizeTags(tags)), } - poller, err := s.azCli.SnapshotsClient.BeginUpdate(ctx, rg, name, snapProperties, nil) + result, err := s.azCli.SnapshotsClient.Update(ctx, rg, name, snapProperties) if err != nil { return errors.Wrapf(err, "SnapshotsClient.Update in SetTags, snapshotID: %s", name) } - _, err = poller.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.SnapshotsClient.Client) return errors.Wrapf(err, "SnapshotsClient.Update in SetTags, snapshotID: %s", name) } case *blockstorage.Volume: @@ -653,20 +615,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, nil) + vol, err := s.azCli.DisksClient.Get(ctx, rg, volID) if err != nil { return errors.Wrapf(err, "DiskClient.Get in SetTags, volumeID: %s", volID) } - tags = ktags.AddMissingTags(blockstorage.StringMap(vol.Tags), ktags.GetTags(tags)) + tags = ktags.AddMissingTags(azto.StringMap(vol.Tags), ktags.GetTags(tags)) - diskProperties := armcompute.DiskUpdate{ - Tags: *blockstorage.StringMapPtr(blockstorage.SanitizeTags(tags)), + diskProperties := azcompute.DiskUpdate{ + Tags: *azto.StringMapPtr(blockstorage.SanitizeTags(tags)), } - poller, err := s.azCli.DisksClient.BeginUpdate(ctx, rg, volID, diskProperties, nil) + result, err := s.azCli.DisksClient.Update(ctx, rg, volID, diskProperties) if err != nil { return errors.Wrapf(err, "DiskClient.Update in SetTags, volumeID: %s", volID) } - _, err = poller.PollUntilDone(ctx, nil) + err = result.WaitForCompletionRef(ctx, s.azCli.DisksClient.Client) return errors.Wrapf(err, "DiskClient.Update in SetTags, volumeID: %s", volID) } default: @@ -716,38 +678,39 @@ 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 := s.azCli.SubscriptionsClient - regionMap := make(map[string]LocationZoneMap) - - 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") - } - for _, location := range page.Value { - if location != nil && location.Name != nil { - regionMap[*location.Name] = make(LocationZoneMap) - } else { - continue - } - } + 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{}) } - 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) + 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 + } } } + if err = skuResults.NextWithContext(ctx); err != nil { + return nil, err + } } + // convert to map of []string regionMapResult := make(map[string][]string) for region, zoneSet := range regionMap { @@ -759,21 +722,3 @@ 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 { - 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[location] = val - } - } -} diff --git a/pkg/blockstorage/azure/client.go b/pkg/blockstorage/azure/client.go index 79c5413f7d..86589b8af6 100644 --- a/pkg/blockstorage/azure/client.go +++ b/pkg/blockstorage/azure/client.go @@ -21,34 +21,26 @@ 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/Azure/azure-sdk-for-go/services/compute/mgmt/2019-03-01/compute" + "github.com/Azure/go-autorest/autorest" + "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" ) -// Client is a wrapper +// Client is a wrapper for Client client type Client struct { - Cred azcore.TokenCredential - SubscriptionID string - ResourceGroup string - BaseURI string - DisksClient *armcompute.DisksClient - SnapshotsClient *armcompute.SnapshotsClient - SKUsClient *armcompute.ResourceSKUsClient - SubscriptionsClient *armsubscriptions.Client + SubscriptionID string + ResourceGroup string + BaseURI string + Authorizer *autorest.BearerAuthorizer + DisksClient *compute.DisksClient + SnapshotsClient *compute.SnapshotsClient } // 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 @@ -73,62 +65,94 @@ func NewClient(ctx context.Context, config map[string]string) (*Client, error) { } } - authenticator, err := NewAzureAuthenticator(config) - if err != nil { - return nil, err + if id, ok := config[blockstorage.AzureCloudEnvironmentID]; !ok || id == "" { + config[blockstorage.AzureCloudEnvironmentID] = azure.PublicCloud.Name } - err = authenticator.Authenticate(config) + + env, err := azure.EnvironmentFromName(config[blockstorage.AzureCloudEnvironmentID]) if err != nil { - return nil, err + return nil, errors.Wrap(err, "Failed to fetch the cloud environment.") } - cred := authenticator.GetAuthorizer() - computeClientFactory, err = armcompute.NewClientFactory(subscriptionID, cred, nil) + + authorizer, err := getAuthorizer(env, config) if err != nil { return nil, err } - subscriptionsClientFactory, err = armsubscriptions.NewClientFactory(cred, nil) - - if err != nil { - return nil, err + _, ok = config[blockstorage.AzureResurceMgrEndpoint] + if !ok { + config[blockstorage.AzureResurceMgrEndpoint] = env.ResourceManagerEndpoint } - disksClient := computeClientFactory.NewDisksClient() - snapshotsClient := computeClientFactory.NewSnapshotsClient() - skusClient := computeClientFactory.NewResourceSKUsClient() - subscriptionsClient := subscriptionsClientFactory.NewClient() + disksClient := compute.NewDisksClientWithBaseURI(config[blockstorage.AzureResurceMgrEndpoint], subscriptionID) + disksClient.Authorizer = authorizer - if err != nil { - return nil, err - } + snapshotsClient := compute.NewSnapshotsClientWithBaseURI(config[blockstorage.AzureResurceMgrEndpoint], subscriptionID) + snapshotsClient.Authorizer = authorizer return &Client{ - Cred: cred, - BaseURI: config[blockstorage.AzureResurceMgrEndpoint], - SubscriptionID: subscriptionID, - DisksClient: disksClient, - SnapshotsClient: snapshotsClient, - SKUsClient: skusClient, - SubscriptionsClient: subscriptionsClient, - ResourceGroup: resourceGroup, + BaseURI: config[blockstorage.AzureResurceMgrEndpoint], + SubscriptionID: subscriptionID, + Authorizer: authorizer, + DisksClient: &disksClient, + SnapshotsClient: &snapshotsClient, + ResourceGroup: resourceGroup, }, nil } -func getCredConfig(env Environment, config map[string]string) (ClientCredentialsConfig, error) { - credConfig, err := getCredConfigForAuth(config) +//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") +} + +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 ba, nil +} + +func getMSIsAuthorizer(config map[string]string) (*autorest.BearerAuthorizer, error) { + msiConfig := auth.NewMSIConfig() + msiConfig.ClientID = config[blockstorage.AzureClientID] + a, err := msiConfig.Authorizer() if err != nil { - return ClientCredentialsConfig{}, err + 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 ba, nil +} - //Todo: Find alternatives to azure.Environment +func getCredConfig(env azure.Environment, config map[string]string) (auth.ClientCredentialsConfig, error) { + credConfig, err := getCredConfigForAuth(config) + if err != nil { + return auth.ClientCredentialsConfig{}, err + } var ok bool if credConfig.AADEndpoint, ok = config[blockstorage.AzureActiveDirEndpoint]; !ok || credConfig.AADEndpoint == "" { - credConfig.AADEndpoint = env.Configuration.ActiveDirectoryAuthorityHost + credConfig.AADEndpoint = env.ActiveDirectoryEndpoint config[blockstorage.AzureActiveDirEndpoint] = credConfig.AADEndpoint } if credConfig.Resource, ok = config[blockstorage.AzureActiveDirResourceID]; !ok || credConfig.Resource == "" { - credConfig.Resource = env.Configuration.Services[cloud.ResourceManager].Endpoint + credConfig.Resource = env.ResourceManagerEndpoint config[blockstorage.AzureActiveDirResourceID] = credConfig.Resource } diff --git a/pkg/blockstorage/azure/client_test.go b/pkg/blockstorage/azure/client_test.go index 72970dc6f5..a49c1be597 100644 --- a/pkg/blockstorage/azure/client_test.go +++ b/pkg/blockstorage/azure/client_test.go @@ -20,11 +20,11 @@ import ( "strings" "testing" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" - . "gopkg.in/check.v1" - + "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" ) // Hook up gocheck into the "go test" runner. @@ -48,13 +48,12 @@ 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.Authorizer, NotNil) c.Assert(azCli.DisksClient, NotNil) c.Assert(azCli.SnapshotsClient, NotNil) - c.Assert(azCli.DisksClient.NewListPager(nil), NotNil) - c.Assert(azCli.SKUsClient, NotNil) - c.Assert(azCli.SubscriptionsClient, NotNil) + _, err = azCli.DisksClient.List(context.Background()) c.Assert(err, IsNil) } @@ -88,15 +87,13 @@ func (s ClientSuite) TestGetRegions(c *C) { func (s *ClientSuite) TestGetCredConfig(c *C) { for _, tc := range []struct { - name string - env Environment + env azure.Environment config map[string]string errChecker Checker - expCCC ClientCredentialsConfig + expCCC auth.ClientCredentialsConfig }{ { - name: "Test with all attributes in configuration", - env: PublicCloud, + env: azure.PublicCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -104,7 +101,7 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { blockstorage.AzureActiveDirEndpoint: "aade", blockstorage.AzureActiveDirResourceID: "aadrid", }, - expCCC: ClientCredentialsConfig{ + expCCC: auth.ClientCredentialsConfig{ ClientID: "acid", ClientSecret: "acs", TenantID: "atid", @@ -114,25 +111,23 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: IsNil, }, { - name: "Test with client credential in configuration", - env: PublicCloud, + env: azure.PublicCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", blockstorage.AzureClientSecret: "acs", }, - expCCC: ClientCredentialsConfig{ + expCCC: auth.ClientCredentialsConfig{ ClientID: "acid", ClientSecret: "acs", TenantID: "atid", - Resource: cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint, - AADEndpoint: cloud.AzurePublic.ActiveDirectoryAuthorityHost, + Resource: azure.PublicCloud.ResourceManagerEndpoint, + AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, }, errChecker: IsNil, }, { - name: "Test without AD in configuration", - env: USGovernmentCloud, + env: azure.USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -140,18 +135,17 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { blockstorage.AzureActiveDirEndpoint: "", blockstorage.AzureActiveDirResourceID: "", }, - expCCC: ClientCredentialsConfig{ + expCCC: auth.ClientCredentialsConfig{ ClientID: "acid", ClientSecret: "acs", TenantID: "atid", - Resource: cloud.AzureGovernment.Services[cloud.ResourceManager].Endpoint, - AADEndpoint: cloud.AzureGovernment.ActiveDirectoryAuthorityHost, + Resource: azure.USGovernmentCloud.ResourceManagerEndpoint, + AADEndpoint: azure.USGovernmentCloud.ActiveDirectoryEndpoint, }, errChecker: IsNil, }, { - name: "Test with tenantid and clientid in configuration", - env: USGovernmentCloud, + env: azure.USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", blockstorage.AzureClientID: "acid", @@ -159,16 +153,14 @@ func (s *ClientSuite) TestGetCredConfig(c *C) { errChecker: NotNil, }, { - name: "Test with tenantid in configuration", - env: USGovernmentCloud, + env: azure.USGovernmentCloud, config: map[string]string{ blockstorage.AzureTenantID: "atid", }, errChecker: NotNil, }, { - name: "Test with nil configuration", - env: USGovernmentCloud, + env: azure.USGovernmentCloud, config: map[string]string{}, errChecker: NotNil, }, diff --git a/pkg/blockstorage/azure/environments.go b/pkg/blockstorage/azure/environments.go deleted file mode 100644 index 181c8b45c5..0000000000 --- a/pkg/blockstorage/azure/environments.go +++ /dev/null @@ -1,98 +0,0 @@ -// 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 ( - "fmt" - "strings" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" -) - -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/blockstorage/helper_test.go b/pkg/blockstorage/helper_test.go deleted file mode 100644 index f3db25f422..0000000000 --- a/pkg/blockstorage/helper_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// 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 ( - . "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) 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) 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) 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 ae28929b2f..20ea680d19 100644 --- a/pkg/blockstorage/helpers.go +++ b/pkg/blockstorage/helpers.go @@ -17,8 +17,6 @@ package blockstorage import ( "bytes" - azto "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" - ktags "github.com/kanisterio/kanister/pkg/blockstorage/tags" ) @@ -107,94 +105,3 @@ 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 -} - -// 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 -} - -// 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 -} - -// String returns a string value for the passed string pointer. It returns the empty string if the -// pointer is nil. -func StringFromPtr(s *string) string { - if s != nil { - return *s - } - return "" -} - -// StringPtr returns a pointer to the passed string. -func StringPtr(s string) *string { - return &s -} diff --git a/pkg/kopia/command/storage/secret_utils.go b/pkg/kopia/command/storage/secret_utils.go index 71fa20183c..1935f7354b 100644 --- a/pkg/kopia/command/storage/secret_utils.go +++ b/pkg/kopia/command/storage/secret_utils.go @@ -16,10 +16,11 @@ package storage import ( "context" - "github.com/kanisterio/kanister/pkg/blockstorage/azure" + "time" + + "github.com/Azure/go-autorest/autorest/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"