Update Azure SDK and remove deprecated autorest dependency

This commit is contained in:
Philip Laine 2022-12-02 11:10:38 +01:00
parent cf1b30f0ea
commit 70eda8b84b
10 changed files with 534 additions and 749 deletions

17
go.mod
View File

@ -4,10 +4,10 @@ go 1.20
require (
cloud.google.com/go/compute/metadata v0.2.3
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
github.com/Azure/go-autorest/autorest v0.11.29
github.com/Azure/go-autorest/autorest/adal v0.9.23
github.com/Azure/go-autorest/autorest/to v0.4.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0
github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.1
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.1.0
github.com/IBM/go-sdk-core/v5 v5.13.4
@ -79,10 +79,8 @@ require (
require (
cloud.google.com/go/compute v1.20.1 // indirect
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/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/Masterminds/semver v1.4.2 // indirect
github.com/Yamashou/gqlgenc v0.14.0 // indirect
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
@ -100,7 +98,6 @@ require (
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/frankban/quicktest v1.14.4 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-openapi/errors v0.20.3 // indirect
@ -142,6 +139,7 @@ require (
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.2.3 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
@ -160,6 +158,7 @@ require (
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/peterhellberg/link v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.43.0 // indirect

47
go.sum
View File

@ -44,36 +44,31 @@ code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTg
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
git.lukeshu.com/go/libsystemd v0.5.3/go.mod h1:FfDoP0i92r4p5Vn4NCLxvjkd7rCOe6otPa4L6hZg9WM=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible h1:KnPIugL51v3N3WwvaSmZbxukD1WuWXOiE9fRdu32f2I=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 h1:8q4SaHjFsClSvuVne0ID/5Ka8u3fcIHyqkLjcFpNRHQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/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/dns/armdns v1.1.0 h1:8iR6OLffWWorFdzL2JFCab5xpD8VKEE2DUBBl+HNTDY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0/go.mod h1:copqlcjMWc/wgQ1N2fzsJFQxDdqKGg1EQt8T5wJMOGE=
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/privatedns/armprivatedns v1.1.0 h1:rR8ZW79lE/ppfXTfiYSnMFv5EzmVuY4pfZWIkscIJ64=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0/go.mod h1:y2zXtLSMM/X5Mfawq0lOftpWn3f4V6OCsRdINsvWBPI=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw=
github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8=
github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
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=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
@ -324,8 +319,7 @@ github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99/go.mod h1:4mP9w
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
@ -462,7 +456,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
@ -719,12 +712,13 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
@ -943,6 +937,8 @@ github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rK
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -1008,7 +1004,6 @@ github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc=
@ -1238,7 +1233,6 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1448,6 +1442,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@ -24,9 +24,9 @@ import (
log "github.com/sirupsen/logrus"
"github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
azcoreruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
dns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns"
"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/plan"
@ -39,14 +39,14 @@ const (
// ZonesClient is an interface of dns.ZoneClient that can be stubbed for testing.
type ZonesClient interface {
ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultIterator, err error)
NewListByResourceGroupPager(resourceGroupName string, options *dns.ZonesClientListByResourceGroupOptions) *azcoreruntime.Pager[dns.ZonesClientListByResourceGroupResponse]
}
// RecordSetsClient is an interface of dns.RecordSetsClient that can be stubbed for testing.
type RecordSetsClient interface {
ListAllByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result dns.RecordSetListResultIterator, err error)
Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error)
CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error)
NewListAllByDNSZonePager(resourceGroupName string, zoneName string, options *dns.RecordSetsClientListAllByDNSZoneOptions) *azcoreruntime.Pager[dns.RecordSetsClientListAllByDNSZoneResponse]
Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, options *dns.RecordSetsClientDeleteOptions) (dns.RecordSetsClientDeleteResponse, error)
CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, options *dns.RecordSetsClientCreateOrUpdateOptions) (dns.RecordSetsClientCreateOrUpdateResponse, error)
}
// AzureProvider implements the DNS provider for Microsoft's Azure cloud platform.
@ -70,17 +70,18 @@ func NewAzureProvider(configFile string, domainFilter endpoint.DomainFilter, zon
if err != nil {
return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err)
}
token, err := getAccessToken(*cfg, cfg.Environment)
cred, err := getCredentials(*cfg)
if err != nil {
return nil, fmt.Errorf("failed to get token: %v", err)
return nil, fmt.Errorf("failed to get credentials: %v", err)
}
zonesClient, err := dns.NewZonesClient(cfg.SubscriptionID, cred, nil)
if err != nil {
return nil, err
}
recordSetsClient, err := dns.NewRecordSetsClient(cfg.SubscriptionID, cred, nil)
if err != nil {
return nil, err
}
zonesClient := dns.NewZonesClientWithBaseURI(cfg.Environment.ResourceManagerEndpoint, cfg.SubscriptionID)
zonesClient.Authorizer = autorest.NewBearerAuthorizer(token)
recordSetsClient := dns.NewRecordSetsClientWithBaseURI(cfg.Environment.ResourceManagerEndpoint, cfg.SubscriptionID)
recordSetsClient.Authorizer = autorest.NewBearerAuthorizer(token)
return &AzureProvider{
domainFilter: domainFilter,
zoneNameFilter: zoneNameFilter,
@ -103,43 +104,44 @@ func (p *AzureProvider) Records(ctx context.Context) (endpoints []*endpoint.Endp
}
for _, zone := range zones {
err := p.iterateRecords(ctx, *zone.Name, func(recordSet dns.RecordSet) bool {
if recordSet.Name == nil || recordSet.Type == nil {
log.Error("Skipping invalid record set with nil name or type.")
return true
pager := p.recordSetsClient.NewListAllByDNSZonePager(p.resourceGroup, *zone.Name, &dns.RecordSetsClientListAllByDNSZoneOptions{Top: nil})
for pager.More() {
nextResult, err := pager.NextPage(ctx)
if err != nil {
return nil, err
}
recordType := strings.TrimPrefix(*recordSet.Type, "Microsoft.Network/dnszones/")
if !p.SupportedRecordType(recordType) {
return true
for _, recordSet := range nextResult.Value {
if recordSet.Name == nil || recordSet.Type == nil {
log.Error("Skipping invalid record set with nil name or type.")
continue
}
recordType := strings.TrimPrefix(*recordSet.Type, "Microsoft.Network/dnszones/")
if !p.SupportedRecordType(recordType) {
continue
}
name := formatAzureDNSName(*recordSet.Name, *zone.Name)
if len(p.zoneNameFilter.Filters) > 0 && !p.domainFilter.Match(name) {
log.Debugf("Skipping return of record %s because it was filtered out by the specified --domain-filter", name)
continue
}
targets := extractAzureTargets(recordSet)
if len(targets) == 0 {
log.Debugf("Failed to extract targets for '%s' with type '%s'.", name, recordType)
continue
}
var ttl endpoint.TTL
if recordSet.Properties.TTL != nil {
ttl = endpoint.TTL(*recordSet.Properties.TTL)
}
ep := endpoint.NewEndpointWithTTL(name, recordType, ttl, targets...)
log.Debugf(
"Found %s record for '%s' with target '%s'.",
ep.RecordType,
ep.DNSName,
ep.Targets,
)
endpoints = append(endpoints, ep)
}
name := formatAzureDNSName(*recordSet.Name, *zone.Name)
if len(p.zoneNameFilter.Filters) > 0 && !p.domainFilter.Match(name) {
log.Debugf("Skipping return of record %s because it was filtered out by the specified --domain-filter", name)
return true
}
targets := extractAzureTargets(&recordSet)
if len(targets) == 0 {
log.Debugf("Failed to extract targets for '%s' with type '%s'.", name, recordType)
return true
}
var ttl endpoint.TTL
if recordSet.TTL != nil {
ttl = endpoint.TTL(*recordSet.TTL)
}
ep := endpoint.NewEndpointWithTTL(name, recordType, ttl, targets...)
log.Debugf(
"Found %s record for '%s' with target '%s'.",
ep.RecordType,
ep.DNSName,
ep.Targets,
)
endpoints = append(endpoints, ep)
return true
})
if err != nil {
return nil, err
}
}
return endpoints, nil
@ -162,30 +164,22 @@ func (p *AzureProvider) ApplyChanges(ctx context.Context, changes *plan.Changes)
func (p *AzureProvider) zones(ctx context.Context) ([]dns.Zone, error) {
log.Debugf("Retrieving Azure DNS zones for resource group: %s.", p.resourceGroup)
var zones []dns.Zone
zonesIterator, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil)
if err != nil {
return nil, err
}
for zonesIterator.NotDone() {
zone := zonesIterator.Value()
if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) {
zones = append(zones, zone)
} else if zone.Name != nil && len(p.zoneNameFilter.Filters) > 0 && p.zoneNameFilter.Match(*zone.Name) {
// Handle zoneNameFilter
zones = append(zones, zone)
}
err := zonesIterator.NextWithContext(ctx)
pager := p.zonesClient.NewListByResourceGroupPager(p.resourceGroup, &dns.ZonesClientListByResourceGroupOptions{Top: nil})
for pager.More() {
nextResult, err := pager.NextPage(ctx)
if err != nil {
return nil, err
}
for _, zone := range nextResult.Value {
if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) {
zones = append(zones, *zone)
} else if zone.Name != nil && len(p.zoneNameFilter.Filters) > 0 && p.zoneNameFilter.Match(*zone.Name) {
// Handle zoneNameFilter
zones = append(zones, *zone)
}
}
}
log.Debugf("Found %d Azure DNS zone(s).", len(zones))
return zones, nil
}
@ -199,28 +193,6 @@ func (p *AzureProvider) SupportedRecordType(recordType string) bool {
}
}
func (p *AzureProvider) iterateRecords(ctx context.Context, zoneName string, callback func(dns.RecordSet) bool) error {
log.Debugf("Retrieving Azure DNS records for zone '%s'.", zoneName)
recordSetsIterator, err := p.recordSetsClient.ListAllByDNSZoneComplete(ctx, p.resourceGroup, zoneName, nil, "")
if err != nil {
return err
}
for recordSetsIterator.NotDone() {
if !callback(recordSetsIterator.Value()) {
return nil
}
err := recordSetsIterator.NextWithContext(ctx)
if err != nil {
return err
}
}
return nil
}
type azureChangeMap map[string][]*endpoint.Endpoint
func (p *AzureProvider) mapChanges(zones []dns.Zone, changes *plan.Changes) (azureChangeMap, azureChangeMap) {
@ -273,7 +245,7 @@ func (p *AzureProvider) deleteRecords(ctx context.Context, deleted azureChangeMa
log.Infof("Would delete %s record named '%s' for Azure DNS zone '%s'.", ep.RecordType, name, zone)
} else {
log.Infof("Deleting %s record named '%s' for Azure DNS zone '%s'.", ep.RecordType, name, zone)
if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, name, dns.RecordType(ep.RecordType), ""); err != nil {
if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, name, dns.RecordType(ep.RecordType), nil); err != nil {
log.Errorf(
"Failed to delete %s record named '%s' for Azure DNS zone '%s': %v",
ep.RecordType,
@ -323,8 +295,7 @@ func (p *AzureProvider) updateRecords(ctx context.Context, updated azureChangeMa
name,
dns.RecordType(ep.RecordType),
recordSet,
"",
"",
nil,
)
}
if err != nil {
@ -360,51 +331,51 @@ func (p *AzureProvider) newRecordSet(endpoint *endpoint.Endpoint) (dns.RecordSet
ttl = int64(endpoint.RecordTTL)
}
switch dns.RecordType(endpoint.RecordType) {
case dns.A:
aRecords := make([]dns.ARecord, len(endpoint.Targets))
case dns.RecordTypeA:
aRecords := make([]*dns.ARecord, len(endpoint.Targets))
for i, target := range endpoint.Targets {
aRecords[i] = dns.ARecord{
Ipv4Address: to.StringPtr(target),
aRecords[i] = &dns.ARecord{
IPv4Address: to.Ptr(target),
}
}
return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
ARecords: &aRecords,
Properties: &dns.RecordSetProperties{
TTL: to.Ptr(ttl),
ARecords: aRecords,
},
}, nil
case dns.CNAME:
case dns.RecordTypeCNAME:
return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
Properties: &dns.RecordSetProperties{
TTL: to.Ptr(ttl),
CnameRecord: &dns.CnameRecord{
Cname: to.StringPtr(endpoint.Targets[0]),
Cname: to.Ptr(endpoint.Targets[0]),
},
},
}, nil
case dns.MX:
mxRecords := make([]dns.MxRecord, len(endpoint.Targets))
case dns.RecordTypeMX:
mxRecords := make([]*dns.MxRecord, len(endpoint.Targets))
for i, target := range endpoint.Targets {
mxRecord, err := parseMxTarget[dns.MxRecord](target)
if err != nil {
return dns.RecordSet{}, err
}
mxRecords[i] = mxRecord
mxRecords[i] = &mxRecord
}
return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
MxRecords: &mxRecords,
Properties: &dns.RecordSetProperties{
TTL: to.Ptr(ttl),
MxRecords: mxRecords,
},
}, nil
case dns.TXT:
case dns.RecordTypeTXT:
return dns.RecordSet{
RecordSetProperties: &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TxtRecords: &[]dns.TxtRecord{
Properties: &dns.RecordSetProperties{
TTL: to.Ptr(ttl),
TxtRecords: []*dns.TxtRecord{
{
Value: &[]string{
endpoint.Targets[0],
Value: []*string{
&endpoint.Targets[0],
},
},
},
@ -424,17 +395,17 @@ func formatAzureDNSName(recordName, zoneName string) string {
// Helper function (shared with text code)
func extractAzureTargets(recordSet *dns.RecordSet) []string {
properties := recordSet.RecordSetProperties
properties := recordSet.Properties
if properties == nil {
return []string{}
}
// Check for A records
aRecords := properties.ARecords
if aRecords != nil && len(*aRecords) > 0 && (*aRecords)[0].Ipv4Address != nil {
targets := make([]string, len(*aRecords))
for i, aRecord := range *aRecords {
targets[i] = *aRecord.Ipv4Address
if len(aRecords) > 0 && (aRecords)[0].IPv4Address != nil {
targets := make([]string, len(aRecords))
for i, aRecord := range aRecords {
targets[i] = *aRecord.IPv4Address
}
return targets
}
@ -447,9 +418,9 @@ func extractAzureTargets(recordSet *dns.RecordSet) []string {
// Check for MX records
mxRecords := properties.MxRecords
if mxRecords != nil && len(*mxRecords) > 0 && (*mxRecords)[0].Exchange != nil {
targets := make([]string, len(*mxRecords))
for i, mxRecord := range *mxRecords {
if len(mxRecords) > 0 && (mxRecords)[0].Exchange != nil {
targets := make([]string, len(mxRecords))
for i, mxRecord := range mxRecords {
targets[i] = fmt.Sprintf("%d %s", *mxRecord.Preference, *mxRecord.Exchange)
}
return targets
@ -457,10 +428,10 @@ func extractAzureTargets(recordSet *dns.RecordSet) []string {
// Check for TXT records
txtRecords := properties.TxtRecords
if txtRecords != nil && len(*txtRecords) > 0 && (*txtRecords)[0].Value != nil {
values := (*txtRecords)[0].Value
if values != nil && len(*values) > 0 {
return []string{(*values)[0]}
if len(txtRecords) > 0 && (txtRecords)[0].Value != nil {
values := (txtRecords)[0].Value
if len(values) > 0 {
return []string{*(values)[0]}
}
}
return []string{}

View File

@ -22,9 +22,9 @@ import (
"fmt"
"strings"
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
azcoreruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
privatedns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns"
log "github.com/sirupsen/logrus"
"sigs.k8s.io/external-dns/endpoint"
@ -34,14 +34,14 @@ import (
// PrivateZonesClient is an interface of privatedns.PrivateZoneClient that can be stubbed for testing.
type PrivateZonesClient interface {
ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result privatedns.PrivateZoneListResultIterator, err error)
NewListByResourceGroupPager(resourceGroupName string, options *privatedns.PrivateZonesClientListByResourceGroupOptions) *azcoreruntime.Pager[privatedns.PrivateZonesClientListByResourceGroupResponse]
}
// PrivateRecordSetsClient is an interface of privatedns.RecordSetsClient that can be stubbed for testing.
type PrivateRecordSetsClient interface {
ListComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result privatedns.RecordSetListResultIterator, err error)
Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, err error)
CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, parameters privatedns.RecordSet, ifMatch string, ifNoneMatch string) (result privatedns.RecordSet, err error)
NewListPager(resourceGroupName string, privateZoneName string, options *privatedns.RecordSetsClientListOptions) *azcoreruntime.Pager[privatedns.RecordSetsClientListResponse]
Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, options *privatedns.RecordSetsClientDeleteOptions) (privatedns.RecordSetsClientDeleteResponse, error)
CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, parameters privatedns.RecordSet, options *privatedns.RecordSetsClientCreateOrUpdateOptions) (privatedns.RecordSetsClientCreateOrUpdateResponse, error)
}
// AzurePrivateDNSProvider implements the DNS provider for Microsoft's Azure Private DNS service
@ -64,17 +64,18 @@ func NewAzurePrivateDNSProvider(configFile string, domainFilter endpoint.DomainF
if err != nil {
return nil, fmt.Errorf("failed to read Azure config file '%s': %v", configFile, err)
}
token, err := getAccessToken(*cfg, cfg.Environment)
cred, err := getCredentials(*cfg)
if err != nil {
return nil, fmt.Errorf("failed to get token: %v", err)
return nil, fmt.Errorf("failed to get credentials: %v", err)
}
zonesClient, err := privatedns.NewPrivateZonesClient(cfg.SubscriptionID, cred, nil)
if err != nil {
return nil, err
}
recordSetsClient, err := privatedns.NewRecordSetsClient(cfg.SubscriptionID, cred, nil)
if err != nil {
return nil, err
}
zonesClient := privatedns.NewPrivateZonesClientWithBaseURI(cfg.Environment.ResourceManagerEndpoint, cfg.SubscriptionID)
zonesClient.Authorizer = autorest.NewBearerAuthorizer(token)
recordSetsClient := privatedns.NewRecordSetsClientWithBaseURI(cfg.Environment.ResourceManagerEndpoint, cfg.SubscriptionID)
recordSetsClient.Authorizer = autorest.NewBearerAuthorizer(token)
return &AzurePrivateDNSProvider{
domainFilter: domainFilter,
zoneIDFilter: zoneIDFilter,
@ -98,43 +99,48 @@ func (p *AzurePrivateDNSProvider) Records(ctx context.Context) (endpoints []*end
log.Debugf("Retrieving Azure Private DNS Records for resource group '%s'", p.resourceGroup)
for _, zone := range zones {
err := p.iterateRecords(ctx, *zone.Name, func(recordSet privatedns.RecordSet) {
var recordType string
if recordSet.Type == nil {
log.Debugf("Skipping invalid record set with missing type.")
return
}
recordType = strings.TrimPrefix(*recordSet.Type, "Microsoft.Network/privateDnsZones/")
var name string
if recordSet.Name == nil {
log.Debugf("Skipping invalid record set with missing name.")
return
}
name = formatAzureDNSName(*recordSet.Name, *zone.Name)
targets := extractAzurePrivateDNSTargets(&recordSet)
if len(targets) == 0 {
log.Debugf("Failed to extract targets for '%s' with type '%s'.", name, recordType)
return
pager := p.recordSetsClient.NewListPager(p.resourceGroup, *zone.Name, &privatedns.RecordSetsClientListOptions{Top: nil})
for pager.More() {
nextResult, err := pager.NextPage(ctx)
if err != nil {
return nil, err
}
var ttl endpoint.TTL
if recordSet.TTL != nil {
ttl = endpoint.TTL(*recordSet.TTL)
}
for _, recordSet := range nextResult.Value {
var recordType string
if recordSet.Type == nil {
log.Debugf("Skipping invalid record set with missing type.")
continue
}
recordType = strings.TrimPrefix(*recordSet.Type, "Microsoft.Network/privateDnsZones/")
ep := endpoint.NewEndpointWithTTL(name, recordType, ttl, targets...)
log.Debugf(
"Found %s record for '%s' with target '%s'.",
ep.RecordType,
ep.DNSName,
ep.Targets,
)
endpoints = append(endpoints, ep)
})
if err != nil {
return nil, err
var name string
if recordSet.Name == nil {
log.Debugf("Skipping invalid record set with missing name.")
continue
}
name = formatAzureDNSName(*recordSet.Name, *zone.Name)
targets := extractAzurePrivateDNSTargets(recordSet)
if len(targets) == 0 {
log.Debugf("Failed to extract targets for '%s' with type '%s'.", name, recordType)
continue
}
var ttl endpoint.TTL
if recordSet.Properties.TTL != nil {
ttl = endpoint.TTL(*recordSet.Properties.TTL)
}
ep := endpoint.NewEndpointWithTTL(name, recordType, ttl, targets...)
log.Debugf(
"Found %s record for '%s' with target '%s'.",
ep.RecordType,
ep.DNSName,
ep.Targets,
)
endpoints = append(endpoints, ep)
}
}
}
@ -165,49 +171,25 @@ func (p *AzurePrivateDNSProvider) zones(ctx context.Context) ([]privatedns.Priva
var zones []privatedns.PrivateZone
i, err := p.zonesClient.ListByResourceGroupComplete(ctx, p.resourceGroup, nil)
if err != nil {
return nil, err
}
for i.NotDone() {
zone := i.Value()
log.Debugf("Validating Zone: %v", *zone.Name)
if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) {
zones = append(zones, zone)
}
err := i.NextWithContext(ctx)
pager := p.zonesClient.NewListByResourceGroupPager(p.resourceGroup, &privatedns.PrivateZonesClientListByResourceGroupOptions{Top: nil})
for pager.More() {
nextResult, err := pager.NextPage(ctx)
if err != nil {
return nil, err
}
for _, zone := range nextResult.Value {
log.Debugf("Validating Zone: %v", *zone.Name)
if zone.Name != nil && p.domainFilter.Match(*zone.Name) && p.zoneIDFilter.Match(*zone.ID) {
zones = append(zones, *zone)
}
}
}
log.Debugf("Found %d Azure Private DNS zone(s).", len(zones))
return zones, nil
}
func (p *AzurePrivateDNSProvider) iterateRecords(ctx context.Context, zoneName string, callback func(privatedns.RecordSet)) error {
log.Debugf("Retrieving Azure Private DNS Records for zone '%s'.", zoneName)
i, err := p.recordSetsClient.ListComplete(ctx, p.resourceGroup, zoneName, nil, "")
if err != nil {
return err
}
for i.NotDone() {
callback(i.Value())
err := i.NextWithContext(ctx)
if err != nil {
return err
}
}
return nil
}
type azurePrivateDNSChangeMap map[string][]*endpoint.Endpoint
func (p *AzurePrivateDNSProvider) mapChanges(zones []privatedns.PrivateZone, changes *plan.Changes) (azurePrivateDNSChangeMap, azurePrivateDNSChangeMap) {
@ -257,7 +239,7 @@ func (p *AzurePrivateDNSProvider) deleteRecords(ctx context.Context, deleted azu
log.Infof("Would delete %s record named '%s' for Azure Private DNS zone '%s'.", ep.RecordType, name, zone)
} else {
log.Infof("Deleting %s record named '%s' for Azure Private DNS zone '%s'.", ep.RecordType, name, zone)
if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, privatedns.RecordType(ep.RecordType), name, ""); err != nil {
if _, err := p.recordSetsClient.Delete(ctx, p.resourceGroup, zone, privatedns.RecordType(ep.RecordType), name, nil); err != nil {
log.Errorf(
"Failed to delete %s record named '%s' for Azure Private DNS zone '%s': %v",
ep.RecordType,
@ -304,8 +286,7 @@ func (p *AzurePrivateDNSProvider) updateRecords(ctx context.Context, updated azu
privatedns.RecordType(ep.RecordType),
name,
recordSet,
"",
"",
nil,
)
}
if err != nil {
@ -341,51 +322,51 @@ func (p *AzurePrivateDNSProvider) newRecordSet(endpoint *endpoint.Endpoint) (pri
ttl = int64(endpoint.RecordTTL)
}
switch privatedns.RecordType(endpoint.RecordType) {
case privatedns.A:
aRecords := make([]privatedns.ARecord, len(endpoint.Targets))
case privatedns.RecordTypeA:
aRecords := make([]*privatedns.ARecord, len(endpoint.Targets))
for i, target := range endpoint.Targets {
aRecords[i] = privatedns.ARecord{
Ipv4Address: to.StringPtr(target),
aRecords[i] = &privatedns.ARecord{
IPv4Address: to.Ptr(target),
}
}
return privatedns.RecordSet{
RecordSetProperties: &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
ARecords: &aRecords,
Properties: &privatedns.RecordSetProperties{
TTL: to.Ptr(ttl),
ARecords: aRecords,
},
}, nil
case privatedns.CNAME:
case privatedns.RecordTypeCNAME:
return privatedns.RecordSet{
RecordSetProperties: &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
Properties: &privatedns.RecordSetProperties{
TTL: to.Ptr(ttl),
CnameRecord: &privatedns.CnameRecord{
Cname: to.StringPtr(endpoint.Targets[0]),
Cname: to.Ptr(endpoint.Targets[0]),
},
},
}, nil
case privatedns.MX:
mxRecords := make([]privatedns.MxRecord, len(endpoint.Targets))
case privatedns.RecordTypeMX:
mxRecords := make([]*privatedns.MxRecord, len(endpoint.Targets))
for i, target := range endpoint.Targets {
mxRecord, err := parseMxTarget[privatedns.MxRecord](target)
if err != nil {
return privatedns.RecordSet{}, err
}
mxRecords[i] = mxRecord
mxRecords[i] = &mxRecord
}
return privatedns.RecordSet{
RecordSetProperties: &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
MxRecords: &mxRecords,
Properties: &privatedns.RecordSetProperties{
TTL: to.Ptr(ttl),
MxRecords: mxRecords,
},
}, nil
case privatedns.TXT:
case privatedns.RecordTypeTXT:
return privatedns.RecordSet{
RecordSetProperties: &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TxtRecords: &[]privatedns.TxtRecord{
Properties: &privatedns.RecordSetProperties{
TTL: to.Ptr(ttl),
TxtRecords: []*privatedns.TxtRecord{
{
Value: &[]string{
endpoint.Targets[0],
Value: []*string{
&endpoint.Targets[0],
},
},
},
@ -397,17 +378,17 @@ func (p *AzurePrivateDNSProvider) newRecordSet(endpoint *endpoint.Endpoint) (pri
// Helper function (shared with test code)
func extractAzurePrivateDNSTargets(recordSet *privatedns.RecordSet) []string {
properties := recordSet.RecordSetProperties
properties := recordSet.Properties
if properties == nil {
return []string{}
}
// Check for A records
aRecords := properties.ARecords
if aRecords != nil && len(*aRecords) > 0 && (*aRecords)[0].Ipv4Address != nil {
targets := make([]string, len(*aRecords))
for i, aRecord := range *aRecords {
targets[i] = *aRecord.Ipv4Address
if len(aRecords) > 0 && (aRecords)[0].IPv4Address != nil {
targets := make([]string, len(aRecords))
for i, aRecord := range aRecords {
targets[i] = *aRecord.IPv4Address
}
return targets
}
@ -420,9 +401,9 @@ func extractAzurePrivateDNSTargets(recordSet *privatedns.RecordSet) []string {
// Check for MX records
mxRecords := properties.MxRecords
if mxRecords != nil && len(*mxRecords) > 0 && (*mxRecords)[0].Exchange != nil {
targets := make([]string, len(*mxRecords))
for i, mxRecord := range *mxRecords {
if len(mxRecords) > 0 && (mxRecords)[0].Exchange != nil {
targets := make([]string, len(mxRecords))
for i, mxRecord := range mxRecords {
targets[i] = fmt.Sprintf("%d %s", *mxRecord.Preference, *mxRecord.Exchange)
}
return targets
@ -430,10 +411,10 @@ func extractAzurePrivateDNSTargets(recordSet *privatedns.RecordSet) []string {
// Check for TXT records
txtRecords := properties.TxtRecords
if txtRecords != nil && len(*txtRecords) > 0 && (*txtRecords)[0].Value != nil {
values := (*txtRecords)[0].Value
if values != nil && len(*values) > 0 {
return []string{(*values)[0]}
if len(txtRecords) > 0 && (txtRecords)[0].Value != nil {
values := (txtRecords)[0].Value
if len(values) > 0 {
return []string{*(values)[0]}
}
}
return []string{}

View File

@ -20,9 +20,9 @@ import (
"context"
"testing"
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
azcoreruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
privatedns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns"
"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/plan"
"sigs.k8s.io/external-dns/provider"
@ -35,111 +35,138 @@ const (
// mockPrivateZonesClient implements the methods of the Azure Private DNS Zones Client which are used in the Azure Private DNS Provider
// and returns static results which are defined per test
type mockPrivateZonesClient struct {
mockZonesClientIterator *privatedns.PrivateZoneListResultIterator
pagingHandler azcoreruntime.PagingHandler[privatedns.PrivateZonesClientListByResourceGroupResponse]
}
func newMockPrivateZonesClient(zones []*privatedns.PrivateZone) mockPrivateZonesClient {
pagingHandler := azcoreruntime.PagingHandler[privatedns.PrivateZonesClientListByResourceGroupResponse]{
More: func(resp privatedns.PrivateZonesClientListByResourceGroupResponse) bool {
return false
},
Fetcher: func(context.Context, *privatedns.PrivateZonesClientListByResourceGroupResponse) (privatedns.PrivateZonesClientListByResourceGroupResponse, error) {
return privatedns.PrivateZonesClientListByResourceGroupResponse{
PrivateZoneListResult: privatedns.PrivateZoneListResult{
Value: zones,
},
}, nil
},
}
return mockPrivateZonesClient{
pagingHandler: pagingHandler,
}
}
func (client *mockPrivateZonesClient) NewListByResourceGroupPager(resourceGroupName string, options *privatedns.PrivateZonesClientListByResourceGroupOptions) *azcoreruntime.Pager[privatedns.PrivateZonesClientListByResourceGroupResponse] {
return azcoreruntime.NewPager(client.pagingHandler)
}
// mockPrivateRecordSetsClient implements the methods of the Azure Private DNS RecordSet Client which are used in the Azure Private DNS Provider
// and returns static results which are defined per test
type mockPrivateRecordSetsClient struct {
mockRecordSetListIterator *privatedns.RecordSetListResultIterator
deletedEndpoints []*endpoint.Endpoint
updatedEndpoints []*endpoint.Endpoint
pagingHandler azcoreruntime.PagingHandler[privatedns.RecordSetsClientListResponse]
deletedEndpoints []*endpoint.Endpoint
updatedEndpoints []*endpoint.Endpoint
}
// mockPrivateZoneListResultPageIterator is used to paginate forward through a list of zones
type mockPrivateZoneListResultPageIterator struct {
offset int
results []privatedns.PrivateZoneListResult
}
// getNextPage provides the next page based on the offset of the mockZoneListResultPageIterator
func (m *mockPrivateZoneListResultPageIterator) getNextPage(context.Context, privatedns.PrivateZoneListResult) (privatedns.PrivateZoneListResult, error) {
// it assumed that instances of this kind of iterator are only skimmed through once per test
// otherwise a real implementation is required, e.g. based on a linked list
if m.offset < len(m.results) {
m.offset++
return m.results[m.offset-1], nil
func newMockPrivateRecordSectsClient(recordSets []*privatedns.RecordSet) mockPrivateRecordSetsClient {
pagingHandler := azcoreruntime.PagingHandler[privatedns.RecordSetsClientListResponse]{
More: func(resp privatedns.RecordSetsClientListResponse) bool {
return false
},
Fetcher: func(context.Context, *privatedns.RecordSetsClientListResponse) (privatedns.RecordSetsClientListResponse, error) {
return privatedns.RecordSetsClientListResponse{
RecordSetListResult: privatedns.RecordSetListResult{
Value: recordSets,
},
}, nil
},
}
// paged to last page or empty
return privatedns.PrivateZoneListResult{}, nil
}
// mockPrivateRecordSetListResultPageIterator is used to paginate forward through a list of recordsets
type mockPrivateRecordSetListResultPageIterator struct {
offset int
results []privatedns.RecordSetListResult
}
// getNextPage provides the next page based on the offset of the mockRecordSetListResultPageIterator
func (m *mockPrivateRecordSetListResultPageIterator) getNextPage(context.Context, privatedns.RecordSetListResult) (privatedns.RecordSetListResult, error) {
// it assumed that instances of this kind of iterator are only skimmed through once per test
// otherwise a real implementation is required, e.g. based on a linked list
if m.offset < len(m.results) {
m.offset++
return m.results[m.offset-1], nil
}
// paged to last page or empty
return privatedns.RecordSetListResult{}, nil
}
func createMockPrivateZone(zone string, id string) privatedns.PrivateZone {
return privatedns.PrivateZone{
ID: to.StringPtr(id),
Name: to.StringPtr(zone),
return mockPrivateRecordSetsClient{
pagingHandler: pagingHandler,
}
}
func (client *mockPrivateZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result privatedns.PrivateZoneListResultIterator, err error) {
// pre-iterate to first item to emulate behaviour of Azure SDK
err = client.mockZonesClientIterator.NextWithContext(ctx)
if err != nil {
return *client.mockZonesClientIterator, err
}
func (client *mockPrivateRecordSetsClient) NewListPager(resourceGroupName string, privateZoneName string, options *privatedns.RecordSetsClientListOptions) *azcoreruntime.Pager[privatedns.RecordSetsClientListResponse] {
return azcoreruntime.NewPager(client.pagingHandler)
}
return *client.mockZonesClientIterator, nil
func (client *mockPrivateRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, options *privatedns.RecordSetsClientDeleteOptions) (privatedns.RecordSetsClientDeleteResponse, error) {
client.deletedEndpoints = append(
client.deletedEndpoints,
endpoint.NewEndpoint(
formatAzureDNSName(relativeRecordSetName, privateZoneName),
string(recordType),
"",
),
)
return privatedns.RecordSetsClientDeleteResponse{}, nil
}
func (client *mockPrivateRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, parameters privatedns.RecordSet, options *privatedns.RecordSetsClientCreateOrUpdateOptions) (privatedns.RecordSetsClientCreateOrUpdateResponse, error) {
var ttl endpoint.TTL
if parameters.Properties.TTL != nil {
ttl = endpoint.TTL(*parameters.Properties.TTL)
}
client.updatedEndpoints = append(
client.updatedEndpoints,
endpoint.NewEndpointWithTTL(
formatAzureDNSName(relativeRecordSetName, privateZoneName),
string(recordType),
ttl,
extractAzurePrivateDNSTargets(&parameters)...,
),
)
return privatedns.RecordSetsClientCreateOrUpdateResponse{}, nil
//return parameters, nil
}
func createMockPrivateZone(zone string, id string) *privatedns.PrivateZone {
return &privatedns.PrivateZone{
ID: to.Ptr(id),
Name: to.Ptr(zone),
}
}
func privateARecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties {
aRecords := make([]privatedns.ARecord, len(values))
aRecords := make([]*privatedns.ARecord, len(values))
for i, value := range values {
aRecords[i] = privatedns.ARecord{
Ipv4Address: to.StringPtr(value),
aRecords[i] = &privatedns.ARecord{
IPv4Address: to.Ptr(value),
}
}
return &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
ARecords: &aRecords,
TTL: to.Ptr(ttl),
ARecords: aRecords,
}
}
func privateCNameRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties {
return &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TTL: to.Ptr(ttl),
CnameRecord: &privatedns.CnameRecord{
Cname: to.StringPtr(values[0]),
Cname: to.Ptr(values[0]),
},
}
}
func privateMXRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties {
mxRecords := make([]privatedns.MxRecord, len(values))
mxRecords := make([]*privatedns.MxRecord, len(values))
for i, target := range values {
mxRecords[i], _ = parseMxTarget[privatedns.MxRecord](target)
mxRecord, _ := parseMxTarget[privatedns.MxRecord](target)
mxRecords[i] = &mxRecord
}
return &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
MxRecords: &mxRecords,
TTL: to.Ptr(ttl),
MxRecords: mxRecords,
}
}
func privateTxtRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties {
return &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TxtRecords: &[]privatedns.TxtRecord{
TTL: to.Ptr(ttl),
TxtRecords: []*privatedns.TxtRecord{
{
Value: &[]string{values[0]},
Value: []*string{&values[0]},
},
},
}
@ -147,19 +174,19 @@ func privateTxtRecordSetPropertiesGetter(values []string, ttl int64) *privatedns
func privateOthersRecordSetPropertiesGetter(values []string, ttl int64) *privatedns.RecordSetProperties {
return &privatedns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TTL: to.Ptr(ttl),
}
}
func createPrivateMockRecordSet(name, recordType string, values ...string) privatedns.RecordSet {
func createPrivateMockRecordSet(name, recordType string, values ...string) *privatedns.RecordSet {
return createPrivateMockRecordSetMultiWithTTL(name, recordType, 0, values...)
}
func createPrivateMockRecordSetWithTTL(name, recordType, value string, ttl int64) privatedns.RecordSet {
func createPrivateMockRecordSetWithTTL(name, recordType, value string, ttl int64) *privatedns.RecordSet {
return createPrivateMockRecordSetMultiWithTTL(name, recordType, ttl, value)
}
func createPrivateMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values ...string) privatedns.RecordSet {
func createPrivateMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values ...string) *privatedns.RecordSet {
var getterFunc func(values []string, ttl int64) *privatedns.RecordSetProperties
switch recordType {
@ -174,84 +201,17 @@ func createPrivateMockRecordSetMultiWithTTL(name, recordType string, ttl int64,
default:
getterFunc = privateOthersRecordSetPropertiesGetter
}
return privatedns.RecordSet{
Name: to.StringPtr(name),
Type: to.StringPtr("Microsoft.Network/privateDnsZones/" + recordType),
RecordSetProperties: getterFunc(values, ttl),
return &privatedns.RecordSet{
Name: to.Ptr(name),
Type: to.Ptr("Microsoft.Network/privateDnsZones/" + recordType),
Properties: getterFunc(values, ttl),
}
}
func (client *mockPrivateRecordSetsClient) ListComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result privatedns.RecordSetListResultIterator, err error) {
// pre-iterate to first item to emulate behaviour of Azure SDK
err = client.mockRecordSetListIterator.NextWithContext(ctx)
if err != nil {
return *client.mockRecordSetListIterator, err
}
return *client.mockRecordSetListIterator, nil
}
func (client *mockPrivateRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, err error) {
client.deletedEndpoints = append(
client.deletedEndpoints,
endpoint.NewEndpoint(
formatAzureDNSName(relativeRecordSetName, privateZoneName),
string(recordType),
"",
),
)
return autorest.Response{}, nil
}
func (client *mockPrivateRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType privatedns.RecordType, relativeRecordSetName string, parameters privatedns.RecordSet, ifMatch string, ifNoneMatch string) (result privatedns.RecordSet, err error) {
var ttl endpoint.TTL
if parameters.TTL != nil {
ttl = endpoint.TTL(*parameters.TTL)
}
client.updatedEndpoints = append(
client.updatedEndpoints,
endpoint.NewEndpointWithTTL(
formatAzureDNSName(relativeRecordSetName, privateZoneName),
string(recordType),
ttl,
extractAzurePrivateDNSTargets(&parameters)...,
),
)
return parameters, nil
}
// newMockedAzurePrivateDNSProvider creates an AzureProvider comprising the mocked clients for zones and recordsets
func newMockedAzurePrivateDNSProvider(domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, zones *[]privatedns.PrivateZone, recordSets *[]privatedns.RecordSet) (*AzurePrivateDNSProvider, error) {
// init zone-related parts of the mock-client
pageIterator := mockPrivateZoneListResultPageIterator{
results: []privatedns.PrivateZoneListResult{
{
Value: zones,
},
},
}
mockZoneListResultPage := privatedns.NewPrivateZoneListResultPage(privatedns.PrivateZoneListResult{}, pageIterator.getNextPage)
mockZoneClientIterator := privatedns.NewPrivateZoneListResultIterator(mockZoneListResultPage)
zonesClient := mockPrivateZonesClient{
mockZonesClientIterator: &mockZoneClientIterator,
}
// init record-related parts of the mock-client
resultPageIterator := mockPrivateRecordSetListResultPageIterator{
results: []privatedns.RecordSetListResult{
{
Value: recordSets,
},
},
}
mockRecordSetListResultPage := privatedns.NewRecordSetListResultPage(privatedns.RecordSetListResult{}, resultPageIterator.getNextPage)
mockRecordSetListIterator := privatedns.NewRecordSetListResultIterator(mockRecordSetListResultPage)
recordSetsClient := mockPrivateRecordSetsClient{
mockRecordSetListIterator: &mockRecordSetListIterator,
}
func newMockedAzurePrivateDNSProvider(domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, zones []*privatedns.PrivateZone, recordSets []*privatedns.RecordSet) (*AzurePrivateDNSProvider, error) {
zonesClient := newMockPrivateZonesClient(zones)
recordSetsClient := newMockPrivateRecordSectsClient(recordSets)
return newAzurePrivateDNSProvider(domainFilter, zoneIDFilter, dryRun, resourceGroup, &zonesClient, &recordSetsClient), nil
}
@ -268,10 +228,10 @@ func newAzurePrivateDNSProvider(domainFilter endpoint.DomainFilter, zoneIDFilter
func TestAzurePrivateDNSRecord(t *testing.T) {
provider, err := newMockedAzurePrivateDNSProvider(endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true, "k8s",
&[]privatedns.PrivateZone{
[]*privatedns.PrivateZone{
createMockPrivateZone("example.com", "/privateDnsZones/example.com"),
},
&[]privatedns.RecordSet{
[]*privatedns.RecordSet{
createPrivateMockRecordSet("@", "NS", "ns1-03.azure-dns.com."),
createPrivateMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"),
createPrivateMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"),
@ -303,10 +263,10 @@ func TestAzurePrivateDNSRecord(t *testing.T) {
func TestAzurePrivateDNSMultiRecord(t *testing.T) {
provider, err := newMockedAzurePrivateDNSProvider(endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true, "k8s",
&[]privatedns.PrivateZone{
[]*privatedns.PrivateZone{
createMockPrivateZone("example.com", "/privateDnsZones/example.com"),
},
&[]privatedns.RecordSet{
[]*privatedns.RecordSet{
createPrivateMockRecordSet("@", "NS", "ns1-03.azure-dns.com."),
createPrivateMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"),
createPrivateMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122", "234.234.234.233"),
@ -374,30 +334,11 @@ func TestAzurePrivateDNSApplyChangesDryRun(t *testing.T) {
}
func testAzurePrivateDNSApplyChangesInternal(t *testing.T, dryRun bool, client PrivateRecordSetsClient) {
zlr := privatedns.PrivateZoneListResult{
Value: &[]privatedns.PrivateZone{
createMockPrivateZone("example.com", "/privateDnsZones/example.com"),
createMockPrivateZone("other.com", "/privateDnsZones/other.com"),
},
}
results := []privatedns.PrivateZoneListResult{
zlr,
}
mockZoneListResultPage := privatedns.NewPrivateZoneListResultPage(privatedns.PrivateZoneListResult{}, func(ctxParam context.Context, zlrParam privatedns.PrivateZoneListResult) (privatedns.PrivateZoneListResult, error) {
if len(results) > 0 {
result := results[0]
results = nil
return result, nil
}
return privatedns.PrivateZoneListResult{}, nil
})
mockZoneClientIterator := privatedns.NewPrivateZoneListResultIterator(mockZoneListResultPage)
zonesClient := mockPrivateZonesClient{
mockZonesClientIterator: &mockZoneClientIterator,
zones := []*privatedns.PrivateZone{
createMockPrivateZone("example.com", "/privateDnsZones/example.com"),
createMockPrivateZone("other.com", "/privateDnsZones/other.com"),
}
zonesClient := newMockPrivateZonesClient(zones)
provider := newAzurePrivateDNSProvider(
endpoint.NewDomainFilter([]string{""}),

View File

@ -20,9 +20,9 @@ import (
"context"
"testing"
"github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/to"
azcoreruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
dns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/external-dns/endpoint"
@ -34,111 +34,137 @@ import (
// mockZonesClient implements the methods of the Azure DNS Zones Client which are used in the Azure Provider
// and returns static results which are defined per test
type mockZonesClient struct {
mockZonesClientIterator *dns.ZoneListResultIterator
pagingHandler azcoreruntime.PagingHandler[dns.ZonesClientListByResourceGroupResponse]
}
func newMockZonesClient(zones []*dns.Zone) mockZonesClient {
pagingHandler := azcoreruntime.PagingHandler[dns.ZonesClientListByResourceGroupResponse]{
More: func(resp dns.ZonesClientListByResourceGroupResponse) bool {
return false
},
Fetcher: func(context.Context, *dns.ZonesClientListByResourceGroupResponse) (dns.ZonesClientListByResourceGroupResponse, error) {
return dns.ZonesClientListByResourceGroupResponse{
ZoneListResult: dns.ZoneListResult{
Value: zones,
},
}, nil
},
}
return mockZonesClient{
pagingHandler: pagingHandler,
}
}
func (client *mockZonesClient) NewListByResourceGroupPager(resourceGroupName string, options *dns.ZonesClientListByResourceGroupOptions) *azcoreruntime.Pager[dns.ZonesClientListByResourceGroupResponse] {
return azcoreruntime.NewPager(client.pagingHandler)
}
// mockZonesClient implements the methods of the Azure DNS RecordSet Client which are used in the Azure Provider
// and returns static results which are defined per test
type mockRecordSetsClient struct {
mockRecordSetListIterator *dns.RecordSetListResultIterator
deletedEndpoints []*endpoint.Endpoint
updatedEndpoints []*endpoint.Endpoint
pagingHandler azcoreruntime.PagingHandler[dns.RecordSetsClientListAllByDNSZoneResponse]
deletedEndpoints []*endpoint.Endpoint
updatedEndpoints []*endpoint.Endpoint
}
// mockZoneListResultPageIterator is used to paginate forward through a list of zones
type mockZoneListResultPageIterator struct {
offset int
results []dns.ZoneListResult
}
// getNextPage provides the next page based on the offset of the mockZoneListResultPageIterator
func (m *mockZoneListResultPageIterator) getNextPage(context.Context, dns.ZoneListResult) (dns.ZoneListResult, error) {
// it assumed that instances of this kind of iterator are only skimmed through once per test
// otherwise a real implementation is required, e.g. based on a linked list
if m.offset < len(m.results) {
m.offset++
return m.results[m.offset-1], nil
func newMockRecordSetsClient(recordSets []*dns.RecordSet) mockRecordSetsClient {
pagingHandler := azcoreruntime.PagingHandler[dns.RecordSetsClientListAllByDNSZoneResponse]{
More: func(resp dns.RecordSetsClientListAllByDNSZoneResponse) bool {
return false
},
Fetcher: func(context.Context, *dns.RecordSetsClientListAllByDNSZoneResponse) (dns.RecordSetsClientListAllByDNSZoneResponse, error) {
return dns.RecordSetsClientListAllByDNSZoneResponse{
RecordSetListResult: dns.RecordSetListResult{
Value: recordSets,
},
}, nil
},
}
// paged to last page or empty
return dns.ZoneListResult{}, nil
}
// mockZoneListResultPageIterator is used to paginate forward through a list of recordsets
type mockRecordSetListResultPageIterator struct {
offset int
results []dns.RecordSetListResult
}
// getNextPage provides the next page based on the offset of the mockRecordSetListResultPageIterator
func (m *mockRecordSetListResultPageIterator) getNextPage(context.Context, dns.RecordSetListResult) (dns.RecordSetListResult, error) {
// it assumed that instances of this kind of iterator are only skimmed through once per test
// otherwise a real implementation is required, e.g. based on a linked list
if m.offset < len(m.results) {
m.offset++
return m.results[m.offset-1], nil
}
// paged to last page or empty
return dns.RecordSetListResult{}, nil
}
func createMockZone(zone string, id string) dns.Zone {
return dns.Zone{
ID: to.StringPtr(id),
Name: to.StringPtr(zone),
return mockRecordSetsClient{
pagingHandler: pagingHandler,
}
}
func (client *mockZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result dns.ZoneListResultIterator, err error) {
// pre-iterate to first item to emulate behaviour of Azure SDK
err = client.mockZonesClientIterator.NextWithContext(ctx)
if err != nil {
return *client.mockZonesClientIterator, err
}
func (client *mockRecordSetsClient) NewListAllByDNSZonePager(resourceGroupName string, zoneName string, options *dns.RecordSetsClientListAllByDNSZoneOptions) *azcoreruntime.Pager[dns.RecordSetsClientListAllByDNSZoneResponse] {
return azcoreruntime.NewPager(client.pagingHandler)
}
return *client.mockZonesClientIterator, nil
func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, options *dns.RecordSetsClientDeleteOptions) (dns.RecordSetsClientDeleteResponse, error) {
client.deletedEndpoints = append(
client.deletedEndpoints,
endpoint.NewEndpoint(
formatAzureDNSName(relativeRecordSetName, zoneName),
string(recordType),
"",
),
)
return dns.RecordSetsClientDeleteResponse{}, nil
}
func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, options *dns.RecordSetsClientCreateOrUpdateOptions) (dns.RecordSetsClientCreateOrUpdateResponse, error) {
var ttl endpoint.TTL
if parameters.Properties.TTL != nil {
ttl = endpoint.TTL(*parameters.Properties.TTL)
}
client.updatedEndpoints = append(
client.updatedEndpoints,
endpoint.NewEndpointWithTTL(
formatAzureDNSName(relativeRecordSetName, zoneName),
string(recordType),
ttl,
extractAzureTargets(&parameters)...,
),
)
return dns.RecordSetsClientCreateOrUpdateResponse{}, nil
}
func createMockZone(zone string, id string) *dns.Zone {
return &dns.Zone{
ID: to.Ptr(id),
Name: to.Ptr(zone),
}
}
func aRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties {
aRecords := make([]dns.ARecord, len(values))
aRecords := make([]*dns.ARecord, len(values))
for i, value := range values {
aRecords[i] = dns.ARecord{
Ipv4Address: to.StringPtr(value),
aRecords[i] = &dns.ARecord{
IPv4Address: to.Ptr(value),
}
}
return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
ARecords: &aRecords,
TTL: to.Ptr(ttl),
ARecords: aRecords,
}
}
func cNameRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TTL: to.Ptr(ttl),
CnameRecord: &dns.CnameRecord{
Cname: to.StringPtr(values[0]),
Cname: to.Ptr(values[0]),
},
}
}
func mxRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties {
mxRecords := make([]dns.MxRecord, len(values))
mxRecords := make([]*dns.MxRecord, len(values))
for i, target := range values {
mxRecords[i], _ = parseMxTarget[dns.MxRecord](target)
mxRecord, _ := parseMxTarget[dns.MxRecord](target)
mxRecords[i] = &mxRecord
}
return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
MxRecords: &mxRecords,
TTL: to.Ptr(ttl),
MxRecords: mxRecords,
}
}
func txtRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TxtRecords: &[]dns.TxtRecord{
TTL: to.Ptr(ttl),
TxtRecords: []*dns.TxtRecord{
{
Value: &[]string{values[0]},
Value: []*string{to.Ptr(values[0])},
},
},
}
@ -146,19 +172,19 @@ func txtRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProp
func othersRecordSetPropertiesGetter(values []string, ttl int64) *dns.RecordSetProperties {
return &dns.RecordSetProperties{
TTL: to.Int64Ptr(ttl),
TTL: to.Ptr(ttl),
}
}
func createMockRecordSet(name, recordType string, values ...string) dns.RecordSet {
func createMockRecordSet(name, recordType string, values ...string) *dns.RecordSet {
return createMockRecordSetMultiWithTTL(name, recordType, 0, values...)
}
func createMockRecordSetWithTTL(name, recordType, value string, ttl int64) dns.RecordSet {
func createMockRecordSetWithTTL(name, recordType, value string, ttl int64) *dns.RecordSet {
return createMockRecordSetMultiWithTTL(name, recordType, ttl, value)
}
func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values ...string) dns.RecordSet {
func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values ...string) *dns.RecordSet {
var getterFunc func(values []string, ttl int64) *dns.RecordSetProperties
switch recordType {
@ -173,84 +199,17 @@ func createMockRecordSetMultiWithTTL(name, recordType string, ttl int64, values
default:
getterFunc = othersRecordSetPropertiesGetter
}
return dns.RecordSet{
Name: to.StringPtr(name),
Type: to.StringPtr("Microsoft.Network/dnszones/" + recordType),
RecordSetProperties: getterFunc(values, ttl),
return &dns.RecordSet{
Name: to.Ptr(name),
Type: to.Ptr("Microsoft.Network/dnszones/" + recordType),
Properties: getterFunc(values, ttl),
}
}
func (client *mockRecordSetsClient) ListAllByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result dns.RecordSetListResultIterator, err error) {
// pre-iterate to first item to emulate behaviour of Azure SDK
err = client.mockRecordSetListIterator.NextWithContext(ctx)
if err != nil {
return *client.mockRecordSetListIterator, err
}
return *client.mockRecordSetListIterator, nil
}
func (client *mockRecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, ifMatch string) (result autorest.Response, err error) {
client.deletedEndpoints = append(
client.deletedEndpoints,
endpoint.NewEndpoint(
formatAzureDNSName(relativeRecordSetName, zoneName),
string(recordType),
"",
),
)
return autorest.Response{}, nil
}
func (client *mockRecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType dns.RecordType, parameters dns.RecordSet, ifMatch string, ifNoneMatch string) (result dns.RecordSet, err error) {
var ttl endpoint.TTL
if parameters.TTL != nil {
ttl = endpoint.TTL(*parameters.TTL)
}
client.updatedEndpoints = append(
client.updatedEndpoints,
endpoint.NewEndpointWithTTL(
formatAzureDNSName(relativeRecordSetName, zoneName),
string(recordType),
ttl,
extractAzureTargets(&parameters)...,
),
)
return parameters, nil
}
// newMockedAzureProvider creates an AzureProvider comprising the mocked clients for zones and recordsets
func newMockedAzureProvider(domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zones *[]dns.Zone, recordSets *[]dns.RecordSet) (*AzureProvider, error) {
// init zone-related parts of the mock-client
pageIterator := mockZoneListResultPageIterator{
results: []dns.ZoneListResult{
{
Value: zones,
},
},
}
mockZoneListResultPage := dns.NewZoneListResultPage(dns.ZoneListResult{}, pageIterator.getNextPage)
mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage)
zonesClient := mockZonesClient{
mockZonesClientIterator: &mockZoneClientIterator,
}
// init record-related parts of the mock-client
resultPageIterator := mockRecordSetListResultPageIterator{
results: []dns.RecordSetListResult{
{
Value: recordSets,
},
},
}
mockRecordSetListResultPage := dns.NewRecordSetListResultPage(dns.RecordSetListResult{}, resultPageIterator.getNextPage)
mockRecordSetListIterator := dns.NewRecordSetListResultIterator(mockRecordSetListResultPage)
recordSetsClient := mockRecordSetsClient{
mockRecordSetListIterator: &mockRecordSetListIterator,
}
func newMockedAzureProvider(domainFilter endpoint.DomainFilter, zoneNameFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, dryRun bool, resourceGroup string, userAssignedIdentityClientID string, zones []*dns.Zone, recordSets []*dns.RecordSet) (*AzureProvider, error) {
zonesClient := newMockZonesClient(zones)
recordSetsClient := newMockRecordSetsClient(recordSets)
return newAzureProvider(domainFilter, zoneNameFilter, zoneIDFilter, dryRun, resourceGroup, userAssignedIdentityClientID, &zonesClient, &recordSetsClient), nil
}
@ -273,10 +232,10 @@ func validateAzureEndpoints(t *testing.T, endpoints []*endpoint.Endpoint, expect
func TestAzureRecord(t *testing.T) {
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"example.com"}), endpoint.NewDomainFilter([]string{}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "",
&[]dns.Zone{
[]*dns.Zone{
createMockZone("example.com", "/dnszones/example.com"),
},
&[]dns.RecordSet{
[]*dns.RecordSet{
createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."),
createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"),
createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"),
@ -309,10 +268,10 @@ func TestAzureRecord(t *testing.T) {
func TestAzureMultiRecord(t *testing.T) {
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"example.com"}), endpoint.NewDomainFilter([]string{}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "",
&[]dns.Zone{
[]*dns.Zone{
createMockZone("example.com", "/dnszones/example.com"),
},
&[]dns.RecordSet{
[]*dns.RecordSet{
createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."),
createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"),
createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122", "234.234.234.233"),
@ -381,30 +340,11 @@ func TestAzureApplyChangesDryRun(t *testing.T) {
}
func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsClient) {
zlr := dns.ZoneListResult{
Value: &[]dns.Zone{
createMockZone("example.com", "/dnszones/example.com"),
createMockZone("other.com", "/dnszones/other.com"),
},
}
results := []dns.ZoneListResult{
zlr,
}
mockZoneListResultPage := dns.NewZoneListResultPage(dns.ZoneListResult{}, func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) {
if len(results) > 0 {
result := results[0]
results = nil
return result, nil
}
return dns.ZoneListResult{}, nil
})
mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage)
zonesClient := mockZonesClient{
mockZonesClientIterator: &mockZoneClientIterator,
zones := []*dns.Zone{
createMockZone("example.com", "/dnszones/example.com"),
createMockZone("other.com", "/dnszones/other.com"),
}
zonesClient := newMockZonesClient(zones)
provider := newAzureProvider(
endpoint.NewDomainFilter([]string{""}),
@ -465,11 +405,11 @@ func testAzureApplyChangesInternal(t *testing.T, dryRun bool, client RecordSetsC
func TestAzureNameFilter(t *testing.T) {
provider, err := newMockedAzureProvider(endpoint.NewDomainFilter([]string{"nginx.example.com"}), endpoint.NewDomainFilter([]string{"example.com"}), provider.NewZoneIDFilter([]string{""}), true, "k8s", "",
&[]dns.Zone{
[]*dns.Zone{
createMockZone("example.com", "/dnszones/example.com"),
},
&[]dns.RecordSet{
[]*dns.RecordSet{
createMockRecordSet("@", "NS", "ns1-03.azure-dns.com."),
createMockRecordSet("@", "SOA", "Email: azuredns-hostmaster.microsoft.com"),
createMockRecordSet("@", endpoint.RecordTypeA, "123.123.123.122"),
@ -518,29 +458,7 @@ func TestAzureApplyChangesZoneName(t *testing.T) {
}
func testAzureApplyChangesInternalZoneName(t *testing.T, dryRun bool, client RecordSetsClient) {
zlr := dns.ZoneListResult{
Value: &[]dns.Zone{
createMockZone("example.com", "/dnszones/example.com"),
},
}
results := []dns.ZoneListResult{
zlr,
}
mockZoneListResultPage := dns.NewZoneListResultPage(dns.ZoneListResult{}, func(ctxParam context.Context, zlrParam dns.ZoneListResult) (dns.ZoneListResult, error) {
if len(results) > 0 {
result := results[0]
results = nil
return result, nil
}
return dns.ZoneListResult{}, nil
})
mockZoneClientIterator := dns.NewZoneListResultIterator(mockZoneListResultPage)
zonesClient := mockZonesClient{
mockZonesClientIterator: &mockZoneClientIterator,
}
zonesClient := newMockZonesClient([]*dns.Zone{createMockZone("example.com", "/dnszones/example.com")})
provider := newAzureProvider(
endpoint.NewDomainFilter([]string{"foo.example.com"}),

View File

@ -22,9 +22,9 @@ import (
"strconv"
"strings"
"github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
"github.com/Azure/go-autorest/autorest/to"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
dns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns"
privatedns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns"
)
// Helper function (shared with test code)
@ -41,7 +41,7 @@ func parseMxTarget[T dns.MxRecord | privatedns.MxRecord](mxTarget string) (T, er
}
return T{
Preference: to.Int32Ptr(int32(preference)),
Exchange: to.StringPtr(exchange),
Preference: to.Ptr(int32(preference)),
Exchange: to.Ptr(exchange),
}, nil
}

View File

@ -20,9 +20,9 @@ import (
"fmt"
"testing"
"github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
"github.com/Azure/go-autorest/autorest/to"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
dns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns"
privatedns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns"
"github.com/stretchr/testify/assert"
)
@ -42,8 +42,8 @@ func Test_parseMxTarget(t *testing.T) {
name: "valid mx target",
args: "10 example.com",
want: dns.MxRecord{
Preference: to.Int32Ptr(int32(10)),
Exchange: to.StringPtr("example.com"),
Preference: to.Ptr(int32(10)),
Exchange: to.Ptr("example.com"),
},
wantErr: assert.NoError,
},
@ -51,8 +51,8 @@ func Test_parseMxTarget(t *testing.T) {
name: "valid mx target with a subdomain",
args: "99 foo-bar.example.com",
want: dns.MxRecord{
Preference: to.Int32Ptr(int32(99)),
Exchange: to.StringPtr("foo-bar.example.com"),
Preference: to.Ptr(int32(99)),
Exchange: to.Ptr("foo-bar.example.com"),
},
wantErr: assert.NoError,
},

View File

@ -21,24 +21,24 @@ import (
"os"
"strings"
"github.com/Azure/go-autorest/autorest/adal"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
// config represents common config items for Azure DNS and Azure Private DNS
type config struct {
Cloud string `json:"cloud" yaml:"cloud"`
Environment azure.Environment `json:"-" yaml:"-"`
TenantID string `json:"tenantId" yaml:"tenantId"`
SubscriptionID string `json:"subscriptionId" yaml:"subscriptionId"`
ResourceGroup string `json:"resourceGroup" yaml:"resourceGroup"`
Location string `json:"location" yaml:"location"`
ClientID string `json:"aadClientId" yaml:"aadClientId"`
ClientSecret string `json:"aadClientSecret" yaml:"aadClientSecret"`
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension" yaml:"useManagedIdentityExtension"`
UserAssignedIdentityID string `json:"userAssignedIdentityID" yaml:"userAssignedIdentityID"`
Cloud string `json:"cloud" yaml:"cloud"`
TenantID string `json:"tenantId" yaml:"tenantId"`
SubscriptionID string `json:"subscriptionId" yaml:"subscriptionId"`
ResourceGroup string `json:"resourceGroup" yaml:"resourceGroup"`
Location string `json:"location" yaml:"location"`
ClientID string `json:"aadClientId" yaml:"aadClientId"`
ClientSecret string `json:"aadClientSecret" yaml:"aadClientSecret"`
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension" yaml:"useManagedIdentityExtension"`
UserAssignedIdentityID string `json:"userAssignedIdentityID" yaml:"userAssignedIdentityID"`
}
func getConfig(configFile, resourceGroup, userAssignedIdentityClientID string) (*config, error) {
@ -60,23 +60,16 @@ func getConfig(configFile, resourceGroup, userAssignedIdentityClientID string) (
if userAssignedIdentityClientID != "" {
cfg.UserAssignedIdentityID = userAssignedIdentityClientID
}
var environment azure.Environment
if cfg.Cloud == "" {
environment = azure.PublicCloud
} else {
environment, err = azure.EnvironmentFromName(cfg.Cloud)
if err != nil {
return nil, fmt.Errorf("invalid cloud value '%s': %v", cfg.Cloud, err)
}
}
cfg.Environment = environment
return cfg, nil
}
// getAccessToken retrieves Azure API access token.
func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePrincipalToken, error) {
func getCredentials(cfg config) (azcore.TokenCredential, error) {
cloudCfg, err := getCloudConfiguration(cfg.Cloud)
if err != nil {
return nil, err
}
// Try to retrieve token with service principal credentials.
// Try to use service principal first, some AKS clusters are in an intermediate state that `UseManagedIdentityExtension` is `true`
// and service principal exists. In this case, we still want to use service principal to authenticate.
@ -88,40 +81,48 @@ func getAccessToken(cfg config, environment azure.Environment) (*adal.ServicePri
!strings.EqualFold(cfg.ClientID, "msi") &&
!strings.EqualFold(cfg.ClientSecret, "msi") {
log.Info("Using client_id+client_secret to retrieve access token for Azure API.")
oauthConfig, err := adal.NewOAuthConfig(environment.ActiveDirectoryEndpoint, cfg.TenantID)
if err != nil {
return nil, fmt.Errorf("failed to retrieve OAuth config: %v", err)
opts := &azidentity.ClientSecretCredentialOptions{
ClientOptions: azcore.ClientOptions{
Cloud: cloudCfg,
},
}
token, err := adal.NewServicePrincipalToken(*oauthConfig, cfg.ClientID, cfg.ClientSecret, environment.ResourceManagerEndpoint)
cred, err := azidentity.NewClientSecretCredential(cfg.TenantID, cfg.ClientID, cfg.ClientSecret, opts)
if err != nil {
return nil, fmt.Errorf("failed to create service principal token: %v", err)
return nil, fmt.Errorf("failed to create service principal token: %w", err)
}
return token, nil
return cred, nil
}
// Try to retrieve token with MSI.
if cfg.UseManagedIdentityExtension {
log.Info("Using managed identity extension to retrieve access token for Azure API.")
msiOpt := azidentity.ManagedIdentityCredentialOptions{
ClientOptions: azcore.ClientOptions{
Cloud: cloudCfg,
},
}
if cfg.UserAssignedIdentityID != "" {
log.Infof("Resolving to user assigned identity, client id is %s.", cfg.UserAssignedIdentityID)
token, err := adal.NewServicePrincipalTokenFromManagedIdentity(environment.ServiceManagementEndpoint, &adal.ManagedIdentityOptions{
ClientID: cfg.UserAssignedIdentityID,
})
if err != nil {
return nil, fmt.Errorf("failed to create the managed service identity token: %v", err)
}
return token, nil
msiOpt.ID = azidentity.ClientID(cfg.UserAssignedIdentityID)
}
log.Info("Resolving to system assigned identity.")
token, err := adal.NewServicePrincipalTokenFromManagedIdentity(environment.ServiceManagementEndpoint, nil)
cred, err := azidentity.NewManagedIdentityCredential(&msiOpt)
if err != nil {
return nil, fmt.Errorf("failed to create the managed service identity token: %v", err)
return nil, fmt.Errorf("failed to create the managed service identity token: %w", err)
}
return token, nil
return cred, nil
}
return nil, fmt.Errorf("no credentials provided for Azure API")
}
func getCloudConfiguration(name string) (cloud.Configuration, error) {
name = strings.ToUpper(name)
switch name {
case "AZURECLOUD", "AZUREPUBLICCLOUD", "":
return cloud.AzurePublic, nil
case "AZUREUSGOVERNMENT", "AZUREUSGOVERNMENTCLOUD":
return cloud.AzureGovernment, nil
case "AZURECHINACLOUD":
return cloud.AzureChina, nil
}
return cloud.Configuration{}, fmt.Errorf("unknown cloud name: %s", name)
}

View File

@ -17,50 +17,29 @@ limitations under the License.
package azure
import (
"fmt"
"os"
"reflect"
"testing"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
)
func TestGetAzureEnvironmentConfig(t *testing.T) {
tmp, err := os.CreateTemp("", "azureconf")
if err != nil {
t.Errorf("couldn't write temp file %v", err)
}
defer os.Remove(tmp.Name())
func TestGetCloudConfiguration(t *testing.T) {
tests := map[string]struct {
cloud string
err error
cloudName string
expected cloud.Configuration
}{
"AzureChinaCloud": {"AzureChinaCloud", nil},
"AzureGermanCloud": {"AzureGermanCloud", nil},
"AzurePublicCloud": {"", nil},
"AzureUSGovernment": {"AzureUSGovernmentCloud", nil},
"AzureChinaCloud": {"AzureChinaCloud", cloud.AzureChina},
"AzurePublicCloud": {"", cloud.AzurePublic},
"AzureUSGovernment": {"AzureUSGovernmentCloud", cloud.AzureGovernment},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
_, _ = tmp.Seek(0, 0)
_, _ = tmp.Write([]byte(fmt.Sprintf(`{"cloud": "%s"}`, test.cloud)))
got, err := getConfig(tmp.Name(), "", "")
cloudCfg, err := getCloudConfiguration(test.cloudName)
if err != nil {
t.Errorf("got unexpected err %v", err)
}
if test.cloud == "" {
test.cloud = "AzurePublicCloud"
}
want, err := azure.EnvironmentFromName(test.cloud)
if err != nil {
t.Errorf("couldn't get azure environment from provided name %v", err)
}
if !reflect.DeepEqual(want, got.Environment) {
t.Errorf("got %v, want %v", got.Environment, want)
if cloudCfg.ActiveDirectoryAuthorityHost != test.expected.ActiveDirectoryAuthorityHost {
t.Errorf("got %v, want %v", cloudCfg, test.expected)
}
})
}