diff --git a/go.mod b/go.mod index 58cef96..6a48cd9 100644 --- a/go.mod +++ b/go.mod @@ -3,30 +3,34 @@ module github.com/vmware-tanzu/velero-plugin-for-microsoft-azure go 1.18 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.6.1 + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 github.com/gofrs/uuid v4.3.1+incompatible - github.com/joho/godotenv v1.4.0 github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.9.0 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.8.2 - github.com/vmware-tanzu/velero v0.0.0-20230727074327-a6d79fc272a2 + github.com/stretchr/testify v1.8.4 + github.com/vmware-tanzu/velero v1.10.0 k8s.io/api v0.26.0 k8s.io/apimachinery v0.26.0 sigs.k8s.io/azuredisk-csi-driver v1.26.0 ) +require ( + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0 // indirect + github.com/joho/godotenv v1.4.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect +) + require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/fatih/color v1.15.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -47,7 +51,7 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -58,17 +62,16 @@ require ( github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cobra v1.6.1 // indirect github.com/stretchr/objx v0.5.0 // indirect - golang.org/x/crypto v0.8.0 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sys v0.7.0 // indirect - golang.org/x/term v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/net v0.11.0 // indirect + golang.org/x/oauth2 v0.9.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/term v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.54.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/grpc v1.56.1 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -86,5 +89,7 @@ require ( // * go list -modfile=go.mod -m -json -mod=mod all: k8s.io/kubectl@v0.0.0: invalid version: unknown revision v0.0.0 replace ( cloud.google.com/go => cloud.google.com/go v0.104.0 + // TODO update after the Velero PR merged + github.com/vmware-tanzu/velero => github.com/ywk253100/velero v0.0.8 k8s.io/kubectl => k8s.io/kubectl v0.25.2 ) diff --git a/go.sum b/go.sum index eae8a39..70b7aad 100644 --- a/go.sum +++ b/go.sum @@ -11,21 +11,21 @@ cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= github.com/Azure/azure-sdk-for-go v67.2.0+incompatible h1:Uu/Ww6ernvPTrpq31kITVTIm/I5jlJ1wjtEH/bmSB2k= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 h1:SEy2xmstIphdPwNBUi7uhvjyjhVKISfwjfOJmuy7kg4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0 h1:/Di3vB4sNeQ+7A8efjUVENvyB945Wruvstucqp7ZArg= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0/go.mod h1:gM3K25LQlsET3QR+4V74zxCsFAy0r6xMNN9n80SZn+4= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0 h1:lMW1lD/17LUA5z1XTURo7LcVG2ICBPlyMHjIUrcFZNQ= +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/network/armnetwork v1.0.0 h1:nBy98uKOIfun5z6wx6jwWLrULcM0+cjBalBFZlEZ7CA= 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/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 v0.6.1 h1:YvQv9Mz6T8oR5ypQOL6erY0Z5t71ak1uHV4QFokCOZk= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.6.1/go.mod h1:c6WvOhtmjNUWbLfOG1qxM/q0SPvQNSVJvolm+C52dIU= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0 h1:LcJtQjCXJUm1s7JpUHZvu+bpgURhCatxVNbGADXniX0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0/go.mod h1:+OgGVo0Httq7N5oayfvaLQ/Jq+2gJdqfp++Hyyl7Tws= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -71,8 +71,8 @@ github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBD github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= @@ -183,8 +183,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -209,8 +209,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= @@ -232,16 +232,16 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 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 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/vmware-tanzu/velero v0.0.0-20230727074327-a6d79fc272a2 h1:9gv429q/2bu75G/agjXDPfwHdZCDDcyH91ryxFx/rb4= -github.com/vmware-tanzu/velero v0.0.0-20230727074327-a6d79fc272a2/go.mod h1:nf1mFikxiN+rhWqpXe38Ut4xyh5ETqdbtk8Byh3+hDg= +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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/ywk253100/velero v0.0.8 h1:tL4ULnbzr6oFsNGRsXPC8TyLYhN4Qx2t2uq6wapOTUw= +github.com/ywk253100/velero v0.0.8/go.mod h1:dJQuhpPZtv6ny5D0QYUd/IGToOnVnjAo9ci7QZ/CjBI= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= @@ -252,8 +252,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= -golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -293,8 +293,8 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -308,8 +308,8 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= -golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= +golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs= +golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -362,12 +362,13 @@ golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -375,8 +376,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 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.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -459,8 +460,8 @@ google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljW google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -483,8 +484,8 @@ google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11 google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc v1.56.1 h1:z0dNfjIl0VpaZ9iSVjA6daGatAYwPGstTjt5vkRMFkQ= +google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -501,8 +502,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/velero-plugin-for-microsoft-azure/common.go b/velero-plugin-for-microsoft-azure/common.go deleted file mode 100644 index accceec..0000000 --- a/velero-plugin-for-microsoft-azure/common.go +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright the Velero contributors. - -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 main - -import ( - "fmt" - "os" - "strings" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" - "github.com/joho/godotenv" - "github.com/pkg/errors" -) - -const ( - subscriptionIDEnvVar = "AZURE_SUBSCRIPTION_ID" - cloudNameEnvVar = "AZURE_CLOUD_NAME" - - resourceGroupConfigKey = "resourceGroup" - credentialsFileConfigKey = "credentialsFile" - subscriptionIDConfigKey = "subscriptionId" - - Storage cloud.ServiceName = "BlobStorage" -) - -// credentialsFileFromEnv retrieves the Azure credentials file from the environment. -func credentialsFileFromEnv() string { - return os.Getenv("AZURE_CREDENTIALS_FILE") -} - -// selectCredentialsFile selects the Azure credentials file to use, retrieving it -// from the given config or falling back to retrieving it from the environment. -func selectCredentialsFile(config map[string]string) (string, error) { - if credentialsFile, ok := config[credentialsFileConfigKey]; ok { - // Check that the provided credentialsFile exists on disk - if _, err := os.Stat(credentialsFile); err != nil { - if os.IsNotExist(err) { - return "", errors.Wrapf(err, "provided credentialsFile does not exist") - } - return "", errors.Wrapf(err, "could not get credentialsFile info") - } - return credentialsFile, nil - } - - return credentialsFileFromEnv(), nil -} - -// loadCredentialsIntoEnv loads the variables in the given credentials -// file into the current environment. -func loadCredentialsIntoEnv(credentialsFile string) error { - if credentialsFile == "" { - return nil - } - - if err := godotenv.Overload(credentialsFile); err != nil { - return errors.Wrapf(err, "error loading environment from credentials file (%s)", credentialsFile) - } - - return nil -} - -// map cloud names from go-autorest to cloud config from azure-sdk -// add the storage endpoint -func cloudFromName(cloudName string) (cloud.Configuration, error) { - fmt.Println(cloudName) - switch strings.ToUpper(cloudName) { - case "AZURECHINACLOUD": - config := cloud.AzureChina - config.Services[Storage] = cloud.ServiceConfiguration{ - Endpoint: "core.chinacloudapi.cn", - } - return config, nil - case "", "AZURECLOUD", "AZUREPUBLICCLOUD": - config := cloud.AzurePublic - config.Services[Storage] = cloud.ServiceConfiguration{ - Endpoint: "core.windows.net", - } - return config, nil - case "AZUREUSGOVERNMENT", "AZUREUSGOVERNMENTCLOUD": - config := cloud.AzureGovernment - config.Services[Storage] = cloud.ServiceConfiguration{ - Endpoint: "core.usgovcloudapi.net", - } - return config, nil - default: - return cloud.Configuration{}, fmt.Errorf("there is no cloud matching the name %q", cloudName) - } -} - -func getRequiredValues(getValue func(string) string, keys ...string) (map[string]string, error) { - missing := []string{} - results := map[string]string{} - - for _, key := range keys { - if val := getValue(key); val == "" { - missing = append(missing, key) - } else { - results[key] = val - } - } - - if len(missing) > 0 { - return nil, errors.Errorf("the following keys do not have values: %s", strings.Join(missing, ", ")) - } - - return results, nil -} - -func mapLookup(data map[string]string) func(string) string { - return func(key string) string { - return data[key] - } -} diff --git a/velero-plugin-for-microsoft-azure/common_test.go b/velero-plugin-for-microsoft-azure/common_test.go deleted file mode 100644 index 8c075eb..0000000 --- a/velero-plugin-for-microsoft-azure/common_test.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright the Velero contributors. - -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 main - -import ( - "testing" - - "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud" - "github.com/stretchr/testify/assert" -) - -func TestCloud(t *testing.T) { - cloudConfig, err := cloudFromName("AzureChinaCloud") - if err != nil { - t.Fatal(err) - } - assert.Equal(t, "core.chinacloudapi.cn", cloudConfig.Services[Storage].Endpoint) - assert.Equal(t, "https://management.chinacloudapi.cn", cloudConfig.Services[cloud.ResourceManager].Endpoint) -} - -func TestCloudDefault(t *testing.T) { - cloudConfig, err := cloudFromName("") - if err != nil { - t.Fatal(err) - } - assert.Equal(t, "core.windows.net", cloudConfig.Services[Storage].Endpoint) -} diff --git a/velero-plugin-for-microsoft-azure/object_store.go b/velero-plugin-for-microsoft-azure/object_store.go index 26896b1..4670ab8 100644 --- a/velero-plugin-for-microsoft-azure/object_store.go +++ b/velero-plugin-for-microsoft-azure/object_store.go @@ -21,18 +21,11 @@ import ( "context" "fmt" "io" - "os" "strconv" - "strings" "time" - "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/azcore/runtime" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" - "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob" @@ -43,16 +36,11 @@ import ( "github.com/sirupsen/logrus" veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/util/azure" ) const ( - storageAccountConfigKey = "storageAccount" - storageAccountKeyEnvVarConfigKey = "storageAccountKeyEnvVar" - blockSizeConfigKey = "blockSizeInBytes" - storageAccountURIConfigKey = "storageAccountURI" - useAADConfigKey = "useAAD" - activeDirectoryAuthorityURIConfigKey = "activeDirectoryAuthorityURI" - + blockSizeConfigKey = "blockSizeInBytes" // blocks must be less than/equal to 100MB in size // ref. https://docs.microsoft.com/en-us/rest/api/storageservices/put-block#uri-parameters defaultBlockSize = 100 * 1024 * 1024 @@ -218,7 +206,6 @@ type ObjectStore struct { containerGetter containerGetter blobGetter blobGetter blockSize int - storageAccount string // we need to keep the credential here to create the sas url sharedKeyCredential *azblob.SharedKeyCredential } @@ -227,174 +214,34 @@ func newObjectStore(logger logrus.FieldLogger) *ObjectStore { return &ObjectStore{log: logger} } -// get storage account key from env var whose name is in config[storageAccountKeyEnvVarConfigKey]. -func getStorageAccountKey(config map[string]string) (string, error) { - secretKeyEnvVar := config[storageAccountKeyEnvVarConfigKey] - if secretKeyEnvVar != "" { - return os.Getenv(secretKeyEnvVar), nil - } - - return "", nil -} - -func populateEnvVarsFromCredentialsFile(config map[string]string) error { - credentialsFile, err := selectCredentialsFile(config) - if err != nil { - return err - } - if err := loadCredentialsIntoEnv(credentialsFile); err != nil { - return err - } - return nil -} - -// getServiceClient creates a client via SharedKeyCredential or DefaultAzureCredential -func getServiceClient(storageAccount, subscription, resouceGroup string, storageAccountURI string, useAAD string, sharedKeyCredential *azblob.SharedKeyCredential, cloud cloud.Configuration, log logrus.FieldLogger) (*service.Client, *azblob.SharedKeyCredential, error) { - localSharedKeyCredential := sharedKeyCredential - clientOptions := policy.ClientOptions{Cloud: cloud} - var serviceClient *service.Client - - credential, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{ClientOptions: policy.ClientOptions{Cloud: cloud}}) - if err != nil { - return nil, nil, errors.Wrap(err, "error getting credentials from environment") - } - serviceURL := getBlobServicUrl(credential, clientOptions, subscription, resouceGroup, storageAccount, storageAccountURI, cloud.Services[Storage].Endpoint, log) - if sharedKeyCredential == nil { - // doc: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/azidentity - if strings.ToLower(useAAD) == "true" { - serviceClient, err = service.NewClient(serviceURL, credential, &service.ClientOptions{ClientOptions: clientOptions}) - return serviceClient, nil, errors.Wrapf(err, "error creating service client with AAD credentials for storage account %s", serviceURL) - } - - // else fetch the storage account key - storageAccountKey, err := fetchStorageAccountKey(credential, clientOptions, subscription, resouceGroup, storageAccount) - if err != nil { - return nil, nil, err - } - localSharedKeyCredential, err = azblob.NewSharedKeyCredential(storageAccount, storageAccountKey) - if err != nil { - return nil, nil, err - } - - } - serviceClient, err = service.NewClientWithSharedKeyCredential(serviceURL, localSharedKeyCredential, &service.ClientOptions{ClientOptions: clientOptions}) - return serviceClient, localSharedKeyCredential, err -} - -func getBlobServicUrl(credential *azidentity.DefaultAzureCredential, clientOptions policy.ClientOptions, subscription, resouceGroup, storageAccount, storageAccountURI, defaultStorageEndpointSuffix string, log logrus.FieldLogger) string { - // We pass in Uri, since we might need to validate this in future against GetProperties. - if storageAccountURI != "" { - return storageAccountURI - } - accountClient, err := armstorage.NewAccountsClient(subscription, credential, &arm.ClientOptions{ClientOptions: clientOptions}) - if err != nil { - log.Debugf("error creating storage account client: %v, falling back to default SA URL forming mechanism", err) - } else { - properties, err := accountClient.GetProperties(context.TODO(), resouceGroup, storageAccount, nil) - if err != nil { - log.Debugf("error getting storage account properties: %v, please provide Microsoft.Storage/storageAccounts/read, falling back to default SA URL forming mechanism", err) - } else { - return *properties.Account.Properties.PrimaryEndpoints.Blob - } - } - - // fallback to default endpoint - return fmt.Sprintf("https://%s.blob.%s", storageAccount, defaultStorageEndpointSuffix) -} - -// fetch the storage account key using the default credential. -// this is deprecated and will be removed in a future release. -func fetchStorageAccountKey(credential *azidentity.DefaultAzureCredential, clientOptions policy.ClientOptions, subscription, resouceGroup, storageAccount string) (string, error) { - accountClient, err := armstorage.NewAccountsClient(subscription, credential, &arm.ClientOptions{ClientOptions: clientOptions}) - if err != nil { - return "", err - } - - res, err := accountClient.ListKeys(context.TODO(), resouceGroup, storageAccount, nil) - if err != nil { - return "", err - } - - for _, key := range res.Keys { - // ignore case for comparison because the ListKeys call returns e.g. "FULL" but - // the armstorage.KeyPermissionFull constant in the SDK is defined as "Full". - if strings.EqualFold(string(*key.Permissions), string(armstorage.KeyPermissionFull)) { - return *key.Value, nil - } - } - return "", errors.New("No storage key with Full permissions found") -} - // Init sets up the ObjectStore using the shared key or default azure credentials func (o *ObjectStore) Init(config map[string]string) error { - var serviceClient *service.Client if err := veleroplugin.ValidateObjectStoreConfigKeys(config, - resourceGroupConfigKey, - storageAccountConfigKey, - subscriptionIDConfigKey, + azure.BSLConfigResourceGroup, + azure.BSLConfigStorageAccount, + azure.BSLConfigSubscriptionID, blockSizeConfigKey, - storageAccountURIConfigKey, - useAADConfigKey, - activeDirectoryAuthorityURIConfigKey, - storageAccountKeyEnvVarConfigKey, + azure.BSLConfigActiveDirectoryAuthorityURI, + azure.BSLConfigStorageAccountURI, + azure.BSLConfigUseAAD, + azure.BSLConfigStorageAccountAccessKeyName, credentialsFileConfigKey, ); err != nil { return err } - if err := populateEnvVarsFromCredentialsFile(config); err != nil { - return err - } - - if config[storageAccountConfigKey] == "" { - return errors.Errorf("%s not defined", storageAccountConfigKey) - } - o.storageAccount = config[storageAccountConfigKey] - - // get Azure cloud from AZURE_CLOUD_NAME, if it exists. If the env var does not - // exist, parseAzureEnvironment will return azure.PublicCloud. - cloudConfig, err := cloudFromName(os.Getenv(cloudNameEnvVar)) - if err != nil { - return errors.Wrap(err, "unable to parse azure cloud name environment variable") - } - - // Update active directory authority host if it is set in the configuration - if config[activeDirectoryAuthorityURIConfigKey] != "" && config[useAADConfigKey] == "true" { - cloudConfig.ActiveDirectoryAuthorityHost = config[activeDirectoryAuthorityURIConfigKey] - } - - o.log.Debugf("Getting storage key") - // optional - storageAccountKey, err := getStorageAccountKey(config) - if err != nil { - o.log.Warnf("Couldn't load storage key: %s", err) - } - if storageAccountKey != "" { - o.sharedKeyCredential, err = azblob.NewSharedKeyCredential(o.storageAccount, storageAccountKey) - if err != nil { - return err - } - } - - o.log.Debugf("Creating service client") - subscriptionID := config[subscriptionIDConfigKey] - if len(subscriptionID) == 0 { - subscriptionID = os.Getenv(subscriptionIDEnvVar) - } - serviceClient, o.sharedKeyCredential, err = getServiceClient(o.storageAccount, subscriptionID, config[resourceGroupConfigKey], config[storageAccountURIConfigKey], config[useAADConfigKey], o.sharedKeyCredential, cloudConfig, o.log) + client, cred, err := azure.NewStorageClient(o.log, config) if err != nil { return err } + o.sharedKeyCredential = cred o.containerGetter = &azureContainerGetter{ - serviceClient: serviceClient, + serviceClient: client.ServiceClient(), } o.blobGetter = &azureBlobGetter{ - serviceClient: serviceClient, + serviceClient: client.ServiceClient(), } - - o.log.Infof("Using storage account key: %t", o.sharedKeyCredential != nil) - o.log.Debugf("Getting blocksize") o.blockSize = getBlockSize(o.log, config) return nil } diff --git a/velero-plugin-for-microsoft-azure/object_store_test.go b/velero-plugin-for-microsoft-azure/object_store_test.go index 7457305..c9d2d10 100644 --- a/velero-plugin-for-microsoft-azure/object_store_test.go +++ b/velero-plugin-for-microsoft-azure/object_store_test.go @@ -21,10 +21,8 @@ import ( "testing" "time" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob" - azcontainer "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -140,26 +138,3 @@ func (m *mockBlob) GetSASURI(ttl time.Duration, sharedKeyCredential *azblob.Shar args := m.Called(ttl, sharedKeyCredential) return args.String(0), args.Error(1) } - -type mockContainerGetter struct { - mock.Mock -} - -func (m *mockContainerGetter) getContainer(bucket string) (container, error) { - args := m.Called(bucket) - return args.Get(0).(container), args.Error(1) -} - -type mockContainer struct { - mock.Mock -} - -func (m *mockContainer) ListBlobs(params *azcontainer.ListBlobsFlatOptions) *runtime.Pager[azcontainer.ListBlobsFlatResponse] { - args := m.Called(params) - return args.Get(0).(*runtime.Pager[azcontainer.ListBlobsFlatResponse]) -} - -func (m *mockContainer) ListBlobsHierarchy(delimiter string, listOptions *azcontainer.ListBlobsHierarchyOptions) *runtime.Pager[azcontainer.ListBlobsHierarchyResponse] { - args := m.Called(delimiter, listOptions) - return args.Get(0).(*runtime.Pager[azcontainer.ListBlobsHierarchyResponse]) -} diff --git a/velero-plugin-for-microsoft-azure/volume_snapshotter.go b/velero-plugin-for-microsoft-azure/volume_snapshotter.go index 611a483..9905396 100644 --- a/velero-plugin-for-microsoft-azure/volume_snapshotter.go +++ b/velero-plugin-for-microsoft-azure/volume_snapshotter.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "net/http" - "os" "regexp" "strconv" "strings" @@ -28,15 +27,14 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm" - "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" - "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute" uuid "github.com/gofrs/uuid" "github.com/pkg/errors" "github.com/sirupsen/logrus" veleroplugin "github.com/vmware-tanzu/velero/pkg/plugin/framework" + "github.com/vmware-tanzu/velero/pkg/util/azure" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -44,12 +42,14 @@ import ( ) const ( - resourceGroupEnvVar = "AZURE_RESOURCE_GROUP" + credentialsFileConfigKey = "credentialsFile" - apiTimeoutConfigKey = "apiTimeout" - snapsIncrementalConfigKey = "incremental" - snapsTagsConfigKey = "tags" - snapsActiveDirectoryAuthorityURIConfigKey = "activeDirectoryAuthorityURI" + vslConfigKeyActiveDirectoryAuthorityURI = "activeDirectoryAuthorityURI" + vslConfigKeySubscriptionID = "subscriptionId" + vslConfigKeyResourceGroup = "resourceGroup" + vslConfigKeyAPITimeout = "apiTimeout" + vslConfigKeyIncremental = "incremental" + vslConfigKeyTags = "tags" snapshotsResource = "snapshots" disksResource = "disks" @@ -87,118 +87,73 @@ func newVolumeSnapshotter(logger logrus.FieldLogger) *VolumeSnapshotter { func (b *VolumeSnapshotter) Init(config map[string]string) error { if err := veleroplugin.ValidateVolumeSnapshotterConfigKeys(config, - resourceGroupConfigKey, - apiTimeoutConfigKey, - subscriptionIDConfigKey, - snapsIncrementalConfigKey, - snapsTagsConfigKey, + vslConfigKeyResourceGroup, + vslConfigKeyAPITimeout, + vslConfigKeyResourceGroup, + vslConfigKeyIncremental, + vslConfigKeyTags, credentialsFileConfigKey, ); err != nil { return err } - credentialsFile, err := selectCredentialsFile(config) + creds, err := azure.LoadCredentials(config) if err != nil { return err } - if err := loadCredentialsIntoEnv(credentialsFile); err != nil { - return err - } - - // we need AZURE_SUBSCRIPTION_ID, AZURE_RESOURCE_GROUP - envVars, err := getRequiredValues(os.Getenv, subscriptionIDEnvVar, resourceGroupEnvVar) - if err != nil { - return errors.Wrap(err, "unable to get all required environment variables") - } - - // set a different subscriptionId for snapshots if specified - snapshotsSubscriptionID := envVars[subscriptionIDEnvVar] - if val := config[subscriptionIDConfigKey]; val != "" { - // if subscription was set in config, it is required to also set the resource group - if _, err := getRequiredValues(mapLookup(config), resourceGroupConfigKey); err != nil { - return errors.Wrap(err, "resourceGroup not specified, but is a requirement when backing up to a different subscription") - } - snapshotsSubscriptionID = val + b.disksSubscription = creds[azure.CredentialKeySubscriptionID] + if b.disksSubscription == "" { + return errors.Errorf("%s is required in credential file", azure.CredentialKeySubscriptionID) } - - // Get Azure cloudConfig from AZURE_CLOUD_NAME, if it exists. If the env var does not - // exist, cloudFromName will return AzurePublic. - cloudConfig, err := cloudFromName(os.Getenv(cloudNameEnvVar)) - if err != nil { - return errors.Wrap(err, "unable to parse azure cloud name environment variable") + b.disksResourceGroup = creds[azure.CredentialKeyResourceGroup] + if b.disksResourceGroup == "" { + return errors.Errorf("%s is required in credential file", azure.CredentialKeyResourceGroup) } - // Update active directory authority host if it is set in the configuration - if config[snapsActiveDirectoryAuthorityURIConfigKey] != "" { - cloudConfig.ActiveDirectoryAuthorityHost = config[snapsActiveDirectoryAuthorityURIConfigKey] - } + b.snapsSubscription = azure.GetFromLocationConfigOrCredential(config, creds, vslConfigKeySubscriptionID, azure.CredentialKeySubscriptionID) + b.snapsResourceGroup = azure.GetFromLocationConfigOrCredential(config, creds, vslConfigKeyResourceGroup, azure.CredentialKeyResourceGroup) - // if config["apiTimeout"] is empty, default to 2m; otherwise, parse it - var apiTimeout time.Duration - if val := config[apiTimeoutConfigKey]; val == "" { - apiTimeout = 2 * time.Minute - } else { - apiTimeout, err = time.ParseDuration(val) + b.apiTimeout = 2 * time.Minute + if val := config[vslConfigKeyAPITimeout]; val != "" { + b.apiTimeout, err = time.ParseDuration(val) if err != nil { - return errors.Wrapf(err, "unable to parse value %q for config key %q (expected a duration string)", val, apiTimeoutConfigKey) + return errors.Wrapf(err, "unable to parse value %q for config key %q (expected a duration string)", val, vslConfigKeyAPITimeout) } } - clientOptions := policy.ClientOptions{Cloud: cloudConfig} - credential, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{ClientOptions: clientOptions}) - if err != nil { - return errors.Wrap(err, "error getting credentials from environment") - } - - // if config["snapsIncrementalConfigKey"] is empty, default to nil; otherwise, parse it - var snapshotsIncremental *bool - if val := config[snapsIncrementalConfigKey]; val != "" { + if val := config[vslConfigKeyIncremental]; val != "" { parseIncremental, err := strconv.ParseBool(val) if err != nil { - return errors.Wrapf(err, "unable to parse value %q for config key %q (expected a boolean value)", val, snapsIncrementalConfigKey) + return errors.Wrapf(err, "unable to parse value %q for config key %q (expected a boolean value)", val, vslConfigKeyIncremental) } - snapshotsIncremental = &parseIncremental - } else { - snapshotsIncremental = nil + b.snapsIncremental = &parseIncremental } - var snapsTags map[string]string - if val := config[snapsTagsConfigKey]; val != "" { - snapsTags, err = util.ConvertTagsToMap(val) + if val := config[vslConfigKeyTags]; val != "" { + b.snapsTags, err = util.ConvertTagsToMap(val) if err != nil { - return errors.Wrapf(err, "unable to parse value %q for config key %q (the valid format is \"key1=value1,key2=value2\")", val, snapsTagsConfigKey) + return errors.Wrapf(err, "unable to parse value %q for config key %q (the valid format is \"key1=value1,key2=value2\")", val, vslConfigKeyTags) } } - // set up clients - disksClient, err := armcompute.NewDisksClient(envVars[subscriptionIDEnvVar], credential, &arm.ClientOptions{ClientOptions: clientOptions}) + clientOptions, err := azure.GetClientOptions(config, creds) if err != nil { - return errors.Wrap(err, "error creating disk client") + return err } - snapsClient, err := armcompute.NewSnapshotsClient(snapshotsSubscriptionID, credential, &arm.ClientOptions{ClientOptions: clientOptions}) + credential, err := azure.NewCredential(creds, clientOptions) if err != nil { - return errors.Wrap(err, "error creating snapshot client") + return err } - b.disks = disksClient - b.snaps = snapsClient - b.disksSubscription = envVars[subscriptionIDEnvVar] - b.snapsSubscription = snapshotsSubscriptionID - b.disksResourceGroup = envVars[resourceGroupEnvVar] - b.snapsResourceGroup = config[resourceGroupConfigKey] - - // if no resource group was explicitly specified in 'config', - // use the value from the env var (i.e. the same one as where - // the cluster & disks are) - if b.snapsResourceGroup == "" { - b.snapsResourceGroup = envVars[resourceGroupEnvVar] + b.disks, err = armcompute.NewDisksClient(b.disksSubscription, credential, &arm.ClientOptions{ClientOptions: clientOptions}) + if err != nil { + return errors.Wrap(err, "error creating disk client") } - b.apiTimeout = apiTimeout - - b.snapsIncremental = snapshotsIncremental - - b.snapsTags = snapsTags + b.snaps, err = armcompute.NewSnapshotsClient(b.snapsSubscription, credential, &arm.ClientOptions{ClientOptions: clientOptions}) + if err != nil { + return errors.Wrap(err, "error creating snapshot client") + } return nil }