зеркало из https://github.com/Azure/aztfexport.git
`CommonConfig` explicitly takes Azure SDK credential, client option and additional provider configs from caller (#346)
* `CommonConfig` takes Azure SDK credential and client option from caller * `CommonConfig` adds `ProviderConfigs` to allow module users to specify additional provider configs explicitly (instead of via env var) * pass gosec
This commit is contained in:
Родитель
29cbc41d25
Коммит
69274d834a
18
go.mod
18
go.mod
|
@ -3,8 +3,8 @@ module github.com/Azure/aztfy
|
|||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.0.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0
|
||||
github.com/charmbracelet/bubbles v0.14.0
|
||||
|
@ -18,8 +18,8 @@ require (
|
|||
github.com/hashicorp/terraform-exec v0.17.2
|
||||
github.com/hexops/gotextdiff v1.0.3
|
||||
github.com/magodo/armid v0.0.0-20220923023118-aec41eaf7370
|
||||
github.com/magodo/azlist v0.0.0-20230118083100-39d50ebb1596
|
||||
github.com/magodo/aztft v0.3.1-0.20230106111449-dcd315087da2
|
||||
github.com/magodo/azlist v0.0.0-20230129022211-862464772b00
|
||||
github.com/magodo/aztft v0.3.1-0.20230129030008-95c799252ad3
|
||||
github.com/magodo/spinner v0.0.0-20220720073946-50f31b2dc5a6
|
||||
github.com/magodo/textinput v0.0.0-20210913072708-7d24f2b4b0c0
|
||||
github.com/magodo/tfadd v0.10.1-0.20230106064825-378b3ebb9a4e
|
||||
|
@ -27,14 +27,14 @@ require (
|
|||
github.com/magodo/workerpool v0.0.0-20230119025400-40192d2716ea
|
||||
github.com/mitchellh/go-wordwrap v1.0.0
|
||||
github.com/muesli/reflow v0.3.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
github.com/urfave/cli/v2 v2.16.3
|
||||
github.com/urfave/cli/v2 v2.24.1
|
||||
github.com/zclconf/go-cty v1.11.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/alertsmanagement/armalertsmanagement v0.6.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/apimanagement/armapimanagement v1.0.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appplatform/armappplatform v1.1.0-beta.1 // indirect
|
||||
|
@ -67,7 +67,7 @@ require (
|
|||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/streamanalytics/armstreamanalytics v1.0.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse v0.5.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/timeseriesinsights/armtimeseriesinsights v1.0.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1 // indirect
|
||||
github.com/agext/levenshtein v1.2.2 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
|
@ -76,7 +76,7 @@ require (
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
|
|
39
go.sum
39
go.sum
|
@ -1,9 +1,9 @@
|
|||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3 h1:8LoU8N2lIUzkmstvwXvVfniMZlFbesfT2AmA1aqvRr8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.3/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 h1:jp0dGvZ7ZK0mgqnTSClMxa5xuRL7NZgHameVYF6BurY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0 h1:VuHAcMq8pU1IWNT/m5yRaGqbK0BiQKHT8X4DTp9CHdI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.3.0/go.mod h1:tZoQYdDZNOiIjdSn0dVWVfl0NEPGOJqVLzSrcFk4Is0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1 h1:T8quHYlUGyb/oqtSTwqlCr1ilJHrDv+ZtpSfo+hm1BU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1/go.mod h1:gLa1CL2RNE4s7M3yopJ/p0iq5DdY6Yv5ZUt9MTRZOQM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/alertsmanagement/armalertsmanagement v0.6.0 h1:pks1dpbMetOpU0LLAMGqQWDmf6KH3YaZZFbvLdczkLY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/alertsmanagement/armalertsmanagement v0.6.0/go.mod h1:ScVCRUj/xrIX0/L+CPzpgFBB3kHuE0OfT7ZkKJL4tFg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/apimanagement/armapimanagement v1.0.0 h1:Ai3+BE11JvwQ2PxLGNKAfMNSceYXjeijReLJiCouO6o=
|
||||
|
@ -74,8 +74,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse v0.5.0
|
|||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/synapse/armsynapse v0.5.0/go.mod h1:0LrLPHG/bVyQWENxWqSj2ycnnrpTjeSFrKuWymCBceM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/timeseriesinsights/armtimeseriesinsights v1.0.0 h1:6zhHj/nA0VfUglOeV8geEXVw/XGAqsAyKjDK2B5gctE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/timeseriesinsights/armtimeseriesinsights v1.0.0/go.mod h1:BJ1j39YchhMI91ICCnhfdwPe4bN59SdA4vYWd0bfF+g=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1 h1:BWe8a+f/t+7KY7zH2mqygeUD0t8hNFXe08p1Pb3/jKE=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1 h1:oPdPEZFSbl7oSPEAIPMPBMUmiL+mqgzBJwM/9qYcwNg=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.8.1/go.mod h1:4qFor3D/HDsvBME35Xy9rwW9DecL+M2sNw1ybjPtwA0=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
|
@ -126,9 +126,8 @@ github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6
|
|||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
|
@ -136,7 +135,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
|
@ -192,10 +190,10 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69
|
|||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/magodo/armid v0.0.0-20220923023118-aec41eaf7370 h1:n8RrB7jcZ9lQE7tyF2a7AEJ3Ux/E6E6FTeZLfgadPmg=
|
||||
github.com/magodo/armid v0.0.0-20220923023118-aec41eaf7370/go.mod h1:rR8E7zfGMbmfnSQvrkFiWYdhrfTqsVSltelnZB09BwA=
|
||||
github.com/magodo/azlist v0.0.0-20230118083100-39d50ebb1596 h1:LsiNgiXcXFU7vJQRR+YeZCk0W4rVo5QfXxcg2wLxf3o=
|
||||
github.com/magodo/azlist v0.0.0-20230118083100-39d50ebb1596/go.mod h1:r1a269lM5tSby3J7PaEUZQCKWgCLKz9KSWgs7u6fR/M=
|
||||
github.com/magodo/aztft v0.3.1-0.20230106111449-dcd315087da2 h1:WxZPV+s4O53tQ0rSlBhzpP5lDwzmCDocg+TuICOK6XA=
|
||||
github.com/magodo/aztft v0.3.1-0.20230106111449-dcd315087da2/go.mod h1:UfUEt4CnhydYUqLTu7kmmx7CfFmQC9Y6cbyC87YA5VQ=
|
||||
github.com/magodo/azlist v0.0.0-20230129022211-862464772b00 h1:b4qcRg5vLTkYLKN7V3C0tTiJh2bBk+Quag6s/OsNI8U=
|
||||
github.com/magodo/azlist v0.0.0-20230129022211-862464772b00/go.mod h1:pkK04XFrJfiki47pbsmEBUAW/fbF2OiFhK37gq4TzOk=
|
||||
github.com/magodo/aztft v0.3.1-0.20230129030008-95c799252ad3 h1:coH6vuc+p76SJ0mqJYEfny376wsJsME7RJEo1+xWlpM=
|
||||
github.com/magodo/aztft v0.3.1-0.20230129030008-95c799252ad3/go.mod h1:UfwvfmEBgNL+dBbljeOHnuHEWILBDMZdH8NZ8wO41iQ=
|
||||
github.com/magodo/spinner v0.0.0-20220720073946-50f31b2dc5a6 h1:CElHO4hPXC+Eivy8sUC/WrnH3jmQzdF2x0lEXBEYul8=
|
||||
github.com/magodo/spinner v0.0.0-20220720073946-50f31b2dc5a6/go.mod h1:Cn4fFwFH/Ddw9sjWPeSS72bNaxbM+FRXf7pkGEDReq8=
|
||||
github.com/magodo/textinput v0.0.0-20210913072708-7d24f2b4b0c0 h1:aNtr4iNv/tex2t8W1u3scAoNHEnFlTKhNNHOpYStqbs=
|
||||
|
@ -230,7 +228,6 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
|||
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/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
|
||||
github.com/muesli/cancelreader v0.2.0/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
|
||||
|
@ -263,22 +260,24 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
|
||||
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk=
|
||||
github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
|
||||
github.com/urfave/cli/v2 v2.24.1 h1:/QYYr7g0EhwXEML8jO+8OYt5trPnLHS0p3mrgExJ5NU=
|
||||
github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
|
|
|
@ -1,107 +1,37 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"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/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
|
||||
)
|
||||
|
||||
type ClientBuilder struct {
|
||||
credential azcore.TokenCredential
|
||||
opt *arm.ClientOptions
|
||||
}
|
||||
|
||||
func NewClientBuilder() (*ClientBuilder, error) {
|
||||
env := "public"
|
||||
if v := os.Getenv("ARM_ENVIRONMENT"); v != "" {
|
||||
env = v
|
||||
}
|
||||
|
||||
var cloudCfg cloud.Configuration
|
||||
switch strings.ToLower(env) {
|
||||
case "public":
|
||||
cloudCfg = cloud.AzurePublic
|
||||
case "usgovernment":
|
||||
cloudCfg = cloud.AzureGovernment
|
||||
case "china":
|
||||
cloudCfg = cloud.AzureChina
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown environment specified: %q", env)
|
||||
}
|
||||
|
||||
// Maps the auth related environment variables used in the provider to what azidentity honors.
|
||||
if v, ok := os.LookupEnv("ARM_TENANT_ID"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_TENANT_ID", v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("ARM_CLIENT_ID"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_ID", v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("ARM_CLIENT_SECRET"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_SECRET", v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("ARM_CLIENT_CERTIFICATE_PATH"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_CERTIFICATE_PATH", v)
|
||||
}
|
||||
|
||||
cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{
|
||||
ClientOptions: policy.ClientOptions{
|
||||
Cloud: cloudCfg,
|
||||
},
|
||||
TenantID: os.Getenv("ARM_TENANT_ID"),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to obtain a credential: %v", err)
|
||||
}
|
||||
|
||||
return &ClientBuilder{
|
||||
credential: cred,
|
||||
opt: &arm.ClientOptions{
|
||||
ClientOptions: policy.ClientOptions{
|
||||
Cloud: cloudCfg,
|
||||
Telemetry: policy.TelemetryOptions{
|
||||
ApplicationID: "aztfy",
|
||||
Disabled: false,
|
||||
},
|
||||
Logging: policy.LogOptions{
|
||||
IncludeBody: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
Credential azcore.TokenCredential
|
||||
Opt arm.ClientOptions
|
||||
}
|
||||
|
||||
func (b *ClientBuilder) NewKeyvaultKeysClient(subscriptionId string) (*armkeyvault.KeysClient, error) {
|
||||
return armkeyvault.NewKeysClient(
|
||||
subscriptionId,
|
||||
b.credential,
|
||||
b.opt,
|
||||
b.Credential,
|
||||
&b.Opt,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *ClientBuilder) NewKeyvaultSecretsClient(subscriptionId string) (*armkeyvault.SecretsClient, error) {
|
||||
return armkeyvault.NewSecretsClient(
|
||||
subscriptionId,
|
||||
b.credential,
|
||||
b.opt,
|
||||
b.Credential,
|
||||
&b.Opt,
|
||||
)
|
||||
}
|
||||
|
||||
func (b *ClientBuilder) NewResourcesClient(subscriptionId string) (*armresources.Client, error) {
|
||||
return armresources.NewClient(
|
||||
subscriptionId,
|
||||
b.credential,
|
||||
b.opt,
|
||||
b.Credential,
|
||||
&b.Opt,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import (
|
|||
"github.com/Azure/aztfy/internal/client"
|
||||
"github.com/Azure/aztfy/internal/resmap"
|
||||
"github.com/Azure/aztfy/internal/utils"
|
||||
"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/resourcemanager/resources/armresources"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclwrite"
|
||||
|
@ -62,17 +64,20 @@ type BaseMeta interface {
|
|||
var _ BaseMeta = &baseMeta{}
|
||||
|
||||
type baseMeta struct {
|
||||
subscriptionId string
|
||||
rootdir string
|
||||
outdir string
|
||||
tf *tfexec.Terraform
|
||||
resourceClient *armresources.Client
|
||||
devProvider bool
|
||||
backendType string
|
||||
backendConfig []string
|
||||
fullConfig bool
|
||||
parallelism int
|
||||
hclOnly bool
|
||||
subscriptionId string
|
||||
azureSDKCred azcore.TokenCredential
|
||||
azureSDKClientOpt arm.ClientOptions
|
||||
rootdir string
|
||||
outdir string
|
||||
tf *tfexec.Terraform
|
||||
resourceClient *armresources.Client
|
||||
devProvider bool
|
||||
backendType string
|
||||
backendConfig []string
|
||||
providerConfig map[string]string
|
||||
fullConfig bool
|
||||
parallelism int
|
||||
hclOnly bool
|
||||
|
||||
// The module address prefix in the resource addr. E.g. module.mod1.module.mod2.azurerm_resource_group.test.
|
||||
// This is an empty string if module path is not specified.
|
||||
|
@ -184,10 +189,10 @@ func NewBaseMeta(cfg config.CommonConfig) (*baseMeta, error) {
|
|||
importBaseDirs = append(importBaseDirs, dir)
|
||||
}
|
||||
|
||||
// Construct client builder
|
||||
b, err := client.NewClientBuilder()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("building authorizer: %w", err)
|
||||
// Construct Azure resources client
|
||||
b := client.ClientBuilder{
|
||||
Credential: cfg.AzureSDKCredential,
|
||||
Opt: cfg.AzureSDKClientOption,
|
||||
}
|
||||
resClient, err := b.NewResourcesClient(cfg.SubscriptionId)
|
||||
if err != nil {
|
||||
|
@ -205,19 +210,22 @@ func NewBaseMeta(cfg config.CommonConfig) (*baseMeta, error) {
|
|||
os.Setenv("ARM_SKIP_PROVIDER_REGISTRATION", "true")
|
||||
|
||||
meta := &baseMeta{
|
||||
subscriptionId: cfg.SubscriptionId,
|
||||
rootdir: rootdir,
|
||||
outdir: cfg.OutputDir,
|
||||
resourceClient: resClient,
|
||||
devProvider: cfg.DevProvider,
|
||||
backendType: cfg.BackendType,
|
||||
backendConfig: cfg.BackendConfig,
|
||||
fullConfig: cfg.FullConfig,
|
||||
parallelism: cfg.Parallelism,
|
||||
useSafeFilename: cfg.Append,
|
||||
hclOnly: cfg.HCLOnly,
|
||||
importBaseDirs: importBaseDirs,
|
||||
importModuleDirs: importModuleDirs,
|
||||
subscriptionId: cfg.SubscriptionId,
|
||||
azureSDKCred: cfg.AzureSDKCredential,
|
||||
azureSDKClientOpt: cfg.AzureSDKClientOption,
|
||||
rootdir: rootdir,
|
||||
outdir: cfg.OutputDir,
|
||||
resourceClient: resClient,
|
||||
devProvider: cfg.DevProvider,
|
||||
backendType: cfg.BackendType,
|
||||
backendConfig: cfg.BackendConfig,
|
||||
providerConfig: cfg.ProviderConfig,
|
||||
fullConfig: cfg.FullConfig,
|
||||
parallelism: cfg.Parallelism,
|
||||
useSafeFilename: cfg.Append,
|
||||
hclOnly: cfg.HCLOnly,
|
||||
importBaseDirs: importBaseDirs,
|
||||
importModuleDirs: importModuleDirs,
|
||||
|
||||
moduleAddr: moduleAddr,
|
||||
moduleDir: moduleDir,
|
||||
|
@ -447,7 +455,7 @@ func (meta baseMeta) generateCfg(ctx context.Context, l ImportList, cfgTrans ...
|
|||
return meta.generateConfig(cfginfos)
|
||||
}
|
||||
|
||||
func (meta *baseMeta) terraformConfig(backendType string) string {
|
||||
func (meta *baseMeta) buildTerraformConfig(backendType string) string {
|
||||
if meta.devProvider {
|
||||
return fmt.Sprintf(`terraform {
|
||||
backend %q {}
|
||||
|
@ -467,11 +475,15 @@ func (meta *baseMeta) terraformConfig(backendType string) string {
|
|||
`, backendType, azurerm.ProviderSchemaInfo.Version)
|
||||
}
|
||||
|
||||
func (meta *baseMeta) providerConfig() string {
|
||||
func (meta *baseMeta) buildProviderConfig() string {
|
||||
lines := []string{" features {}"}
|
||||
for k, v := range meta.providerConfig {
|
||||
lines = append(lines, fmt.Sprintf(" %s = %s", k, v))
|
||||
}
|
||||
return fmt.Sprintf(`provider "azurerm" {
|
||||
features {}
|
||||
%s
|
||||
}
|
||||
`)
|
||||
`, strings.Join(lines, "\n"))
|
||||
}
|
||||
|
||||
func (meta baseMeta) filenameTerraformSetting() string {
|
||||
|
@ -557,7 +569,7 @@ func (meta *baseMeta) initProvider(ctx context.Context) error {
|
|||
log.Printf("[INFO] Output directory doesn't contain provider setting, create one then")
|
||||
cfgFile := filepath.Join(meta.outdir, meta.filenameProviderSetting())
|
||||
// #nosec G306
|
||||
if err := os.WriteFile(cfgFile, []byte(meta.providerConfig()), 0644); err != nil {
|
||||
if err := os.WriteFile(cfgFile, []byte(meta.buildProviderConfig()), 0644); err != nil {
|
||||
return fmt.Errorf("error creating provider config: %w", err)
|
||||
}
|
||||
}
|
||||
|
@ -566,7 +578,7 @@ func (meta *baseMeta) initProvider(ctx context.Context) error {
|
|||
log.Printf("[INFO] Output directory doesn't contain terraform required provider setting, create one then")
|
||||
cfgFile := filepath.Join(meta.outdir, meta.filenameTerraformSetting())
|
||||
// #nosec G306
|
||||
if err := os.WriteFile(cfgFile, []byte(meta.terraformConfig(meta.backendType)), 0644); err != nil {
|
||||
if err := os.WriteFile(cfgFile, []byte(meta.buildTerraformConfig(meta.backendType)), 0644); err != nil {
|
||||
return fmt.Errorf("error creating terraform config: %w", err)
|
||||
}
|
||||
}
|
||||
|
@ -590,12 +602,12 @@ func (meta *baseMeta) initProvider(ctx context.Context) error {
|
|||
wp.AddTask(func() (interface{}, error) {
|
||||
providerFile := filepath.Join(meta.importBaseDirs[i], "provider.tf")
|
||||
// #nosec G306
|
||||
if err := os.WriteFile(providerFile, []byte(meta.providerConfig()), 0644); err != nil {
|
||||
if err := os.WriteFile(providerFile, []byte(meta.buildProviderConfig()), 0644); err != nil {
|
||||
return nil, fmt.Errorf("error creating provider config: %w", err)
|
||||
}
|
||||
terraformFile := filepath.Join(meta.importBaseDirs[i], "terraform.tf")
|
||||
// #nosec G306
|
||||
if err := os.WriteFile(terraformFile, []byte(meta.terraformConfig("local")), 0644); err != nil {
|
||||
if err := os.WriteFile(terraformFile, []byte(meta.buildTerraformConfig("local")), 0644); err != nil {
|
||||
return nil, fmt.Errorf("error creating terraform config: %w", err)
|
||||
}
|
||||
log.Printf(`[DEBUG] Run "terraform init" for the import directory %s`, meta.importBaseDirs[i])
|
||||
|
|
|
@ -60,7 +60,7 @@ func (meta *MetaQuery) ListResource(ctx context.Context) (ImportList, error) {
|
|||
}
|
||||
|
||||
log.Printf("[DEBUG] Azure Resource set map to TF resource set")
|
||||
rl := rset.ToTFResources(meta.parallelism)
|
||||
rl := rset.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
|
||||
|
||||
var l ImportList
|
||||
for i, res := range rl {
|
||||
|
@ -89,7 +89,14 @@ func (meta *MetaQuery) ListResource(ctx context.Context) (ImportList, error) {
|
|||
}
|
||||
|
||||
func (meta MetaQuery) queryResourceSet(ctx context.Context, predicate string, recursive bool) (*resourceset.AzureResourceSet, error) {
|
||||
result, err := azlist.List(ctx, meta.subscriptionId, predicate, &azlist.Option{Parallelism: meta.parallelism, Recursive: recursive})
|
||||
result, err := azlist.List(ctx, predicate,
|
||||
azlist.Option{
|
||||
SubscriptionId: meta.subscriptionId,
|
||||
Cred: meta.azureSDKCred,
|
||||
ClientOpt: meta.azureSDKClientOpt,
|
||||
Parallelism: meta.parallelism,
|
||||
Recursive: recursive,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing resource set: %v", err)
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ func (meta *MetaResource) ListResource(_ context.Context) (ImportList, error) {
|
|||
},
|
||||
}
|
||||
log.Printf("[DEBUG] Azure Resource set map to TF resource set")
|
||||
rl := resourceSet.ToTFResources(meta.parallelism)
|
||||
rl := resourceSet.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
|
||||
|
||||
// This is to record known resource types. In case there is a known resource type and there comes another same typed resource,
|
||||
// then we need to modify the resource name. Otherwise, there will be a resource address conflict.
|
||||
|
@ -81,7 +81,11 @@ func (meta *MetaResource) ListResource(_ context.Context) (ImportList, error) {
|
|||
// In this case, users can use the `--type` option to manually specify the TF resource type.
|
||||
if meta.ResourceType != "" {
|
||||
if meta.AzureId.Equal(res.AzureId) {
|
||||
tfid, err := aztft.QueryId(meta.AzureId.String(), meta.ResourceType, true)
|
||||
tfid, err := aztft.QueryId(meta.AzureId.String(), meta.ResourceType,
|
||||
&aztft.APIOption{
|
||||
Cred: meta.azureSDKCred,
|
||||
ClientOption: meta.azureSDKClientOpt,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ func (meta *MetaResourceGroup) ListResource(ctx context.Context) (ImportList, er
|
|||
}
|
||||
|
||||
log.Printf("[DEBUG] Azure Resource set map to TF resource set")
|
||||
rl := rset.ToTFResources(meta.parallelism)
|
||||
rl := rset.ToTFResources(meta.parallelism, meta.azureSDKCred, meta.azureSDKClientOpt)
|
||||
|
||||
var l ImportList
|
||||
for i, res := range rl {
|
||||
|
@ -82,7 +82,14 @@ func (meta *MetaResourceGroup) ListResource(ctx context.Context) (ImportList, er
|
|||
}
|
||||
|
||||
func (meta MetaResourceGroup) queryResourceSet(ctx context.Context, rg string) (*resourceset.AzureResourceSet, error) {
|
||||
result, err := azlist.List(ctx, meta.subscriptionId, fmt.Sprintf("resourceGroup =~ %q", rg), &azlist.Option{Parallelism: meta.parallelism, Recursive: true})
|
||||
result, err := azlist.List(ctx, fmt.Sprintf("resourceGroup =~ %q", rg),
|
||||
azlist.Option{
|
||||
SubscriptionId: meta.subscriptionId,
|
||||
Cred: meta.azureSDKCred,
|
||||
ClientOpt: meta.azureSDKClientOpt,
|
||||
Parallelism: meta.parallelism,
|
||||
Recursive: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing resource set: %v", err)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/Azure/aztfy/pkg/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
|
||||
|
||||
"github.com/magodo/armid"
|
||||
"github.com/magodo/aztft/aztft"
|
||||
|
@ -24,7 +26,7 @@ type PesudoResourceInfo struct {
|
|||
TFId string
|
||||
}
|
||||
|
||||
func (rset AzureResourceSet) ToTFResources(parallelism int) []TFResource {
|
||||
func (rset AzureResourceSet) ToTFResources(parallelism int, cred azcore.TokenCredential, clientOpt arm.ClientOptions) []TFResource {
|
||||
tfresources := []TFResource{}
|
||||
|
||||
wp := workerpool.NewWorkPool(parallelism)
|
||||
|
@ -73,7 +75,12 @@ func (rset AzureResourceSet) ToTFResources(parallelism int) []TFResource {
|
|||
for _, res := range rset.Resources {
|
||||
res := res
|
||||
wp.AddTask(func() (interface{}, error) {
|
||||
tftypes, tfids, exact, err := aztft.QueryTypeAndId(res.Id.String(), true)
|
||||
tftypes, tfids, exact, err := aztft.QueryTypeAndId(res.Id.String(),
|
||||
&aztft.APIOption{
|
||||
Cred: cred,
|
||||
ClientOption: clientOpt,
|
||||
},
|
||||
)
|
||||
return result{
|
||||
resid: res.Id,
|
||||
tftypes: tftypes,
|
||||
|
|
|
@ -14,7 +14,9 @@ import (
|
|||
|
||||
var _ Case = CaseKeyVaultNestedItems{}
|
||||
|
||||
type CaseKeyVaultNestedItems struct{}
|
||||
type CaseKeyVaultNestedItems struct {
|
||||
B client.ClientBuilder
|
||||
}
|
||||
|
||||
func (CaseKeyVaultNestedItems) Tpl(d test.Data) string {
|
||||
return fmt.Sprintf(`
|
||||
|
@ -124,11 +126,8 @@ func (CaseKeyVaultNestedItems) Total() int {
|
|||
return 5
|
||||
}
|
||||
|
||||
func (CaseKeyVaultNestedItems) getItems(d test.Data) (keyId, secretId, certId string, err error) {
|
||||
b, err := client.NewClientBuilder()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
func (c CaseKeyVaultNestedItems) getItems(d test.Data) (keyId, secretId, certId string, err error) {
|
||||
b := c.B
|
||||
subid := os.Getenv("ARM_SUBSCRIPTION_ID")
|
||||
ctx := context.Background()
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package main
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -83,16 +83,20 @@ resource "azurerm_subnet" "test" {
|
|||
t.Logf("Sleep for %v to wait for the just created resources be recorded in ARG\n", delay)
|
||||
time.Sleep(delay)
|
||||
|
||||
cred, clientOpt := test.BuildCredAndClientOpt(t)
|
||||
|
||||
// Import in non-recursive mode
|
||||
aztfyDir := t.TempDir()
|
||||
cfg := internalconfig.NonInteractiveModeConfig{
|
||||
Config: config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
},
|
||||
ResourceNamePattern: "res-",
|
||||
ARGPredicate: fmt.Sprintf(`resourceGroup =~ "%s" and type =~ "microsoft.network/virtualnetworks"`, d.RandomRgName()),
|
||||
|
|
|
@ -3,12 +3,14 @@ package resmap
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/aztfy/internal/client"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
|
||||
"github.com/Azure/aztfy/pkg/config"
|
||||
|
||||
"github.com/Azure/aztfy/internal"
|
||||
|
@ -66,14 +68,18 @@ func runCase(t *testing.T, d test.Data, c cases.Case) {
|
|||
require.NoError(t, err)
|
||||
require.NoError(t, os.WriteFile(mapFile, bMapping, 0644))
|
||||
|
||||
cred, clientOpt := test.BuildCredAndClientOpt(t)
|
||||
|
||||
cfg := internalconfig.NonInteractiveModeConfig{
|
||||
Config: config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
},
|
||||
MappingFile: mapFile,
|
||||
},
|
||||
|
@ -110,7 +116,8 @@ func TestApplicationInsightWebTest(t *testing.T) {
|
|||
func TestKeyVaultNestedItems(t *testing.T) {
|
||||
t.Parallel()
|
||||
test.Precheck(t)
|
||||
c, d := cases.CaseKeyVaultNestedItems{}, test.NewData()
|
||||
cred, opt := test.BuildCredAndClientOpt(t)
|
||||
c, d := cases.CaseKeyVaultNestedItems{B: client.ClientBuilder{Credential: cred, Opt: *opt}}, test.NewData()
|
||||
runCase(t, d, c)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,14 @@ package resource
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/aztfy/internal/client"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
|
||||
"github.com/Azure/aztfy/pkg/config"
|
||||
|
||||
"github.com/Azure/aztfy/internal"
|
||||
|
@ -62,15 +64,20 @@ func runCase(t *testing.T, d test.Data, c cases.Case) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed to get resource ids: %v", err)
|
||||
}
|
||||
|
||||
cred, clientOpt := test.BuildCredAndClientOpt(t)
|
||||
|
||||
for idx, rctx := range l {
|
||||
cfg := internalconfig.NonInteractiveModeConfig{
|
||||
Config: config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
},
|
||||
ResourceId: rctx.AzureId,
|
||||
TFResourceName: fmt.Sprintf("res-%d", idx),
|
||||
|
@ -111,7 +118,8 @@ func TestApplicationInsightWebTest(t *testing.T) {
|
|||
func TestKeyVaultNestedItems(t *testing.T) {
|
||||
t.Parallel()
|
||||
test.Precheck(t)
|
||||
c, d := cases.CaseKeyVaultNestedItems{}, test.NewData()
|
||||
cred, opt := test.BuildCredAndClientOpt(t)
|
||||
c, d := cases.CaseKeyVaultNestedItems{B: client.ClientBuilder{Credential: cred, Opt: *opt}}, test.NewData()
|
||||
runCase(t, d, c)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,12 @@ package resourcegroup
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
|
||||
"github.com/Azure/aztfy/pkg/config"
|
||||
|
||||
"github.com/Azure/aztfy/internal/test"
|
||||
|
@ -77,14 +78,19 @@ resource "azurerm_resource_group" "test3" {
|
|||
|
||||
// Import the first resource group
|
||||
aztfyDir := t.TempDir()
|
||||
|
||||
cred, clientOpt := test.BuildCredAndClientOpt(t)
|
||||
|
||||
cfg := internalconfig.NonInteractiveModeConfig{
|
||||
Config: config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
},
|
||||
ResourceNamePattern: "t1",
|
||||
},
|
||||
|
|
|
@ -2,12 +2,14 @@ package resourcegroup
|
|||
|
||||
import (
|
||||
"context"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/aztfy/internal/client"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
|
||||
"github.com/Azure/aztfy/pkg/config"
|
||||
|
||||
"github.com/Azure/aztfy/internal"
|
||||
|
@ -56,14 +58,18 @@ func runCase(t *testing.T, d test.Data, c cases.Case) {
|
|||
|
||||
aztfyDir := t.TempDir()
|
||||
|
||||
cred, clientOpt := test.BuildCredAndClientOpt(t)
|
||||
|
||||
cfg := internalconfig.NonInteractiveModeConfig{
|
||||
Config: config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 10,
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 10,
|
||||
},
|
||||
ResourceGroupName: d.RandomRgName(),
|
||||
ResourceNamePattern: "res-",
|
||||
|
@ -101,7 +107,8 @@ func TestApplicationInsightWebTest(t *testing.T) {
|
|||
func TestKeyVaultNestedItems(t *testing.T) {
|
||||
t.Parallel()
|
||||
test.Precheck(t)
|
||||
c, d := cases.CaseKeyVaultNestedItems{}, test.NewData()
|
||||
cred, opt := test.BuildCredAndClientOpt(t)
|
||||
c, d := cases.CaseKeyVaultNestedItems{B: client.ClientBuilder{Credential: cred, Opt: *opt}}, test.NewData()
|
||||
runCase(t, d, c)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,12 @@ package resourcegroup
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
internalconfig "github.com/Azure/aztfy/internal/config"
|
||||
|
||||
"github.com/Azure/aztfy/pkg/config"
|
||||
|
||||
"github.com/Azure/aztfy/internal/test"
|
||||
|
@ -105,16 +106,20 @@ module "sub-module" {
|
|||
t.Fatalf("terraform init failed: %v", err)
|
||||
}
|
||||
|
||||
cred, clientOpt := test.BuildCredAndClientOpt(t)
|
||||
|
||||
cfg := internalconfig.NonInteractiveModeConfig{
|
||||
Config: config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
Append: true,
|
||||
ModulePath: "", // Import to the root module
|
||||
SubscriptionId: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: aztfyDir,
|
||||
BackendType: "local",
|
||||
DevProvider: true,
|
||||
Parallelism: 1,
|
||||
Append: true,
|
||||
ModulePath: "", // Import to the root module
|
||||
},
|
||||
},
|
||||
PlainUI: true,
|
||||
|
|
|
@ -12,6 +12,11 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/Azure/aztfy/internal/resmap"
|
||||
"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/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/hashicorp/go-version"
|
||||
install "github.com/hashicorp/hc-install"
|
||||
"github.com/hashicorp/hc-install/fs"
|
||||
|
@ -42,6 +47,61 @@ func Precheck(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func BuildCredAndClientOpt(t *testing.T) (azcore.TokenCredential, *arm.ClientOptions) {
|
||||
env := "public"
|
||||
if v := os.Getenv("ARM_ENVIRONMENT"); v != "" {
|
||||
env = v
|
||||
}
|
||||
|
||||
var cloudCfg cloud.Configuration
|
||||
switch strings.ToLower(env) {
|
||||
case "public":
|
||||
cloudCfg = cloud.AzurePublic
|
||||
case "usgovernment":
|
||||
cloudCfg = cloud.AzureGovernment
|
||||
case "china":
|
||||
cloudCfg = cloud.AzureChina
|
||||
default:
|
||||
t.Fatalf("unknown environment specified: %q", env)
|
||||
}
|
||||
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_TENANT_ID", os.Getenv("ARM_TENANT_ID"))
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_ID", os.Getenv("ARM_CLIENT_ID"))
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_SECRET", os.Getenv("ARM_CLIENT_SECRET"))
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_CERTIFICATE_PATH", os.Getenv("ARM_CLIENT_CERTIFICATE_PATH"))
|
||||
|
||||
clientOpt := &arm.ClientOptions{
|
||||
ClientOptions: policy.ClientOptions{
|
||||
Cloud: cloudCfg,
|
||||
Telemetry: policy.TelemetryOptions{
|
||||
ApplicationID: "aztfy",
|
||||
Disabled: false,
|
||||
},
|
||||
Logging: policy.LogOptions{
|
||||
IncludeBody: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cred, err := azidentity.NewClientSecretCredential(
|
||||
os.Getenv("ARM_TENANT_ID"),
|
||||
os.Getenv("ARM_CLIENT_ID"),
|
||||
os.Getenv("ARM_CLIENT_SECRET"),
|
||||
&azidentity.ClientSecretCredentialOptions{
|
||||
ClientOptions: clientOpt.ClientOptions,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to obtain a credential: %v", err)
|
||||
}
|
||||
|
||||
return cred, clientOpt
|
||||
}
|
||||
|
||||
func EnsureTF(t *testing.T) string {
|
||||
i := install.NewInstaller()
|
||||
execPath, err := i.Ensure(context.Background(), []src.Source{
|
||||
|
|
182
main.go
182
main.go
|
@ -25,7 +25,12 @@ import (
|
|||
"github.com/Azure/aztfy/internal"
|
||||
"github.com/Azure/aztfy/internal/ui"
|
||||
"github.com/Azure/aztfy/internal/utils"
|
||||
"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/cloud"
|
||||
azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
@ -370,20 +375,27 @@ The output directory is not empty. Please choose one of actions below:
|
|||
return fmt.Errorf("invalid resource id: %v", err)
|
||||
}
|
||||
|
||||
cred, clientOpt, err := buildAzureSDKCredAndClientOpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize the config
|
||||
cfg := config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
},
|
||||
ResourceId: resId,
|
||||
TFResourceName: flagResName,
|
||||
|
@ -410,20 +422,27 @@ The output directory is not empty. Please choose one of actions below:
|
|||
|
||||
rg := c.Args().First()
|
||||
|
||||
cred, clientOpt, err := buildAzureSDKCredAndClientOpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize the config
|
||||
cfg := config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
},
|
||||
ResourceGroupName: rg,
|
||||
ResourceNamePattern: flagPattern,
|
||||
|
@ -449,20 +468,27 @@ The output directory is not empty. Please choose one of actions below:
|
|||
|
||||
predicate := c.Args().First()
|
||||
|
||||
cred, clientOpt, err := buildAzureSDKCredAndClientOpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize the config
|
||||
cfg := config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
},
|
||||
ARGPredicate: predicate,
|
||||
ResourceNamePattern: flagPattern,
|
||||
|
@ -489,20 +515,27 @@ The output directory is not empty. Please choose one of actions below:
|
|||
|
||||
mapFile := c.Args().First()
|
||||
|
||||
cred, clientOpt, err := buildAzureSDKCredAndClientOpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize the config
|
||||
cfg := config.Config{
|
||||
CommonConfig: config.CommonConfig{
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
SubscriptionId: flagSubscriptionId,
|
||||
AzureSDKCredential: cred,
|
||||
AzureSDKClientOption: *clientOpt,
|
||||
OutputDir: flagOutputDir,
|
||||
Append: flagAppend,
|
||||
DevProvider: flagDevProvider,
|
||||
ContinueOnError: flagContinue,
|
||||
BackendType: flagBackendType,
|
||||
BackendConfig: flagBackendConfig.Value(),
|
||||
FullConfig: flagFullConfig,
|
||||
Parallelism: flagParallelism,
|
||||
HCLOnly: flagHCLOnly,
|
||||
ModulePath: flagModulePath,
|
||||
},
|
||||
MappingFile: mapFile,
|
||||
}
|
||||
|
@ -571,6 +604,67 @@ func initLog(path string, level hclog.Level) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// buildAzureSDKCredAndClientOpt builds the Azure SDK credential and client option from multiple sources (i.e. environment variables, MSI, Azure CLI).
|
||||
func buildAzureSDKCredAndClientOpt() (azcore.TokenCredential, *arm.ClientOptions, error) {
|
||||
env := "public"
|
||||
if v := os.Getenv("ARM_ENVIRONMENT"); v != "" {
|
||||
env = v
|
||||
}
|
||||
|
||||
var cloudCfg cloud.Configuration
|
||||
switch strings.ToLower(env) {
|
||||
case "public":
|
||||
cloudCfg = cloud.AzurePublic
|
||||
case "usgovernment":
|
||||
cloudCfg = cloud.AzureGovernment
|
||||
case "china":
|
||||
cloudCfg = cloud.AzureChina
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown environment specified: %q", env)
|
||||
}
|
||||
|
||||
// Maps the auth related environment variables used in the provider to what azidentity honors
|
||||
if v, ok := os.LookupEnv("ARM_TENANT_ID"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_TENANT_ID", v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("ARM_CLIENT_ID"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_ID", v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("ARM_CLIENT_SECRET"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_SECRET", v)
|
||||
}
|
||||
if v, ok := os.LookupEnv("ARM_CLIENT_CERTIFICATE_PATH"); ok {
|
||||
// #nosec G104
|
||||
os.Setenv("AZURE_CLIENT_CERTIFICATE_PATH", v)
|
||||
}
|
||||
|
||||
clientOpt := &arm.ClientOptions{
|
||||
ClientOptions: policy.ClientOptions{
|
||||
Cloud: cloudCfg,
|
||||
Telemetry: policy.TelemetryOptions{
|
||||
ApplicationID: "aztfy",
|
||||
Disabled: false,
|
||||
},
|
||||
Logging: policy.LogOptions{
|
||||
IncludeBody: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cred, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{
|
||||
ClientOptions: clientOpt.ClientOptions,
|
||||
TenantID: os.Getenv("ARM_TENANT_ID"),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to obtain a credential: %v", err)
|
||||
}
|
||||
|
||||
return cred, clientOpt, nil
|
||||
}
|
||||
|
||||
func subscriptionIdFromCLI() (string, error) {
|
||||
var stderr bytes.Buffer
|
||||
var stdout bytes.Buffer
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
|
||||
)
|
||||
|
||||
type CommonConfig struct {
|
||||
// SubscriptionId specifies the user's Azure subscription id.
|
||||
SubscriptionId string
|
||||
// AzureSDKCredential specifies the Azure SDK token credential
|
||||
AzureSDKCredential azcore.TokenCredential
|
||||
// AzureSDKClientOption specifies the Azure SDK client option
|
||||
AzureSDKClientOption arm.ClientOptions
|
||||
// OutputDir specifies the Terraform working directory for aztfy to import resources and generate TF configs.
|
||||
OutputDir string
|
||||
// Append specifies whether this run is in append mode, in which case aztfy will generate some "safe" file name to avoid conflicts to usre's existing files.
|
||||
|
@ -15,6 +24,11 @@ type CommonConfig struct {
|
|||
BackendType string
|
||||
// BackendConfig specifies an array of Terraform backend configs.
|
||||
BackendConfig []string
|
||||
// ProviderConfig specifies key value pairs that will be expanded to the terraform-provider-azurerm settings (i.e. `azurerm {}` block)
|
||||
// Currently, only the top level attribute whose type is string is supported.
|
||||
// This is not used directly by aztfy binary as the provider configs can be set by environment variable already.
|
||||
// While it is useful for module users that want support multi-users scenarios in one process (in which case changing env vars affect the whole process).
|
||||
ProviderConfig map[string]string
|
||||
// FullConfig specifies whether to export all (non computed-only) Terarform properties when generating TF configs.
|
||||
FullConfig bool
|
||||
// Parallelism specifies the parallelism for the process
|
||||
|
|
Загрузка…
Ссылка в новой задаче