mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 09:36:58 +02:00
Resolving conflicts
This commit is contained in:
commit
8810311ca8
254
Gopkg.lock
generated
254
Gopkg.lock
generated
@ -2,66 +2,53 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ae9d0182a5cf7dbb025a8fc5821234cc1f26ca342fc41d951a99f71b9adc1b87"
|
||||
name = "cloud.google.com/go"
|
||||
packages = [
|
||||
"compute/metadata",
|
||||
"internal",
|
||||
"internal"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "3b1ae45394a234c385be014e9a488f2bb6eef821"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:fd38e3b8c27cab6561a7d2e8557205c3ca5c57cbb6d3a79e10f22e73e84fd776"
|
||||
name = "github.com/Azure/azure-sdk-for-go"
|
||||
packages = ["arm/dns"]
|
||||
pruneopts = ""
|
||||
revision = "2629e2dfcfeab50896230140542c3b9d89b35ae1"
|
||||
version = "v10.0.4-beta"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f719ef698feb8da2923ebda9a8d553b977320b02182f3797e185202e588a94b1"
|
||||
name = "github.com/Azure/go-autorest"
|
||||
packages = [
|
||||
"autorest",
|
||||
"autorest/adal",
|
||||
"autorest/azure",
|
||||
"autorest/date",
|
||||
"autorest/to",
|
||||
"autorest/to"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "aa2a4534ab680e938d933870f58f23f77e0e208e"
|
||||
version = "v10.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7dc69d1597e4773ec5f64e5c078d55f0f011bb05ec0435346d0649ad978a23fd"
|
||||
name = "github.com/alecthomas/kingpin"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "1087e65c9441605df944fb12c33f0fe7072d18ca"
|
||||
version = "v2.2.5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a74730e052a45a3fab1d310fdef2ec17ae3d6af16228421e238320846f2aaec8"
|
||||
name = "github.com/alecthomas/template"
|
||||
packages = [
|
||||
".",
|
||||
"parse",
|
||||
"parse"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "a0175ee3bccc567396460bf5acd36800cb10c49c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8483994d21404c8a1d489f6be756e25bfccd3b45d65821f25695577791a08e68"
|
||||
name = "github.com/alecthomas/units"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d2dc5d0ccc137594ea6fb3870964967b96b43daac19b8093930c7b02873fd5ca"
|
||||
name = "github.com/aliyun/alibaba-cloud-sdk-go"
|
||||
packages = [
|
||||
"sdk",
|
||||
@ -74,14 +61,12 @@
|
||||
"sdk/responses",
|
||||
"sdk/utils",
|
||||
"services/alidns",
|
||||
"services/pvtz",
|
||||
"services/pvtz"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "cad214d7d71fba7883fcf3b7e550ba782c15b400"
|
||||
version = "1.27.7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1c82dd6a02941a3c4f23a32eca182717ab79691939e97d6b971466b780f06eea"
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
packages = [
|
||||
"aws",
|
||||
@ -113,18 +98,15 @@
|
||||
"private/protocol/xml/xmlutil",
|
||||
"service/route53",
|
||||
"service/servicediscovery",
|
||||
"service/sts",
|
||||
"service/sts"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "9b0098a71f6d4d473a26ec8ad3c2feaac6eb1da6"
|
||||
version = "v1.13.32"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0c5485088ce274fac2e931c1b979f2619345097b39d91af3239977114adf0320"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
pruneopts = ""
|
||||
revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9"
|
||||
|
||||
[[projects]]
|
||||
@ -136,7 +118,6 @@
|
||||
revision = "0c85496d873009e53e64d391ade643e7ac02e0d4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:eaeede87b418b97f9dee473f8940fd9b65ca5cdac0503350c7c8f8965ea3cf4d"
|
||||
name = "github.com/coreos/etcd"
|
||||
packages = [
|
||||
"auth/authpb",
|
||||
@ -144,108 +125,84 @@
|
||||
"etcdserver/api/v3rpc/rpctypes",
|
||||
"etcdserver/etcdserverpb",
|
||||
"mvcc/mvccpb",
|
||||
"pkg/types",
|
||||
"pkg/types"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "1b3ac99e8a431b381e633802cc42fe70e663baf5"
|
||||
version = "v3.2.15"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = ""
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:dc166ce7345c060c2153561130d6d49ac580c804226ac675e368d533b36eb169"
|
||||
name = "github.com/denverdino/aliyungo"
|
||||
packages = [
|
||||
"metadata",
|
||||
"util",
|
||||
"util"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "69560d9530f5265ba00ffad2520d7ef01c2cddd4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6098222470fe0172157ce9bbef5d2200df4edde17ee649c5d6e48330e4afa4c6"
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
|
||||
version = "v3.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:32d1941b093bb945de75b0276348494be318d34f3df39c4413d61e002c800bc6"
|
||||
name = "github.com/digitalocean/godo"
|
||||
packages = [
|
||||
".",
|
||||
"context",
|
||||
"context"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "77ea48de76a7b31b234d854f15d003c68bb2fb90"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5ffd39844bdd1259a6227d544f582c6686ce43c8c44399a46052fe3bd2bed93c"
|
||||
name = "github.com/dnsimple/dnsimple-go"
|
||||
packages = ["dnsimple"]
|
||||
pruneopts = ""
|
||||
revision = "d1105abc03b313d7b8d9b04364f6bd053b346e59"
|
||||
version = "v0.14.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e17d18b233f506404061c27ac4a08624dad38dcd0d49f9cfdae67a7772a4fb8c"
|
||||
name = "github.com/exoscale/egoscale"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "c6d915cb993f1a54f604acefc0fc15cf6578a87a"
|
||||
version = "v0.11.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ae7fb2062735e966ab69d14d2a091f3778b0d676dc8d1f01d092bcb0fb8ed45b"
|
||||
name = "github.com/ffledgling/pdns-go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "524e7daccd99651cdb56426eb15b7d61f9597a5c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b13707423743d41665fd23f0c36b2f37bb49c30e94adb813319c44188a51ba22"
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a00483fe4106b86fb1187a92b5cf6915c85f294ed4c129ccbe7cb1f1a06abd46"
|
||||
name = "github.com/go-ini/ini"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "32e4c1e6bc4e7d0d8451aa6b75200d19e37a536a"
|
||||
version = "v1.32.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8e67153fc0a9fb0d6c9707e36cf80e217a012364307b222eb4ba6828f7e881e6"
|
||||
name = "github.com/go-resty/resty"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "97a15579492cd5f35632499f315d7a8df94160a1"
|
||||
version = "v1.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:54d5c6a784a9de9c836fc070d51d0689c3e99ee6d24dba8a36f0762039dae830"
|
||||
name = "github.com/gogo/googleapis"
|
||||
packages = ["google/rpc"]
|
||||
pruneopts = ""
|
||||
revision = "8558fb44d2f1fc223118afc694129d2c2d2924d1"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6e73003ecd35f4487a5e88270d3ca0a81bc80dc88053ac7e4dcfec5fba30d918"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = [
|
||||
"gogoproto",
|
||||
@ -253,23 +210,19 @@
|
||||
"proto",
|
||||
"protoc-gen-gogo/descriptor",
|
||||
"sortkeys",
|
||||
"types",
|
||||
"types"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "636bf0302bc95575d69441b25a2603156ffdddf1"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b12aff239810a9fa71e901a712a52f9da4c6e536852e943be693dec1d4519dfd"
|
||||
name = "github.com/golang/glog"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "3fa5b9870d1d29f6d7907b29f1ae8c6eeb403829"
|
||||
source = "github.com/kubermatic/glog-logrus"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3dd078fda7500c341bc26cfbc6c6a34614f295a2457149fc1045cab767cbcf18"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"jsonpb",
|
||||
@ -279,50 +232,51 @@
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/struct",
|
||||
"ptypes/timestamp",
|
||||
"ptypes/timestamp"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:be28c0531a755f2178acf1e327e6f5a8a3968feb5f2567cdc968064253141751"
|
||||
name = "github.com/google/btree"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "e89373fe6b4a7413d7acd6da1725b83ef713e6e4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/go-cmp"
|
||||
packages = [
|
||||
"cmp",
|
||||
"cmp/internal/diff",
|
||||
"cmp/internal/function",
|
||||
"cmp/internal/value"
|
||||
]
|
||||
revision = "3af367b6b30c263d47e8895973edcca9a49cf029"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:9abc49f39e3e23e262594bb4fb70abf74c0c99e94f99153f43b143805e850719"
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
pruneopts = ""
|
||||
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2823c34933d4a2b36284f617f483d51fe156a443923284b3660f183dcfa3338"
|
||||
name = "github.com/google/gofuzz"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "44d81051d367757e1c7c6a5a86423ece9afcf63c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:16b2837c8b3cf045fa2cdc82af0cf78b19582701394484ae76b2c3bc3c99ad73"
|
||||
name = "github.com/googleapis/gnostic"
|
||||
packages = [
|
||||
"OpenAPIv2",
|
||||
"compiler",
|
||||
"extensions",
|
||||
"extensions"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "7c663266750e7d82587642f65e60bc4083f1f84e"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:54a44d48a24a104e078ef5f94d82f025a6be757e7c42b4370c621a3928d6ab7c"
|
||||
name = "github.com/gophercloud/gophercloud"
|
||||
packages = [
|
||||
".",
|
||||
@ -333,100 +287,77 @@
|
||||
"openstack/identity/v2/tokens",
|
||||
"openstack/identity/v3/tokens",
|
||||
"openstack/utils",
|
||||
"pagination",
|
||||
"pagination"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "bfc4756e1a693a850d7d459f4b28b21f35a24b5a"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:dbbeb8ddb0be949954c8157ee8439c2adfd8dc1c9510eb44a6e58cb68c3dce28"
|
||||
name = "github.com/gorilla/context"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c2c8666b4836c81a1d247bdf21c6a6fc1ab586538ab56f74437c2e0df5c375e1"
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
|
||||
version = "v1.6.2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:009a1928b8c096338b68b5822d838a72b4d8520715c1463614476359f3282ec8"
|
||||
name = "github.com/gregjones/httpcache"
|
||||
packages = [
|
||||
".",
|
||||
"diskcache",
|
||||
"diskcache"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "9cad4c3443a7200dd6400aef47183728de563a38"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8e3bd93036b4a925fe2250d3e4f38f21cadb8ef623561cd80c3c50c114b13201"
|
||||
name = "github.com/hashicorp/errwrap"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "8a6fb523712970c966eefc6b39ed2c5e74880354"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:72308fdd6d5ef61106a95be7ca72349a5565809042b6426a3cfb61d99483b824"
|
||||
name = "github.com/hashicorp/go-multierror"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "886a7fbe3eb1c874d46f623bfa70af45f425b3d1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3313a63031ae281e5f6fd7b0bbca733dfa04d2429df86519e3b4d4c016ccb836"
|
||||
name = "github.com/hashicorp/golang-lru"
|
||||
packages = [
|
||||
".",
|
||||
"simplelru",
|
||||
"simplelru"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "20f1fb78b0740ba8c3cb143a61e86ba5c8669768"
|
||||
version = "v0.5.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:af7e132906cb360f4d7c34a9e1434825467f21c4ff5c521ad4cc5b55352876a8"
|
||||
name = "github.com/imdario/mergo"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "6633656539c1639d9d78127b7d47c622b5d7b6dc"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be"
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e0a13d0a368c028716e78448db972657b5292c7238d61405e8289f47c05c8706"
|
||||
name = "github.com/infobloxopen/infoblox-go-client"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "61dc5f9b0a655ebf43026f0d8a837ad1e28e4b96"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6f49eae0c1e5dab1dafafee34b207aeb7a42303105960944828c2079b92fc88e"
|
||||
name = "github.com/jmespath/go-jmespath"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "0b12d6b5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:53ac4e911e12dde0ab68655e2006449d207a5a681f084974da2b06e5dbeaca72"
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "ab8a2e0c74be9d3be70b3184d9acc634935ded82"
|
||||
version = "1.1.4"
|
||||
|
||||
@ -439,239 +370,185 @@
|
||||
revision = "1bcb110c8726cee477939f507f4760a95e155347"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7c23a751ce2f84663fa411acb87eae0da2d09c39a8e99b08bd8f65fae75d8928"
|
||||
name = "github.com/linki/instrumented_http"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "508103cfb3b315fa9752b5bcd4fb2d97bbc26d89"
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1c41354ef11c9dbae2fe1ceee8369fcb2634977ba07e701e19ea53e8742c5420"
|
||||
name = "github.com/linode/linodego"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "7edbc87f0140b7561dbc20458877a56bdded5eb8"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:63722a4b1e1717be7b98fc686e0b30d5e7f734b9e93d7dee86293b6deab7ea28"
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
pruneopts = ""
|
||||
revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4c8d8358c45ba11ab7bb15df749d4df8664ff1582daead28bae58cf8cbe49890"
|
||||
name = "github.com/miekg/dns"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "5a2b9fab83ff0f8bfc99684bd5f43a37abe560f1"
|
||||
version = "v1.0.8"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0c0ff2a89c1bb0d01887e1dac043ad7efbf3ec77482ef058ac423d13497e16fd"
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||
version = "1.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e32bdbdb7c377a07a9a46378290059822efdce5c8d96fe71940d87cb4f918855"
|
||||
name = "github.com/modern-go/reflect2"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:11c58e19ff7ce22740423bb933f1ddca3bf575def40d5ac3437ec12871b1648b"
|
||||
name = "github.com/natefinch/lumberjack"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "a96e63847dc3c67d17befa69c303767e2f84e54f"
|
||||
version = "v2.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d8b5d0ecca348c835914a1ed8589f17a6a7f309befab7327b0470324531f7ac4"
|
||||
name = "github.com/nesv/go-dynect"
|
||||
packages = ["dynect"]
|
||||
pruneopts = ""
|
||||
revision = "cdd946344b54bdf7dbeac406c2f1fe93150f08ea"
|
||||
version = "v0.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:70df8e71a953626770223d4982801fa73e7e99cbfcca068b95127f72af9b9edd"
|
||||
name = "github.com/oracle/oci-go-sdk"
|
||||
packages = [
|
||||
"common",
|
||||
"dns",
|
||||
"dns"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "a2ded717dc4bb4916c0416ec79f81718b576dbc4"
|
||||
version = "v1.8.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:c24598ffeadd2762552269271b3b1510df2d83ee6696c1e543a0ff653af494bc"
|
||||
name = "github.com/petar/GoLLRB"
|
||||
packages = ["llrb"]
|
||||
pruneopts = ""
|
||||
revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b46305723171710475f2dd37547edd57b67b9de9f2a6267cafdd98331fd6897f"
|
||||
name = "github.com/peterbourgon/diskv"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "5f041e8faa004a95c88a202771f4cc3e991971e6"
|
||||
version = "v2.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:cf172c58bb2a13ed39ea1c9e79525567c63bcc2c4afbb6cf023e87b31780f249"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "f15c970de5b76fac0b59abb32d62c17cc7bed265"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411"
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
pruneopts = ""
|
||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2f69dc6b2685b31a1a410ef697410aa8a669704fb201d45dbd8c1911728afa75"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
"prometheus/promhttp",
|
||||
"prometheus/promhttp"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "967789050ba94deca04a5e84cce8ad472ce313c1"
|
||||
version = "v0.9.0-pre1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:60aca47f4eeeb972f1b9da7e7db51dee15ff6c59f7b401c1588b8e6771ba15ef"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = ""
|
||||
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e3aa5178be4fc4ae8cdb37d11c02f7490c00450a9f419e6aa84d02d3b47e90d2"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
"internal/bitbucket.org/ww/goautoneg",
|
||||
"model",
|
||||
"model"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "2e54d0b93cba2fd133edc32211dcc32c06ef72ca"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a6a85fc81f2a06ccac3d45005523afbeee45138d781d4f3cb7ad9889d5c65aab"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
"xfs",
|
||||
"xfs"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "a6e9df898b1336106c743392c48ee0b71f5c4efa"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:bb2ccb2d56cbafdec58af0f473f45304e19876f09fa671960ca87802b656a9c0"
|
||||
name = "github.com/sanyu/dynectsoap"
|
||||
packages = ["dynectsoap"]
|
||||
pruneopts = ""
|
||||
revision = "b83de5edc4e022f22903eeb3b428d2f39fb740e5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7f569d906bdd20d906b606415b7d794f798f91a62fcfb6a4daa6d50690fb7a3f"
|
||||
name = "github.com/satori/go.uuid"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3ac248add5bb40a3c631c5334adcd09aa72d15af2768a5bc0274084ea7b2e5ba"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "f006c2ac4710855cf0f916dd6b77acf6b048dc6e"
|
||||
version = "v1.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a1403cc8a94b8d7956ee5e9694badef0e7b051af289caad1cf668331e3ffa4f6"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385"
|
||||
version = "v0.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0a52bcb568386d98f4894575d53ce3e456f56471de6897bb8b9de13c33d9340e"
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "9a97c102cda95a86cec2345a6f09f55a939babf5"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:306417ea2f31ea733df356a2b895de63776b6a5107085b33458e5cd6eb1d584d"
|
||||
name = "github.com/stretchr/objx"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "facf9a85c22f48d2f52f2380e4efce1768749a89"
|
||||
version = "v0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a30066593578732a356dc7e5d7f78d69184ca65aeeff5939241a3ab10559bb06"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
"mock",
|
||||
"require",
|
||||
"suite",
|
||||
"suite"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:81f435c83e3523a7ee3f277769727f73ca66218ca8188d96a0935a4841b47a76"
|
||||
name = "github.com/tent/http-link-go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "ac974c61c2f990f4115b119354b5e0b47550e888"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:74f86c458e82e1c4efbab95233e0cf51b7cc02dc03193be9f62cd81224e10401"
|
||||
name = "go.uber.org/atomic"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289"
|
||||
version = "v1.3.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:22c7effcb4da0eacb2bb1940ee173fac010e9ef3c691f5de4b524d538bd980f5"
|
||||
name = "go.uber.org/multierr"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:246f378f80fba6fcf0f191c486b6613265abd2bc0f2fa55a36b928c67352021e"
|
||||
name = "go.uber.org/zap"
|
||||
packages = [
|
||||
".",
|
||||
@ -680,26 +557,22 @@
|
||||
"internal/color",
|
||||
"internal/exit",
|
||||
"zapcore",
|
||||
"zapgrpc",
|
||||
"zapgrpc"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "ff33455a0e382e8a81d14dd7c922020b6b5e7982"
|
||||
version = "v1.9.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b2d8b39397ca07929a3de3a3fd2b6ca4c8d48e9cadaa7cf2b083e27fd9e78107"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"ed25519",
|
||||
"ed25519/internal/edwards25519",
|
||||
"ssh/terminal",
|
||||
"ssh/terminal"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "0709b304e793a5edb4a2c0145f281ecdc20838a4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:782723d6fc27d202f1943219d68d58b3f6bcab6212c85294b1ddd8b586b1d356"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"bpf",
|
||||
@ -715,36 +588,30 @@
|
||||
"ipv4",
|
||||
"ipv6",
|
||||
"publicsuffix",
|
||||
"trace",
|
||||
"trace"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "161cd47e91fd58ac17490ef4d742dc98bb4cf60e"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:dad5a319c4710358be1f2bf68f9fb7f90a71d7c641221b79801d5667b28f19e3"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"google",
|
||||
"internal",
|
||||
"jws",
|
||||
"jwt",
|
||||
"jwt"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:39d88a855976e160babdd254802e1c2ae75ed380328c39742b57928852da6207"
|
||||
name = "golang.org/x/sys"
|
||||
packages = [
|
||||
"unix",
|
||||
"windows",
|
||||
"windows"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "13d03a9a82fba647c21a0ef8fba44a795d0f0835"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5acd3512b047305d49e8763eef7ba423901e85d5dd2fd1e71778a0ea8de10bd4"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
@ -760,34 +627,28 @@
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable",
|
||||
"unicode/rangetable"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:55a681cb66f28755765fa5fa5104cbd8dc85c55c02d206f9f89566451e3fe1aa"
|
||||
name = "golang.org/x/time"
|
||||
packages = ["rate"]
|
||||
pruneopts = ""
|
||||
revision = "fbb02b2291d28baffd63558aa44b4b56f178d650"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2ad38d79865e33dde6157b7048debd6e7d47e0709df7b5e11bb888168e316908"
|
||||
name = "google.golang.org/api"
|
||||
packages = [
|
||||
"dns/v1",
|
||||
"gensupport",
|
||||
"googleapi",
|
||||
"googleapi/internal/uritemplates",
|
||||
"googleapi/internal/uritemplates"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "a0ff90edab763c86aa88f2b1eb4f3301b82f6336"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:41e2b7e287117f6136f75286d48072ecf781ba54823ffeb2098e152e7dc45ef6"
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
".",
|
||||
@ -799,24 +660,20 @@
|
||||
"internal/modules",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch",
|
||||
"urlfetch"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e43f1cb3f488a0c2be85939c2a594636f60b442a12a196c778bd2d6c9aca3df7"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = [
|
||||
"googleapis/api/annotations",
|
||||
"googleapis/rpc/status",
|
||||
"googleapis/rpc/status"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "11092d34479b07829b72e10713b159248caf5dad"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ca75b3775a5d4e5d1fb48f57ef0865b4aaa8b3f00e6b52be68db991c4594e0a7"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
@ -845,31 +702,25 @@
|
||||
"resolver/passthrough",
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
"tap"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "32fb0ac620c32ba40a4626ddf94d90d12cce3455"
|
||||
version = "v1.14.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e5d1fb981765b6f7513f793a3fcaac7158408cca77f75f7311ac82cc88e9c445"
|
||||
name = "gopkg.in/inf.v0"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4"
|
||||
version = "v0.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f0620375dd1f6251d9973b5f2596228cc8042e887cd7f827e4220bc1ce8c30e2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "release-1.0"
|
||||
digest = "1:bc43af6616d8ca12a7b8e806874387f0f1e181c08f547e9cd77f6cbac8cefd86"
|
||||
name = "istio.io/api"
|
||||
packages = [
|
||||
"authentication/v1alpha1",
|
||||
@ -877,13 +728,11 @@
|
||||
"mixer/v1",
|
||||
"mixer/v1/config/client",
|
||||
"networking/v1alpha3",
|
||||
"rbac/v1alpha1",
|
||||
"rbac/v1alpha1"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "76349c53b87f03f1e610b3aa3843dba3c38138d7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7eb25280e1f610470bb0c43ab6c91573cfc78672a58542106b9b71705581429a"
|
||||
name = "istio.io/istio"
|
||||
packages = [
|
||||
"pilot/pkg/config/kube/crd",
|
||||
@ -892,14 +741,12 @@
|
||||
"pilot/pkg/serviceregistry/kube",
|
||||
"pkg/cache",
|
||||
"pkg/kube",
|
||||
"pkg/log",
|
||||
"pkg/log"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "42773aacced474d97159902d20579a25b1f98106"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f420c8548c93242d8e5dcfa5b34e0243883b4e660f65076e869daafac877144d"
|
||||
name = "k8s.io/api"
|
||||
packages = [
|
||||
"admissionregistration/v1alpha1",
|
||||
@ -930,28 +777,24 @@
|
||||
"settings/v1alpha1",
|
||||
"storage/v1",
|
||||
"storage/v1alpha1",
|
||||
"storage/v1beta1",
|
||||
"storage/v1beta1"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "072894a440bdee3a891dea811fe42902311cd2a3"
|
||||
version = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:66d1421ecff35bc48ee0b11a3f891f3af6f775ed6bb1d3e0deeaba221bf42490"
|
||||
name = "k8s.io/apiextensions-apiserver"
|
||||
packages = [
|
||||
"pkg/apis/apiextensions",
|
||||
"pkg/apis/apiextensions/v1beta1",
|
||||
"pkg/client/clientset/clientset",
|
||||
"pkg/client/clientset/clientset/scheme",
|
||||
"pkg/client/clientset/clientset/typed/apiextensions/v1beta1",
|
||||
"pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "8e7f43002fec5394a8d96ebca781aa9d4b37aaef"
|
||||
version = "kubernetes-1.10.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b6b2fb7b4da1ac973b64534ace2299a02504f16bc7820cb48edb8ca4077183e1"
|
||||
name = "k8s.io/apimachinery"
|
||||
packages = [
|
||||
"pkg/api/errors",
|
||||
@ -994,14 +837,12 @@
|
||||
"pkg/version",
|
||||
"pkg/watch",
|
||||
"third_party/forked/golang/json",
|
||||
"third_party/forked/golang/reflect",
|
||||
"third_party/forked/golang/reflect"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "103fd098999dc9c0c88536f5c9ad2e5da39373ae"
|
||||
version = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d04779a8de7d5465e0463bd986506348de5e89677c74777f695d3145a7a8d15e"
|
||||
name = "k8s.io/client-go"
|
||||
packages = [
|
||||
"discovery",
|
||||
@ -1099,18 +940,15 @@
|
||||
"util/homedir",
|
||||
"util/integer",
|
||||
"util/jsonpath",
|
||||
"util/retry",
|
||||
"util/retry"
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "7d04d0e2a0a1a4d4a1cd6baa432a2301492e4e65"
|
||||
version = "v8.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:526095379da1098c3f191a0008cc59c9bf9927492e63da7689e5de424219c162"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = ["pkg/util/proto"]
|
||||
pruneopts = ""
|
||||
revision = "d8ea2fe547a448256204cfc68dfee7b26c720acb"
|
||||
|
||||
[solve-meta]
|
||||
|
@ -116,6 +116,10 @@ ignored = ["github.com/kubernetes/repo-infra/kazel"]
|
||||
name = "github.com/miekg/dns"
|
||||
version = "1.0.8"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/google/go-cmp"
|
||||
version = "0.2.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/sanyu/dynectsoap"
|
||||
branch = "master"
|
||||
|
@ -10,7 +10,6 @@
|
||||
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
||||
# INSTRUCTIONS AT https://kubernetes.io/security/
|
||||
|
||||
linki
|
||||
njuettner
|
||||
hjacobs
|
||||
raffo
|
||||
|
@ -14,7 +14,11 @@ Here is typical example of [CRD API type](https://github.com/kubernetes-incubato
|
||||
```go
|
||||
type TTL int64
|
||||
type Targets []string
|
||||
type ProviderSpecific map[string]string
|
||||
type ProviderSpecificProperty struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
type ProviderSpecific []ProviderSpecificProperty
|
||||
|
||||
type Endpoint struct {
|
||||
// The hostname of the DNS record
|
||||
|
@ -33,7 +33,14 @@ spec:
|
||||
labels:
|
||||
type: object
|
||||
providerSpecific:
|
||||
type: object
|
||||
items:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
recordTTL:
|
||||
format: int64
|
||||
type: integer
|
||||
|
@ -243,3 +243,11 @@ To do this with ExternalDNS you can use the `--annotation-filter` to specificall
|
||||
an instance of a ingress controller. Let's assume you have two ingress controllers `nginx-internal` and `nginx-external`
|
||||
then you can start two ExternalDNS providers one with `--annotation-filter=kubernetes.io/ingress.class=nginx-internal`
|
||||
and one with `--annotation-filter=kubernetes.io/ingress.class=nginx-external`.
|
||||
|
||||
### Can external-dns manage(add/remove) records in a hosted zone which is setup in different aws account.
|
||||
|
||||
yes, give it the correct cross-account/assume-role permissions and use the `--aws-assume-role` flag https://github.com/kubernetes-incubator/external-dns/pull/524#issue-181256561
|
||||
|
||||
### how do I provide multiple values to the annotation `external-dns.alpha.kubernetes.io/hostname`
|
||||
|
||||
separate them by `,`
|
||||
|
@ -47,14 +47,14 @@ $ aws route53 create-hosted-zone --name "external-dns-test.my-org.com." --caller
|
||||
Make a note of the ID of the hosted zone you just created.
|
||||
|
||||
```console
|
||||
$ aws route53 list-hosted-zones-by-name --dns-name "external-dns-test.my-org.com." | jq -r '.HostedZones[0].Id'
|
||||
$ aws route53 list-hosted-zones-by-name --output json --dns-name "external-dns-test.my-org.com." | jq -r '.HostedZones[0].Id'
|
||||
/hostedzone/ZEWFWZ4R16P7IB
|
||||
```
|
||||
|
||||
Make a note of the nameservers that were assigned to your new zone.
|
||||
|
||||
```console
|
||||
$ aws route53 list-resource-record-sets --hosted-zone-id "/hostedzone/ZEWFWZ4R16P7IB" \
|
||||
$ aws route53 list-resource-record-sets --output json --hosted-zone-id "/hostedzone/ZEWFWZ4R16P7IB" \
|
||||
--query "ResourceRecordSets[?Type == 'NS']" | jq -r '.[0].ResourceRecords[].Value'
|
||||
ns-5514.awsdns-53.org.
|
||||
...
|
||||
@ -177,7 +177,7 @@ Annotations which are specific to AWS.
|
||||
|
||||
### alias
|
||||
|
||||
`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well.
|
||||
`external-dns.alpha.kubernetes.io/alias` if set to `true` on an ingress, it will create an ALIAS record when the target is an ALIAS as well. To make the target an alias, the ingress needs to be configured correctly as described in [the docs](./nginx-ingress.md#with-a-separate-tcp-load-balancer).
|
||||
|
||||
## Verify ExternalDNS works (Ingress example)
|
||||
|
||||
@ -247,7 +247,7 @@ spec:
|
||||
After roughly two minutes check that a corresponding DNS record for your service was created.
|
||||
|
||||
```console
|
||||
$ aws route53 list-resource-record-sets --hosted-zone-id "/hostedzone/ZEWFWZ4R16P7IB" \
|
||||
$ aws route53 list-resource-record-sets --output json --hosted-zone-id "/hostedzone/ZEWFWZ4R16P7IB" \
|
||||
--query "ResourceRecordSets[?Name == 'nginx.external-dns-test.my-org.com.']|[?Type == 'A']"
|
||||
[
|
||||
{
|
||||
|
@ -61,13 +61,18 @@ The `resourceGroup` is the Resource Group created in a previous step.
|
||||
The `aadClientID` and `aaClientSecret` are assoiated with the Service Principal, that you need to create next.
|
||||
|
||||
### Creating service principal
|
||||
A Service Principal with a minimum access level of contribute to the resource group containing the Azure DNS zone(s) is necessary for ExternalDNS to be able to edit DNS records. This is an Azure CLI example on how to query the Azure API for the information required for the Resource Group and DNS zone you would have already created in previous steps.
|
||||
A Service Principal with a minimum access level of `contributor` to the DNS zone(s) and `reader` to the resource group containing the Azure DNS zone(s) is necessary for ExternalDNS to be able to edit DNS records. However, other more permissive access levels will work too (e.g. `contributor` to the resource group or the whole subscription).
|
||||
|
||||
This is an Azure CLI example on how to query the Azure API for the information required for the Resource Group and DNS zone you would have already created in previous steps.
|
||||
|
||||
``` bash
|
||||
> az login
|
||||
```
|
||||
>az login
|
||||
...
|
||||
# find the relevant subscription and set the az context. id = subscriptionId value in the azure.json.
|
||||
>az account list
|
||||
|
||||
Find the relevant subscription and make sure it is selected (the same subscriptionId should be set into azure.json)
|
||||
|
||||
``` bash
|
||||
> az account list
|
||||
{
|
||||
"cloudName": "AzureCloud",
|
||||
"id": "<subscriptionId GUID>",
|
||||
@ -79,16 +84,15 @@ A Service Principal with a minimum access level of contribute to the resource gr
|
||||
"name": "name",
|
||||
"type": "user"
|
||||
}
|
||||
>az account set -s id
|
||||
...
|
||||
>az group show --name externaldns
|
||||
{
|
||||
"id": "/subscriptions/id/resourceGroups/externaldns",
|
||||
...
|
||||
}
|
||||
|
||||
# use the id from the previous step in the scopes argument
|
||||
>az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/id/resourceGroups/externaldns" -n ExternalDnsServicePrincipal
|
||||
# select the subscription
|
||||
> az account set -s <subscriptionId GUID>
|
||||
...
|
||||
```
|
||||
Create the service principal
|
||||
|
||||
``` bash
|
||||
> az ad sp create-for-rbac -n ExternalDnsServicePrincipal
|
||||
{
|
||||
"appId": "appId GUID", <-- aadClientId value
|
||||
...
|
||||
@ -97,6 +101,33 @@ A Service Principal with a minimum access level of contribute to the resource gr
|
||||
}
|
||||
```
|
||||
|
||||
Assign the rights for the service principal
|
||||
|
||||
```
|
||||
# find out the resource ids of the resource group where the dns zone is deployed, and the dns zone itself
|
||||
> az group show --name externaldns
|
||||
{
|
||||
"id": "/subscriptions/id/resourceGroups/externaldns",
|
||||
...
|
||||
}
|
||||
|
||||
> az network dns zone show --name example.com -g externaldns
|
||||
{
|
||||
"id": "/subscriptions/.../resourceGroups/externaldns/providers/Microsoft.Network/dnszones/example.com",
|
||||
...
|
||||
}
|
||||
```
|
||||
```
|
||||
# assign the rights to the created service principal, using the resource ids from previous step
|
||||
|
||||
# 1. as a reader to the resource group
|
||||
> az role assignment create --role "Reader" --assignee <appId GUID> --scope <resource group resource id>
|
||||
|
||||
# 2. as a contributor to DNS Zone itself
|
||||
> az role assignment create --role "Contributor" --assignee <appId GUID> --scope <dns zone resource id>
|
||||
|
||||
```
|
||||
|
||||
Now you can create a file named 'azure.json' with values gathered above and with the structure of the example above. Use this file to create a Kubernetes secret:
|
||||
|
||||
```
|
||||
|
@ -196,3 +196,7 @@ Now that we have verified that ExternalDNS will automatically manage Cloudflare
|
||||
$ kubectl delete -f nginx.yaml
|
||||
$ kubectl delete -f externaldns.yaml
|
||||
```
|
||||
|
||||
## Setting cloudflare-proxied on a per-ingress basis
|
||||
|
||||
Using the `external-dns.alpha.kubernetes.io/cloudflare-proxied: "true"` annotation on your ingress, you can specify if the proxy feature of Cloudflare should be enabled for that record. This setting will override the global `--cloudflare-proxied` setting.
|
||||
|
@ -109,8 +109,14 @@ func (t Targets) IsLess(o Targets) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ProviderSpecificProperty holds the name and value of a configuration which is specific to individual DNS providers
|
||||
type ProviderSpecificProperty struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// ProviderSpecific holds configuration which is specific to individual DNS providers
|
||||
type ProviderSpecific map[string]string
|
||||
type ProviderSpecific []ProviderSpecificProperty
|
||||
|
||||
// Endpoint is a high-level way of a connection between a service and an IP
|
||||
type Endpoint struct {
|
||||
@ -160,10 +166,21 @@ func (e *Endpoint) WithProviderSpecific(key, value string) *Endpoint {
|
||||
if e.ProviderSpecific == nil {
|
||||
e.ProviderSpecific = ProviderSpecific{}
|
||||
}
|
||||
e.ProviderSpecific[key] = value
|
||||
|
||||
e.ProviderSpecific = append(e.ProviderSpecific, ProviderSpecificProperty{Name: key, Value: value})
|
||||
return e
|
||||
}
|
||||
|
||||
// GetProviderSpecificProperty returns a ProviderSpecificProperty if the property exists.
|
||||
func (e *Endpoint) GetProviderSpecificProperty(key string) (ProviderSpecificProperty, bool) {
|
||||
for _, providerSpecific := range e.ProviderSpecific {
|
||||
if providerSpecific.Name == key {
|
||||
return providerSpecific, true
|
||||
}
|
||||
}
|
||||
return ProviderSpecificProperty{}, false
|
||||
}
|
||||
|
||||
func (e *Endpoint) String() string {
|
||||
return fmt.Sprintf("%s %d IN %s %s %s", e.DNSName, e.RecordTTL, e.RecordType, e.Targets, e.ProviderSpecific)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/kubernetes-incubator/external-dns/endpoint"
|
||||
@ -49,7 +50,7 @@ func SameEndpoint(a, b *endpoint.Endpoint) bool {
|
||||
return a.DNSName == b.DNSName && a.Targets.Same(b.Targets) && a.RecordType == b.RecordType &&
|
||||
a.Labels[endpoint.OwnerLabelKey] == b.Labels[endpoint.OwnerLabelKey] && a.RecordTTL == b.RecordTTL &&
|
||||
a.Labels[endpoint.ResourceLabelKey] == b.Labels[endpoint.ResourceLabelKey] &&
|
||||
SameMap(a.ProviderSpecific, b.ProviderSpecific)
|
||||
SameProverSpecific(a.ProviderSpecific, b.ProviderSpecific)
|
||||
}
|
||||
|
||||
// SameEndpoints compares two slices of endpoints regardless of order
|
||||
@ -81,17 +82,7 @@ func SamePlanChanges(a, b map[string][]*endpoint.Endpoint) bool {
|
||||
SameEndpoints(a["UpdateOld"], b["UpdateOld"]) && SameEndpoints(a["UpdateNew"], b["UpdateNew"])
|
||||
}
|
||||
|
||||
// SameMap verifies that two maps contain the same string/string key/value pairs
|
||||
func SameMap(a, b map[string]string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for k, v := range a {
|
||||
if v != b[k] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
// SameProverSpecific verifies that two maps contain the same string/string key/value pairs
|
||||
func SameProverSpecific(a, b endpoint.ProviderSpecific) bool {
|
||||
return reflect.DeepEqual(a, b)
|
||||
}
|
||||
|
@ -56,9 +56,11 @@ func ExampleSameEndpoints() {
|
||||
RecordTTL: endpoint.TTL(60),
|
||||
},
|
||||
{
|
||||
DNSName: "example.org",
|
||||
Targets: endpoint.Targets{"load-balancer.org"},
|
||||
ProviderSpecific: endpoint.ProviderSpecific{"foo": "bar"},
|
||||
DNSName: "example.org",
|
||||
Targets: endpoint.Targets{"load-balancer.org"},
|
||||
ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{Name: "foo", Value: "bar"},
|
||||
},
|
||||
},
|
||||
}
|
||||
sort.Sort(byAllFields(eps))
|
||||
@ -66,11 +68,11 @@ func ExampleSameEndpoints() {
|
||||
fmt.Println(ep)
|
||||
}
|
||||
// Output:
|
||||
// abc.com 0 IN A 1.2.3.4 map[]
|
||||
// abc.com 0 IN TXT something map[]
|
||||
// bbc.com 0 IN CNAME foo.com map[]
|
||||
// cbc.com 60 IN CNAME foo.com map[]
|
||||
// example.org 0 IN load-balancer.org map[]
|
||||
// example.org 0 IN load-balancer.org map[foo:bar]
|
||||
// example.org 0 IN TXT load-balancer.org map[]
|
||||
// abc.com 0 IN A 1.2.3.4 []
|
||||
// abc.com 0 IN TXT something []
|
||||
// bbc.com 0 IN CNAME foo.com []
|
||||
// cbc.com 60 IN CNAME foo.com []
|
||||
// example.org 0 IN load-balancer.org []
|
||||
// example.org 0 IN load-balancer.org [{foo bar}]
|
||||
// example.org 0 IN TXT load-balancer.org []
|
||||
}
|
||||
|
1
main.go
1
main.go
@ -116,6 +116,7 @@ func main() {
|
||||
BatchChangeInterval: cfg.AWSBatchChangeInterval,
|
||||
EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth,
|
||||
AssumeRole: cfg.AWSAssumeRole,
|
||||
APIRetries: cfg.AWSAPIRetries,
|
||||
DryRun: cfg.DryRun,
|
||||
},
|
||||
)
|
||||
|
@ -61,6 +61,7 @@ type Config struct {
|
||||
AWSBatchChangeSize int
|
||||
AWSBatchChangeInterval time.Duration
|
||||
AWSEvaluateTargetHealth bool
|
||||
AWSAPIRetries int
|
||||
AzureConfigFile string
|
||||
AzureResourceGroup string
|
||||
CloudflareProxied bool
|
||||
@ -134,6 +135,7 @@ var defaultConfig = &Config{
|
||||
AWSBatchChangeSize: 1000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
AWSEvaluateTargetHealth: true,
|
||||
AWSAPIRetries: 3,
|
||||
AzureConfigFile: "/etc/kubernetes/azure.json",
|
||||
AzureResourceGroup: "",
|
||||
CloudflareProxied: false,
|
||||
@ -250,6 +252,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
app.Flag("aws-batch-change-size", "When using the AWS provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSize)).IntVar(&cfg.AWSBatchChangeSize)
|
||||
app.Flag("aws-batch-change-interval", "When using the AWS provider, set the interval between batch changes.").Default(defaultConfig.AWSBatchChangeInterval.String()).DurationVar(&cfg.AWSBatchChangeInterval)
|
||||
app.Flag("aws-evaluate-target-health", "When using the AWS provider, set whether to evaluate the health of a DNS target (default: enabled, disable with --no-aws-evaluate-target-health)").Default(strconv.FormatBool(defaultConfig.AWSEvaluateTargetHealth)).BoolVar(&cfg.AWSEvaluateTargetHealth)
|
||||
app.Flag("aws-api-retries", "When using the AWS provider, set the maximum number of retries for API calls before giving up.").Default(strconv.Itoa(defaultConfig.AWSAPIRetries)).IntVar(&cfg.AWSAPIRetries)
|
||||
app.Flag("azure-config-file", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure").Default(defaultConfig.AzureConfigFile).StringVar(&cfg.AzureConfigFile)
|
||||
app.Flag("azure-resource-group", "When using the Azure provider, override the Azure resource group to use (optional)").Default(defaultConfig.AzureResourceGroup).StringVar(&cfg.AzureResourceGroup)
|
||||
app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied)
|
||||
|
@ -48,6 +48,7 @@ var (
|
||||
AWSBatchChangeSize: 1000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
AWSEvaluateTargetHealth: true,
|
||||
AWSAPIRetries: 3,
|
||||
AzureConfigFile: "/etc/kubernetes/azure.json",
|
||||
AzureResourceGroup: "",
|
||||
CloudflareProxied: false,
|
||||
@ -101,6 +102,7 @@ var (
|
||||
AWSBatchChangeSize: 100,
|
||||
AWSBatchChangeInterval: time.Second * 2,
|
||||
AWSEvaluateTargetHealth: false,
|
||||
AWSAPIRetries: 13,
|
||||
AzureConfigFile: "azure.json",
|
||||
AzureResourceGroup: "arg",
|
||||
CloudflareProxied: true,
|
||||
@ -198,6 +200,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"--aws-assume-role=some-other-role",
|
||||
"--aws-batch-change-size=100",
|
||||
"--aws-batch-change-interval=2s",
|
||||
"--aws-api-retries=13",
|
||||
"--no-aws-evaluate-target-health",
|
||||
"--policy=upsert-only",
|
||||
"--registry=noop",
|
||||
@ -260,6 +263,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE": "100",
|
||||
"EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s",
|
||||
"EXTERNAL_DNS_AWS_EVALUATE_TARGET_HEALTH": "0",
|
||||
"EXTERNAL_DNS_AWS_API_RETRIES": "13",
|
||||
"EXTERNAL_DNS_POLICY": "upsert-only",
|
||||
"EXTERNAL_DNS_REGISTRY": "noop",
|
||||
"EXTERNAL_DNS_TXT_OWNER_ID": "owner-1",
|
||||
|
23
plan/plan.go
23
plan/plan.go
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/kubernetes-incubator/external-dns/endpoint"
|
||||
)
|
||||
|
||||
@ -84,7 +85,7 @@ func (t planTableRow) String() string {
|
||||
}
|
||||
|
||||
func (t planTable) addCurrent(e *endpoint.Endpoint) {
|
||||
dnsName := sanitizeDNSName(e.DNSName)
|
||||
dnsName := normalizeDNSName(e.DNSName)
|
||||
if _, ok := t.rows[dnsName]; !ok {
|
||||
t.rows[dnsName] = &planTableRow{}
|
||||
}
|
||||
@ -92,7 +93,7 @@ func (t planTable) addCurrent(e *endpoint.Endpoint) {
|
||||
}
|
||||
|
||||
func (t planTable) addCandidate(e *endpoint.Endpoint) {
|
||||
dnsName := sanitizeDNSName(e.DNSName)
|
||||
dnsName := normalizeDNSName(e.DNSName)
|
||||
if _, ok := t.rows[dnsName]; !ok {
|
||||
t.rows[dnsName] = &planTableRow{}
|
||||
}
|
||||
@ -105,7 +106,7 @@ func (t planTable) getUpdates() (updateNew []*endpoint.Endpoint, updateOld []*en
|
||||
if row.current != nil && len(row.candidates) > 0 { //dns name is taken
|
||||
update := t.resolver.ResolveUpdate(row.current, row.candidates)
|
||||
// compare "update" to "current" to figure out if actual update is required
|
||||
if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) {
|
||||
if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || shouldUpdateProviderSpecific(update, row.current) {
|
||||
inheritOwner(row.current, update)
|
||||
updateNew = append(updateNew, update)
|
||||
updateOld = append(updateOld, row.current)
|
||||
@ -185,6 +186,10 @@ func shouldUpdateTTL(desired, current *endpoint.Endpoint) bool {
|
||||
return desired.RecordTTL != current.RecordTTL
|
||||
}
|
||||
|
||||
func shouldUpdateProviderSpecific(desired, current *endpoint.Endpoint) bool {
|
||||
return !cmp.Equal(desired.ProviderSpecific, current.ProviderSpecific)
|
||||
}
|
||||
|
||||
// filterRecordsForPlan removes records that are not relevant to the planner.
|
||||
// Currently this just removes TXT records to prevent them from being
|
||||
// deleted erroneously by the planner (only the TXT registry should do this.)
|
||||
@ -209,8 +214,12 @@ func filterRecordsForPlan(records []*endpoint.Endpoint) []*endpoint.Endpoint {
|
||||
return filtered
|
||||
}
|
||||
|
||||
// sanitizeDNSName checks if the DNS name is correct
|
||||
// for now it only removes space and lower case
|
||||
func sanitizeDNSName(dnsName string) string {
|
||||
return strings.TrimSpace(strings.ToLower(dnsName))
|
||||
// normalizeDNSName converts a DNS name to a canonical form, so that we can use string equality
|
||||
// it: removes space, converts to lower case, ensures there is a trailing dot
|
||||
func normalizeDNSName(dnsName string) string {
|
||||
s := strings.TrimSpace(strings.ToLower(dnsName))
|
||||
if !strings.HasSuffix(s, ".") {
|
||||
s += "."
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@ -27,15 +27,17 @@ import (
|
||||
|
||||
type PlanTestSuite struct {
|
||||
suite.Suite
|
||||
fooV1Cname *endpoint.Endpoint
|
||||
fooV2Cname *endpoint.Endpoint
|
||||
fooV2TXT *endpoint.Endpoint
|
||||
fooV2CnameNoLabel *endpoint.Endpoint
|
||||
fooV3CnameSameResource *endpoint.Endpoint
|
||||
fooA5 *endpoint.Endpoint
|
||||
bar127A *endpoint.Endpoint
|
||||
bar127AWithTTL *endpoint.Endpoint
|
||||
bar192A *endpoint.Endpoint
|
||||
fooV1Cname *endpoint.Endpoint
|
||||
fooV2Cname *endpoint.Endpoint
|
||||
fooV2TXT *endpoint.Endpoint
|
||||
fooV2CnameNoLabel *endpoint.Endpoint
|
||||
fooV3CnameSameResource *endpoint.Endpoint
|
||||
fooA5 *endpoint.Endpoint
|
||||
bar127A *endpoint.Endpoint
|
||||
bar127AWithTTL *endpoint.Endpoint
|
||||
bar127AWithProviderSpecificTrue *endpoint.Endpoint
|
||||
bar127AWithProviderSpecificFalse *endpoint.Endpoint
|
||||
bar192A *endpoint.Endpoint
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) SetupTest() {
|
||||
@ -100,6 +102,34 @@ func (suite *PlanTestSuite) SetupTest() {
|
||||
endpoint.ResourceLabelKey: "ingress/default/bar-127",
|
||||
},
|
||||
}
|
||||
suite.bar127AWithProviderSpecificTrue = &endpoint.Endpoint{
|
||||
DNSName: "bar",
|
||||
Targets: endpoint.Targets{"127.0.0.1"},
|
||||
RecordType: "A",
|
||||
Labels: map[string]string{
|
||||
endpoint.ResourceLabelKey: "ingress/default/bar-127",
|
||||
},
|
||||
ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
|
||||
Value: "true",
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.bar127AWithProviderSpecificFalse = &endpoint.Endpoint{
|
||||
DNSName: "bar",
|
||||
Targets: endpoint.Targets{"127.0.0.1"},
|
||||
RecordType: "A",
|
||||
Labels: map[string]string{
|
||||
endpoint.ResourceLabelKey: "ingress/default/bar-127",
|
||||
},
|
||||
ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
|
||||
Value: "false",
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.bar192A = &endpoint.Endpoint{
|
||||
DNSName: "bar",
|
||||
Targets: endpoint.Targets{"192.168.0.1"},
|
||||
@ -108,6 +138,7 @@ func (suite *PlanTestSuite) SetupTest() {
|
||||
endpoint.ResourceLabelKey: "ingress/default/bar-192",
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestSyncFirstRound() {
|
||||
@ -194,6 +225,27 @@ func (suite *PlanTestSuite) TestSyncSecondRoundWithTTLChange() {
|
||||
validateEntries(suite.T(), changes.Delete, expectedDelete)
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestSyncSecondRoundWithProviderSpecificChange() {
|
||||
current := []*endpoint.Endpoint{suite.bar127AWithProviderSpecificTrue}
|
||||
desired := []*endpoint.Endpoint{suite.bar127AWithProviderSpecificFalse}
|
||||
expectedCreate := []*endpoint.Endpoint{}
|
||||
expectedUpdateOld := []*endpoint.Endpoint{suite.bar127AWithProviderSpecificTrue}
|
||||
expectedUpdateNew := []*endpoint.Endpoint{suite.bar127AWithProviderSpecificFalse}
|
||||
expectedDelete := []*endpoint.Endpoint{}
|
||||
|
||||
p := &Plan{
|
||||
Policies: []Policy{&SyncPolicy{}},
|
||||
Current: current,
|
||||
Desired: desired,
|
||||
}
|
||||
|
||||
changes := p.Calculate().Changes
|
||||
validateEntries(suite.T(), changes.Create, expectedCreate)
|
||||
validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew)
|
||||
validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld)
|
||||
validateEntries(suite.T(), changes.Delete, expectedDelete)
|
||||
}
|
||||
|
||||
func (suite *PlanTestSuite) TestSyncSecondRoundWithOwnerInherited() {
|
||||
current := []*endpoint.Endpoint{suite.fooV1Cname}
|
||||
desired := []*endpoint.Endpoint{suite.fooV2Cname}
|
||||
@ -354,6 +406,7 @@ func (suite *PlanTestSuite) TestDuplicatedEndpointsForSameResourceReplace() {
|
||||
|
||||
//TODO: remove once multiple-target per endpoint is supported
|
||||
func (suite *PlanTestSuite) TestDuplicatedEndpointsForSameResourceRetain() {
|
||||
|
||||
current := []*endpoint.Endpoint{suite.fooV1Cname, suite.bar192A}
|
||||
desired := []*endpoint.Endpoint{suite.fooV1Cname, suite.fooV3CnameSameResource}
|
||||
expectedCreate := []*endpoint.Endpoint{}
|
||||
@ -385,54 +438,58 @@ func validateEntries(t *testing.T, entries, expected []*endpoint.Endpoint) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeDNSName(t *testing.T) {
|
||||
func TestNormalizeDNSName(t *testing.T) {
|
||||
records := []struct {
|
||||
dnsName string
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
"3AAAA.FOO.BAR.COM ",
|
||||
"3aaaa.foo.bar.com",
|
||||
"3aaaa.foo.bar.com.",
|
||||
},
|
||||
{
|
||||
" example.foo.com",
|
||||
"example.foo.com",
|
||||
" example.foo.com.",
|
||||
"example.foo.com.",
|
||||
},
|
||||
{
|
||||
"example123.foo.com ",
|
||||
"example123.foo.com",
|
||||
"example123.foo.com.",
|
||||
},
|
||||
{
|
||||
"foo",
|
||||
"foo",
|
||||
"foo.",
|
||||
},
|
||||
{
|
||||
"123foo.bar",
|
||||
"123foo.bar",
|
||||
"123foo.bar.",
|
||||
},
|
||||
{
|
||||
"foo.com",
|
||||
"foo.com",
|
||||
"foo.com.",
|
||||
},
|
||||
{
|
||||
"foo.com.",
|
||||
"foo.com.",
|
||||
},
|
||||
{
|
||||
"foo123.COM",
|
||||
"foo123.com",
|
||||
"foo123.com.",
|
||||
},
|
||||
{
|
||||
"my-exaMple3.FOO.BAR.COM",
|
||||
"my-example3.foo.bar.com",
|
||||
"my-example3.foo.bar.com.",
|
||||
},
|
||||
{
|
||||
" my-example1214.FOO-1235.BAR-foo.COM ",
|
||||
"my-example1214.foo-1235.bar-foo.com",
|
||||
"my-example1214.foo-1235.bar-foo.com.",
|
||||
},
|
||||
{
|
||||
"my-example-my-example-1214.FOO-1235.BAR-foo.COM",
|
||||
"my-example-my-example-1214.foo-1235.bar-foo.com",
|
||||
"my-example-my-example-1214.foo-1235.bar-foo.com.",
|
||||
},
|
||||
}
|
||||
for _, r := range records {
|
||||
gotName := sanitizeDNSName(r.dnsName)
|
||||
gotName := normalizeDNSName(r.dnsName)
|
||||
assert.Equal(t, r.expect, gotName)
|
||||
}
|
||||
}
|
||||
|
@ -117,12 +117,13 @@ type AWSConfig struct {
|
||||
BatchChangeInterval time.Duration
|
||||
EvaluateTargetHealth bool
|
||||
AssumeRole string
|
||||
APIRetries int
|
||||
DryRun bool
|
||||
}
|
||||
|
||||
// NewAWSProvider initializes a new AWS Route53 based Provider.
|
||||
func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) {
|
||||
config := aws.NewConfig()
|
||||
config := aws.NewConfig().WithMaxRetries(awsConfig.APIRetries)
|
||||
|
||||
config.WithHTTPClient(
|
||||
instrumented_http.NewClient(config.HTTPClient, &instrumented_http.Callbacks{
|
||||
@ -394,8 +395,8 @@ func (p *AWSProvider) newChange(action string, endpoint *endpoint.Endpoint) *rou
|
||||
|
||||
if isAWSLoadBalancer(endpoint) {
|
||||
evalTargetHealth := p.evaluateTargetHealth
|
||||
if _, ok := endpoint.ProviderSpecific[providerSpecificEvaluateTargetHealth]; ok {
|
||||
evalTargetHealth = endpoint.ProviderSpecific[providerSpecificEvaluateTargetHealth] == "true"
|
||||
if prop, ok := endpoint.GetProviderSpecificProperty(providerSpecificEvaluateTargetHealth); ok {
|
||||
evalTargetHealth = prop.Value == "true"
|
||||
}
|
||||
|
||||
change.ResourceRecordSet.Type = aws.String(route53.RRTypeA)
|
||||
@ -587,7 +588,7 @@ func isAWSLoadBalancer(ep *endpoint.Endpoint) bool {
|
||||
|
||||
// isAWSAlias determines if a given hostname belongs to an AWS Alias record by doing an reverse lookup.
|
||||
func isAWSAlias(ep *endpoint.Endpoint, addrs []*endpoint.Endpoint) string {
|
||||
if val, exists := ep.ProviderSpecific["alias"]; ep.RecordType == endpoint.RecordTypeCNAME && exists && val == "true" {
|
||||
if prop, exists := ep.GetProviderSpecificProperty("alias"); ep.RecordType == endpoint.RecordTypeCNAME && exists && prop.Value == "true" {
|
||||
for _, addr := range addrs {
|
||||
if addr.DNSName == ep.Targets[0] {
|
||||
if hostedZone := canonicalHostedZone(addr.Targets[0]); hostedZone != "" {
|
||||
|
@ -799,7 +799,10 @@ func TestAWSCreateRecordsWithALIAS(t *testing.T) {
|
||||
Targets: endpoint.Targets{"foo.eu-central-1.elb.amazonaws.com"},
|
||||
RecordType: endpoint.RecordTypeCNAME,
|
||||
ProviderSpecific: endpoint.ProviderSpecific{
|
||||
providerSpecificEvaluateTargetHealth: key,
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: providerSpecificEvaluateTargetHealth,
|
||||
Value: key,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -850,9 +853,14 @@ func TestAWSisAWSAlias(t *testing.T) {
|
||||
{"foo.example.org", endpoint.RecordTypeCNAME, "true", ""},
|
||||
} {
|
||||
ep := &endpoint.Endpoint{
|
||||
Targets: endpoint.Targets{tc.target},
|
||||
RecordType: tc.recordType,
|
||||
ProviderSpecific: map[string]string{"alias": tc.alias},
|
||||
Targets: endpoint.Targets{tc.target},
|
||||
RecordType: tc.recordType,
|
||||
ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: "alias",
|
||||
Value: tc.alias,
|
||||
},
|
||||
},
|
||||
}
|
||||
addrs := []*endpoint.Endpoint{
|
||||
{
|
||||
|
@ -410,6 +410,36 @@ func TestNewCloudFlareChangeNoProxied(t *testing.T) {
|
||||
assert.False(t, change.ResourceRecordSet.Proxied)
|
||||
}
|
||||
|
||||
func TestNewCloudFlareProxiedAnnotationTrue(t *testing.T) {
|
||||
change := newCloudFlareChange(cloudFlareCreate, &endpoint.Endpoint{DNSName: "new", RecordType: "A", Targets: endpoint.Targets{"target"}, ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
|
||||
Value: "true",
|
||||
},
|
||||
}}, false)
|
||||
assert.True(t, change.ResourceRecordSet.Proxied)
|
||||
}
|
||||
|
||||
func TestNewCloudFlareProxiedAnnotationFalse(t *testing.T) {
|
||||
change := newCloudFlareChange(cloudFlareCreate, &endpoint.Endpoint{DNSName: "new", RecordType: "A", Targets: endpoint.Targets{"target"}, ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
|
||||
Value: "false",
|
||||
},
|
||||
}}, true)
|
||||
assert.False(t, change.ResourceRecordSet.Proxied)
|
||||
}
|
||||
|
||||
func TestNewCloudFlareProxiedAnnotationIllegalValue(t *testing.T) {
|
||||
change := newCloudFlareChange(cloudFlareCreate, &endpoint.Endpoint{DNSName: "new", RecordType: "A", Targets: endpoint.Targets{"target"}, ProviderSpecific: endpoint.ProviderSpecific{
|
||||
endpoint.ProviderSpecificProperty{
|
||||
Name: "external-dns.alpha.kubernetes.io/cloudflare-proxied",
|
||||
Value: "asdaslkjndaslkdjals",
|
||||
},
|
||||
}}, false)
|
||||
assert.False(t, change.ResourceRecordSet.Proxied)
|
||||
}
|
||||
|
||||
func TestNewCloudFlareChangeProxiable(t *testing.T) {
|
||||
var cloudFlareTypes = []struct {
|
||||
recordType string
|
||||
|
@ -118,6 +118,11 @@ func (cs *crdSource) Endpoints() ([]*endpoint.Endpoint, error) {
|
||||
|
||||
for _, dnsEndpoint := range result.Items {
|
||||
endpoints = append(endpoints, dnsEndpoint.Spec.Endpoints...)
|
||||
|
||||
if dnsEndpoint.Status.ObservedGeneration == dnsEndpoint.Generation {
|
||||
continue
|
||||
}
|
||||
|
||||
dnsEndpoint.Status.ObservedGeneration = dnsEndpoint.Generation
|
||||
// Update the ObservedGeneration
|
||||
_, err = cs.UpdateStatus(&dnsEndpoint)
|
||||
|
@ -18,6 +18,7 @@ package source
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -54,20 +55,21 @@ func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
|
||||
}
|
||||
|
||||
func startCRDServerToServeTargets(endpoints []*endpoint.Endpoint, apiVersion, kind, namespace, name string) rest.Interface {
|
||||
func startCRDServerToServeTargets(endpoints []*endpoint.Endpoint, apiVersion, kind, namespace, name string, t *testing.T) rest.Interface {
|
||||
groupVersion, _ := schema.ParseGroupVersion(apiVersion)
|
||||
scheme := runtime.NewScheme()
|
||||
addKnownTypes(scheme, groupVersion)
|
||||
|
||||
dnsEndpointList := endpoint.DNSEndpointList{}
|
||||
dnsEndpoint := endpoint.DNSEndpoint{
|
||||
dnsEndpoint := &endpoint.DNSEndpoint{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: apiVersion,
|
||||
Kind: kind,
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Generation: 1,
|
||||
},
|
||||
Spec: endpoint.DNSEndpointSpec{
|
||||
Endpoints: endpoints,
|
||||
@ -88,10 +90,18 @@ func startCRDServerToServeTargets(endpoints []*endpoint.Endpoint, apiVersion, ki
|
||||
case p == "/apis/"+apiVersion+"/"+strings.ToLower(kind)+"s" && m == http.MethodGet:
|
||||
fallthrough
|
||||
case p == "/apis/"+apiVersion+"/namespaces/"+namespace+"/"+strings.ToLower(kind)+"s" && m == http.MethodGet:
|
||||
dnsEndpointList.Items = append(dnsEndpointList.Items, dnsEndpoint)
|
||||
dnsEndpointList.Items = dnsEndpointList.Items[:0]
|
||||
dnsEndpointList.Items = append(dnsEndpointList.Items, *dnsEndpoint)
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, &dnsEndpointList)}, nil
|
||||
case strings.HasPrefix(p, "/apis/"+apiVersion+"/namespaces/") && strings.HasSuffix(p, strings.ToLower(kind)+"s") && m == http.MethodGet:
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, &dnsEndpointList)}, nil
|
||||
case p == "/apis/"+apiVersion+"/namespaces/"+namespace+"/"+strings.ToLower(kind)+"s/"+name+"/status" && m == http.MethodPut:
|
||||
decoder := json.NewDecoder(req.Body)
|
||||
|
||||
var body endpoint.DNSEndpoint
|
||||
decoder.Decode(&body)
|
||||
dnsEndpoint.Status.ObservedGeneration = body.Status.ObservedGeneration
|
||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, dnsEndpoint)}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected request: %#v\n%#v", req.URL, req)
|
||||
}
|
||||
@ -200,6 +210,8 @@ func testCRDSourceEndpoints(t *testing.T) {
|
||||
apiVersion: "test.k8s.io/v1alpha1",
|
||||
registeredKind: "DNSEndpoint",
|
||||
kind: "DNSEndpoint",
|
||||
namespace: "foo",
|
||||
registeredNamespace: "foo",
|
||||
endpoints: []*endpoint.Endpoint{
|
||||
{DNSName: "abc.example.org",
|
||||
Targets: endpoint.Targets{"1.2.3.4"},
|
||||
@ -216,6 +228,8 @@ func testCRDSourceEndpoints(t *testing.T) {
|
||||
apiVersion: "test.k8s.io/v1alpha1",
|
||||
registeredKind: "DNSEndpoint",
|
||||
kind: "DNSEndpoint",
|
||||
namespace: "foo",
|
||||
registeredNamespace: "foo",
|
||||
endpoints: []*endpoint.Endpoint{
|
||||
{DNSName: "abc.example.org",
|
||||
Targets: endpoint.Targets{"1.2.3.4"},
|
||||
@ -233,7 +247,7 @@ func testCRDSourceEndpoints(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(ti.title, func(t *testing.T) {
|
||||
restClient := startCRDServerToServeTargets(ti.endpoints, ti.registeredAPIVersion, ti.registeredKind, ti.registeredNamespace, "")
|
||||
restClient := startCRDServerToServeTargets(ti.endpoints, ti.registeredAPIVersion, ti.registeredKind, ti.registeredNamespace, "test", t)
|
||||
groupVersion, err := schema.ParseGroupVersion(ti.apiVersion)
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -253,8 +267,28 @@ func testCRDSourceEndpoints(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
validateCRDResource(t, cs, ti.expectError)
|
||||
}
|
||||
|
||||
// Validate received endpoints against expected endpoints.
|
||||
validateEndpoints(t, receivedEndpoints, ti.endpoints)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func validateCRDResource(t *testing.T, src Source, expectError bool) {
|
||||
cs := src.(*crdSource)
|
||||
result, err := cs.List(&metav1.ListOptions{})
|
||||
if expectError {
|
||||
require.Errorf(t, err, "Received err %v", err)
|
||||
} else {
|
||||
require.NoErrorf(t, err, "Received err %v", err)
|
||||
}
|
||||
|
||||
for _, dnsEndpoint := range result.Items {
|
||||
if dnsEndpoint.Status.ObservedGeneration != dnsEndpoint.Generation {
|
||||
require.Errorf(t, err, "Unexpected CRD resource result: ObservedGenerations <%v> is not equal to Generation<%v>", dnsEndpoint.Status.ObservedGeneration, dnsEndpoint.Generation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,6 @@ func endpointsFromIngress(ing *v1beta1.Ingress) []*endpoint.Endpoint {
|
||||
for _, hostname := range hostnameList {
|
||||
endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl, providerSpecific)...)
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
|
||||
return endpoints
|
||||
}
|
||||
|
||||
targetsByHeadlessDomain := make(map[string][]string)
|
||||
for _, v := range pods.Items {
|
||||
headlessDomain := hostname
|
||||
if v.Spec.Hostname != "" {
|
||||
@ -181,11 +182,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
|
||||
log.Debugf("Generating matching endpoint %s with HostIP %s", headlessDomain, v.Status.HostIP)
|
||||
// To reduce traffice on the DNS API only add record for running Pods. Good Idea?
|
||||
if v.Status.Phase == v1.PodRunning {
|
||||
if ttl.IsConfigured() {
|
||||
endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessDomain, endpoint.RecordTypeA, ttl, v.Status.HostIP))
|
||||
} else {
|
||||
endpoints = append(endpoints, endpoint.NewEndpoint(headlessDomain, endpoint.RecordTypeA, v.Status.HostIP))
|
||||
}
|
||||
targetsByHeadlessDomain[headlessDomain] = append(targetsByHeadlessDomain[headlessDomain], v.Status.HostIP)
|
||||
} else {
|
||||
log.Debugf("Pod %s is not in running phase", v.Spec.Hostname)
|
||||
}
|
||||
@ -193,11 +190,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
|
||||
log.Debugf("Generating matching endpoint %s with PodIP %s", headlessDomain, v.Status.PodIP)
|
||||
// To reduce traffice on the DNS API only add record for running Pods. Good Idea?
|
||||
if v.Status.Phase == v1.PodRunning {
|
||||
if ttl.IsConfigured() {
|
||||
endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessDomain, endpoint.RecordTypeA, ttl, v.Status.PodIP))
|
||||
} else {
|
||||
endpoints = append(endpoints, endpoint.NewEndpoint(headlessDomain, endpoint.RecordTypeA, v.Status.PodIP))
|
||||
}
|
||||
targetsByHeadlessDomain[headlessDomain] = append(targetsByHeadlessDomain[headlessDomain], v.Status.PodIP)
|
||||
} else {
|
||||
log.Debugf("Pod %s is not in running phase", v.Spec.Hostname)
|
||||
}
|
||||
@ -205,6 +198,20 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
|
||||
|
||||
}
|
||||
|
||||
headlessDomains := []string{}
|
||||
for headlessDomain := range targetsByHeadlessDomain {
|
||||
headlessDomains = append(headlessDomains, headlessDomain)
|
||||
}
|
||||
sort.Strings(headlessDomains)
|
||||
for _, headlessDomain := range headlessDomains {
|
||||
targets := targetsByHeadlessDomain[headlessDomain]
|
||||
if ttl.IsConfigured() {
|
||||
endpoints = append(endpoints, endpoint.NewEndpointWithTTL(headlessDomain, endpoint.RecordTypeA, ttl, targets...))
|
||||
} else {
|
||||
endpoints = append(endpoints, endpoint.NewEndpoint(headlessDomain, endpoint.RecordTypeA, targets...))
|
||||
}
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
||||
@ -218,9 +225,10 @@ func (sc *serviceSource) endpointsFromTemplate(svc *v1.Service, nodeTargets endp
|
||||
return nil, fmt.Errorf("failed to apply template on service %s: %v", svc.String(), err)
|
||||
}
|
||||
|
||||
providerSpecific := getProviderSpecificAnnotations(svc.Annotations)
|
||||
hostnameList := strings.Split(strings.Replace(buf.String(), " ", "", -1), ",")
|
||||
for _, hostname := range hostnameList {
|
||||
endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, nodeTargets)...)
|
||||
endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, nodeTargets, providerSpecific)...)
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
@ -230,9 +238,10 @@ func (sc *serviceSource) endpointsFromTemplate(svc *v1.Service, nodeTargets endp
|
||||
func (sc *serviceSource) endpoints(svc *v1.Service, nodeTargets endpoint.Targets) []*endpoint.Endpoint {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
||||
providerSpecific := getProviderSpecificAnnotations(svc.Annotations)
|
||||
hostnameList := getHostnamesFromAnnotations(svc.Annotations)
|
||||
for _, hostname := range hostnameList {
|
||||
endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, nodeTargets)...)
|
||||
endpoints = append(endpoints, sc.generateEndpoints(svc, hostname, nodeTargets, providerSpecific)...)
|
||||
}
|
||||
|
||||
return endpoints
|
||||
@ -288,7 +297,7 @@ func (sc *serviceSource) setResourceLabel(service v1.Service, endpoints []*endpo
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, nodeTargets endpoint.Targets) []*endpoint.Endpoint {
|
||||
func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, nodeTargets endpoint.Targets, providerSpecific endpoint.ProviderSpecific) []*endpoint.Endpoint {
|
||||
hostname = strings.TrimSuffix(hostname, ".")
|
||||
ttl, err := getTTLFromAnnotations(svc.Annotations)
|
||||
if err != nil {
|
||||
@ -296,19 +305,21 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, nod
|
||||
}
|
||||
|
||||
epA := &endpoint.Endpoint{
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
Labels: endpoint.NewLabels(),
|
||||
Targets: make(endpoint.Targets, 0, defaultTargetsCapacity),
|
||||
DNSName: hostname,
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
Labels: endpoint.NewLabels(),
|
||||
Targets: make(endpoint.Targets, 0, defaultTargetsCapacity),
|
||||
DNSName: hostname,
|
||||
ProviderSpecific: providerSpecific,
|
||||
}
|
||||
|
||||
epCNAME := &endpoint.Endpoint{
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeCNAME,
|
||||
Labels: endpoint.NewLabels(),
|
||||
Targets: make(endpoint.Targets, 0, defaultTargetsCapacity),
|
||||
DNSName: hostname,
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeCNAME,
|
||||
Labels: endpoint.NewLabels(),
|
||||
Targets: make(endpoint.Targets, 0, defaultTargetsCapacity),
|
||||
DNSName: hostname,
|
||||
ProviderSpecific: providerSpecific,
|
||||
}
|
||||
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
@ -1321,7 +1321,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
labels map[string]string
|
||||
annotations map[string]string
|
||||
clusterIP string
|
||||
podIP string
|
||||
podIPs []string
|
||||
selector map[string]string
|
||||
lbs []string
|
||||
podnames []string
|
||||
@ -1343,7 +1343,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
hostnameAnnotationKey: "service.example.org",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1353,7 +1353,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
[]v1.PodPhase{v1.PodRunning, v1.PodRunning},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -1371,7 +1371,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
ttlAnnotationKey: "1",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1381,7 +1381,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
[]v1.PodPhase{v1.PodRunning, v1.PodRunning},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -1398,7 +1398,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
hostnameAnnotationKey: "service.example.org",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1424,7 +1424,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
hostnameAnnotationKey: "service.example.org",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1433,8 +1433,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
[]string{"", ""},
|
||||
[]v1.PodPhase{v1.PodRunning, v1.PodRunning},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -1473,7 +1472,7 @@ func TestHeadlessServices(t *testing.T) {
|
||||
Annotations: tc.annotations,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
PodIP: tc.podIP,
|
||||
PodIP: tc.podIPs[i],
|
||||
Phase: tc.phases[i],
|
||||
},
|
||||
}
|
||||
@ -1522,7 +1521,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
labels map[string]string
|
||||
annotations map[string]string
|
||||
clusterIP string
|
||||
hostIP string
|
||||
hostIPs []string
|
||||
selector map[string]string
|
||||
lbs []string
|
||||
podnames []string
|
||||
@ -1544,7 +1543,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
hostnameAnnotationKey: "service.example.org",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1554,7 +1553,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
[]v1.PodPhase{v1.PodRunning, v1.PodRunning},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -1572,7 +1571,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
ttlAnnotationKey: "1",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1582,7 +1581,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
[]v1.PodPhase{v1.PodRunning, v1.PodRunning},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
|
||||
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -1599,7 +1598,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
hostnameAnnotationKey: "service.example.org",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1625,7 +1624,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
hostnameAnnotationKey: "service.example.org",
|
||||
},
|
||||
v1.ClusterIPNone,
|
||||
"1.1.1.1",
|
||||
[]string{"1.1.1.1", "1.1.1.2"},
|
||||
map[string]string{
|
||||
"component": "foo",
|
||||
},
|
||||
@ -1634,8 +1633,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
[]string{"", ""},
|
||||
[]v1.PodPhase{v1.PodRunning, v1.PodRunning},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
|
||||
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
|
||||
},
|
||||
false,
|
||||
},
|
||||
@ -1674,7 +1672,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
|
||||
Annotations: tc.annotations,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
HostIP: tc.hostIP,
|
||||
HostIP: tc.hostIPs[i],
|
||||
Phase: tc.phases[i],
|
||||
},
|
||||
}
|
||||
|
@ -41,6 +41,12 @@ const (
|
||||
controllerAnnotationValue = "dns-controller"
|
||||
)
|
||||
|
||||
// Provider-specific annotations
|
||||
const (
|
||||
// The annotation used for determining if traffic will go through Cloudflare
|
||||
CloudflareProxiedKey = "external-dns.alpha.kubernetes.io/cloudflare-proxied"
|
||||
)
|
||||
|
||||
const (
|
||||
ttlMinimum = 1
|
||||
ttlMaximum = math.MaxUint32
|
||||
@ -72,7 +78,6 @@ func getHostnamesFromAnnotations(annotations map[string]string) []string {
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
return strings.Split(strings.Replace(hostnameAnnotation, " ", "", -1), ",")
|
||||
}
|
||||
|
||||
@ -82,10 +87,22 @@ func getAliasFromAnnotations(annotations map[string]string) bool {
|
||||
}
|
||||
|
||||
func getProviderSpecificAnnotations(annotations map[string]string) endpoint.ProviderSpecific {
|
||||
if getAliasFromAnnotations(annotations) {
|
||||
return map[string]string{"alias": "true"}
|
||||
providerSpecificAnnotations := endpoint.ProviderSpecific{}
|
||||
|
||||
v, exists := annotations[CloudflareProxiedKey]
|
||||
if exists {
|
||||
providerSpecificAnnotations = append(providerSpecificAnnotations, endpoint.ProviderSpecificProperty{
|
||||
Name: CloudflareProxiedKey,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
return map[string]string{}
|
||||
if getAliasFromAnnotations(annotations) {
|
||||
providerSpecificAnnotations = append(providerSpecificAnnotations, endpoint.ProviderSpecificProperty{
|
||||
Name: "alias",
|
||||
Value: "true",
|
||||
})
|
||||
}
|
||||
return providerSpecificAnnotations
|
||||
}
|
||||
|
||||
// getTargetsFromTargetAnnotation gets endpoints from optional "target" annotation.
|
||||
|
Loading…
Reference in New Issue
Block a user