mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 09:36:58 +02:00
Add Source implementation for Istio Gateway (#694)
* add Istio Gateway Source * add documentation for Istio Gateway Source * make both istio namespace and ingress gateway service configurable * prefix gateway types, constructors, and flags with 'istio-' * fix: add missing sources to source flag docs
This commit is contained in:
parent
a7ac4f9b1e
commit
b9b6842195
349
Gopkg.lock
generated
349
Gopkg.lock
generated
@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e94ea655a0038d2274be202f77a2ea0eb2d3f74dfee674fd5d1f541e81008039"
|
||||
digest = "1:ae9d0182a5cf7dbb025a8fc5821234cc1f26ca342fc41d951a99f71b9adc1b87"
|
||||
name = "cloud.google.com/go"
|
||||
packages = [
|
||||
"compute/metadata",
|
||||
@ -12,7 +12,7 @@
|
||||
revision = "3b1ae45394a234c385be014e9a488f2bb6eef821"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b341fb465b057e991b166d073b35a224f5a84228e5ef7e40b4da7a70c152e7ec"
|
||||
digest = "1:fd38e3b8c27cab6561a7d2e8557205c3ca5c57cbb6d3a79e10f22e73e84fd776"
|
||||
name = "github.com/Azure/azure-sdk-for-go"
|
||||
packages = ["arm/dns"]
|
||||
pruneopts = ""
|
||||
@ -20,7 +20,7 @@
|
||||
version = "v10.0.4-beta"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:767f5f5dd4fa8e4f7f206726361d29aa0f7622b0bb8294b73d071864368c0d6b"
|
||||
digest = "1:f719ef698feb8da2923ebda9a8d553b977320b02182f3797e185202e588a94b1"
|
||||
name = "github.com/Azure/go-autorest"
|
||||
packages = [
|
||||
"autorest",
|
||||
@ -34,7 +34,7 @@
|
||||
version = "v10.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:283a95024c33e84b23f24b1b47e3157ff2df2517d786a2e17bb0e6e4955e94e4"
|
||||
digest = "1:7dc69d1597e4773ec5f64e5c078d55f0f011bb05ec0435346d0649ad978a23fd"
|
||||
name = "github.com/alecthomas/kingpin"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:1399282ad03ac819f0e8a747c888407c5c98bb497d33821a7047c7bae667ede0"
|
||||
digest = "1:a74730e052a45a3fab1d310fdef2ec17ae3d6af16228421e238320846f2aaec8"
|
||||
name = "github.com/alecthomas/template"
|
||||
packages = [
|
||||
".",
|
||||
@ -61,7 +61,7 @@
|
||||
revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7b6c017b0290ccf1dd98c47a51e1db8b72b0863b6c7c52ddaa5a0d894aa3c2fc"
|
||||
digest = "1:d2dc5d0ccc137594ea6fb3870964967b96b43daac19b8093930c7b02873fd5ca"
|
||||
name = "github.com/aliyun/alibaba-cloud-sdk-go"
|
||||
packages = [
|
||||
"sdk",
|
||||
@ -81,7 +81,7 @@
|
||||
version = "1.27.7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f04a72eefe1c7adec1dce30e099cec1e5fea8903a66e2db25bbbdfa66915428d"
|
||||
digest = "1:1c82dd6a02941a3c4f23a32eca182717ab79691939e97d6b971466b780f06eea"
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
packages = [
|
||||
"aws",
|
||||
@ -121,14 +121,14 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d20bdb6bf44087574af3139835946875bb098440426785282c741865b7bc66d3"
|
||||
digest = "1:0c5485088ce274fac2e931c1b979f2619345097b39d91af3239977114adf0320"
|
||||
name = "github.com/beorn7/perks"
|
||||
packages = ["quantile"]
|
||||
pruneopts = ""
|
||||
revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d9d9c71f9776ef8f15b5c0a20246d5303071294743863ac3f4dde056f8c7b40a"
|
||||
digest = "1:85fd00554a6ed5b33687684b76635d532c74141508b5bce2843d85e8a3c9dc91"
|
||||
name = "github.com/cloudflare/cloudflare-go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -136,7 +136,7 @@
|
||||
version = "v0.7.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:31259dbcb4c073aace59b951f5b471b3d5dbc4051b4a9d7e000f4392e143977e"
|
||||
digest = "1:eaeede87b418b97f9dee473f8940fd9b65ca5cdac0503350c7c8f8965ea3cf4d"
|
||||
name = "github.com/coreos/etcd"
|
||||
packages = [
|
||||
"client",
|
||||
@ -158,7 +158,7 @@
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0a39ec8bf5629610a4bc7873a92039ee509246da3cef1a0ea60f1ed7e5f9cea5"
|
||||
digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = ""
|
||||
@ -167,7 +167,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:64ee6871ef691c663f910e29bc2f7c10c8c342b06665920f1138b6aa8b11cb5a"
|
||||
digest = "1:dc166ce7345c060c2153561130d6d49ac580c804226ac675e368d533b36eb169"
|
||||
name = "github.com/denverdino/aliyungo"
|
||||
packages = [
|
||||
"metadata",
|
||||
@ -177,7 +177,7 @@
|
||||
revision = "69560d9530f5265ba00ffad2520d7ef01c2cddd4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2426da75f49e5b8507a6ed5d4c49b06b2ff795f4aec401c106b7db8fb2625cd7"
|
||||
digest = "1:6098222470fe0172157ce9bbef5d2200df4edde17ee649c5d6e48330e4afa4c6"
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -185,7 +185,7 @@
|
||||
version = "v3.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3da5806ef37ea163fee80ed179d40a5e013e671ccbe321a04c47c5aee3d5080a"
|
||||
digest = "1:32d1941b093bb945de75b0276348494be318d34f3df39c4413d61e002c800bc6"
|
||||
name = "github.com/digitalocean/godo"
|
||||
packages = [
|
||||
".",
|
||||
@ -196,7 +196,7 @@
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ca3b228bf258217cff2070f4045e53729886c66a27bf9cce30dcbf8a575ea86a"
|
||||
digest = "1:5ffd39844bdd1259a6227d544f582c6686ce43c8c44399a46052fe3bd2bed93c"
|
||||
name = "github.com/dnsimple/dnsimple-go"
|
||||
packages = ["dnsimple"]
|
||||
pruneopts = ""
|
||||
@ -204,7 +204,7 @@
|
||||
version = "v0.14.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bfce2cc5b829073f93962e742275d45913948e22d182fbc5464104da1c5f2f89"
|
||||
digest = "1:e17d18b233f506404061c27ac4a08624dad38dcd0d49f9cfdae67a7772a4fb8c"
|
||||
name = "github.com/exoscale/egoscale"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -213,21 +213,22 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:bc12846e4bae094e01a33ef98cad0a1afa35da37090e5126513be6f747e074ab"
|
||||
digest = "1:ae7fb2062735e966ab69d14d2a091f3778b0d676dc8d1f01d092bcb0fb8ed45b"
|
||||
name = "github.com/ffledgling/pdns-go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "524e7daccd99651cdb56426eb15b7d61f9597a5c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a31fbb19d2b38d50bc125d97b7c3e7a286d3f6f37d18756011eb6e7d1a9fa7d0"
|
||||
digest = "1:b13707423743d41665fd23f0c36b2f37bb49c30e94adb813319c44188a51ba22"
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
|
||||
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bbc763f3c703dc3c6a99a22c1318760099b52bc00a47a36dc4462e88eee7846b"
|
||||
digest = "1:a00483fe4106b86fb1187a92b5cf6915c85f294ed4c129ccbe7cb1f1a06abd46"
|
||||
name = "github.com/go-ini/ini"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -235,7 +236,7 @@
|
||||
version = "v1.32.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:cdeb6a9eb9f2356b2987c401d013d41e018b819ee1e8d5a1b32a5b714e53c392"
|
||||
digest = "1:8e67153fc0a9fb0d6c9707e36cf80e217a012364307b222eb4ba6828f7e881e6"
|
||||
name = "github.com/go-resty/resty"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -243,11 +244,23 @@
|
||||
version = "v1.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:673df1d02ca0c6f51458fe94bbb6fae0b05e54084a31db2288f1c4321255c2da"
|
||||
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",
|
||||
"jsonpb",
|
||||
"proto",
|
||||
"protoc-gen-gogo/descriptor",
|
||||
"sortkeys",
|
||||
"types",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "636bf0302bc95575d69441b25a2603156ffdddf1"
|
||||
@ -261,17 +274,20 @@
|
||||
revision = "44145f04b68cf362d9c4df2182967c2275eaefed"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4321edcf693514c7a3811c9b58a19705ef0b4aaec5ee4e5baa2f5c07ad3b96ae"
|
||||
digest = "1:3dd078fda7500c341bc26cfbc6c6a34614f295a2457149fc1045cab767cbcf18"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = [
|
||||
"jsonpb",
|
||||
"proto",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/struct",
|
||||
"ptypes/timestamp",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "8616e8ee5e20a1704615e6c8d7afcdac06087a67"
|
||||
revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -297,7 +313,7 @@
|
||||
revision = "44d81051d367757e1c7c6a5a86423ece9afcf63c"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1962b5d00f5285d08504697049627d45ad876912894528d31cdc1c05cdc853f6"
|
||||
digest = "1:16b2837c8b3cf045fa2cdc82af0cf78b19582701394484ae76b2c3bc3c99ad73"
|
||||
name = "github.com/googleapis/gnostic"
|
||||
packages = [
|
||||
"OpenAPIv2",
|
||||
@ -310,7 +326,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:815036d12757902f85888f3cb0440c2e00220dd4177e4c2bb048e03259db077a"
|
||||
digest = "1:54a44d48a24a104e078ef5f94d82f025a6be757e7c42b4370c621a3928d6ab7c"
|
||||
name = "github.com/gophercloud/gophercloud"
|
||||
packages = [
|
||||
".",
|
||||
@ -326,9 +342,25 @@
|
||||
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:8c4d156acec272201ffc4d1bdb9302de1c48314e0451eb38c70150cf11bdb33a"
|
||||
digest = "1:009a1928b8c096338b68b5822d838a72b4d8520715c1463614476359f3282ec8"
|
||||
name = "github.com/gregjones/httpcache"
|
||||
packages = [
|
||||
".",
|
||||
@ -337,6 +369,33 @@
|
||||
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",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "20f1fb78b0740ba8c3cb143a61e86ba5c8669768"
|
||||
version = "v0.5.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:af7e132906cb360f4d7c34a9e1434825467f21c4ff5c521ad4cc5b55352876a8"
|
||||
name = "github.com/imdario/mergo"
|
||||
@ -344,6 +403,14 @@
|
||||
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"
|
||||
@ -353,14 +420,14 @@
|
||||
revision = "61dc5f9b0a655ebf43026f0d8a837ad1e28e4b96"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4f767a115bc8e08576f6d38ab73c376fc1b1cd3bb5041171c9e8668cc7739b52"
|
||||
digest = "1:6f49eae0c1e5dab1dafafee34b207aeb7a42303105960944828c2079b92fc88e"
|
||||
name = "github.com/jmespath/go-jmespath"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "0b12d6b5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:890dd7615573f096655600bbe7beb2f532a437f6d8ef237831894301fca31f23"
|
||||
digest = "1:53ac4e911e12dde0ab68655e2006449d207a5a681f084974da2b06e5dbeaca72"
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -368,14 +435,14 @@
|
||||
version = "1.1.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:def40684a573560241c8344da452fa3574dfc2c7da525903992a3790d2262625"
|
||||
digest = "1:1c88ec29544b281964ed7a9a365b2802a523cd06c50cdee87eb3eec89cd864f4"
|
||||
name = "github.com/kubernetes/repo-infra"
|
||||
packages = ["verify/boilerplate/test"]
|
||||
pruneopts = ""
|
||||
revision = "c2f9667a4c29e70a39b0e89db2d4f0cab907dbee"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c3aa5f9d5119ca1cfdaa41a5084e3deceef0460eef3e6c71b58fa50e500f01a0"
|
||||
digest = "1:7c23a751ce2f84663fa411acb87eae0da2d09c39a8e99b08bd8f65fae75d8928"
|
||||
name = "github.com/linki/instrumented_http"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -383,7 +450,7 @@
|
||||
version = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:93d29291d0c37678592d77ee847031aec2ce1631f3ce4cf975b77216e8bd4a01"
|
||||
digest = "1:1c41354ef11c9dbae2fe1ceee8369fcb2634977ba07e701e19ea53e8742c5420"
|
||||
name = "github.com/linode/linodego"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -392,7 +459,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:49a8b01a6cd6558d504b65608214ca40a78000e1b343ed0da5c6a9ccd83d6d30"
|
||||
digest = "1:63722a4b1e1717be7b98fc686e0b30d5e7f734b9e93d7dee86293b6deab7ea28"
|
||||
name = "github.com/matttproud/golang_protobuf_extensions"
|
||||
packages = ["pbutil"]
|
||||
pruneopts = ""
|
||||
@ -415,7 +482,15 @@
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7aef6d4ad1b4a613d66ed554010c552a249e9afabcb079f54528a298474549cc"
|
||||
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 = ""
|
||||
@ -423,7 +498,7 @@
|
||||
version = "v0.6.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2062e45c462d0327f680340dce46fe11ae2d34bf802e15e397cb1d6c4d159b39"
|
||||
digest = "1:70df8e71a953626770223d4982801fa73e7e99cbfcca068b95127f72af9b9edd"
|
||||
name = "github.com/oracle/oci-go-sdk"
|
||||
packages = [
|
||||
"common",
|
||||
@ -435,14 +510,14 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:b7be9a944fe102bf466420fa8a064534dd12547a0482f5b684d228425b559b56"
|
||||
digest = "1:c24598ffeadd2762552269271b3b1510df2d83ee6696c1e543a0ff653af494bc"
|
||||
name = "github.com/petar/GoLLRB"
|
||||
packages = ["llrb"]
|
||||
pruneopts = ""
|
||||
revision = "53be0d36a84c2a886ca057d34b6aa4468df9ccb4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:6db21ad64a13fe79220e47fcc895e13b8da923676a3a024f98210fca57a10d9a"
|
||||
digest = "1:b46305723171710475f2dd37547edd57b67b9de9f2a6267cafdd98331fd6897f"
|
||||
name = "github.com/peterbourgon/diskv"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -465,19 +540,19 @@
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:981835985f655d1d380cc6aa7d9fa9ad7abfaf40c75da200fd40d864cd05a7c3"
|
||||
digest = "1:2f69dc6b2685b31a1a410ef697410aa8a669704fb201d45dbd8c1911728afa75"
|
||||
name = "github.com/prometheus/client_golang"
|
||||
packages = [
|
||||
"prometheus",
|
||||
"prometheus/promhttp",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "c5b7fccd204277076155f10851dad72b76a49317"
|
||||
version = "v0.8.0"
|
||||
revision = "967789050ba94deca04a5e84cce8ad472ce313c1"
|
||||
version = "v0.9.0-pre1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:83bf37d060fca77e959fe5ceee81e58bbd1b01836f4addc70043a948e9912547"
|
||||
digest = "1:60aca47f4eeeb972f1b9da7e7db51dee15ff6c59f7b401c1588b8e6771ba15ef"
|
||||
name = "github.com/prometheus/client_model"
|
||||
packages = ["go"]
|
||||
pruneopts = ""
|
||||
@ -485,7 +560,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:7221d79e41a24b2245d06f331d0825b479a9acd0bd05a8353806c7bf38395795"
|
||||
digest = "1:e3aa5178be4fc4ae8cdb37d11c02f7490c00450a9f419e6aa84d02d3b47e90d2"
|
||||
name = "github.com/prometheus/common"
|
||||
packages = [
|
||||
"expfmt",
|
||||
@ -496,7 +571,7 @@
|
||||
revision = "2e54d0b93cba2fd133edc32211dcc32c06ef72ca"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:91345f4cce04248cf4998c4f70a82579c1468101767636acf5af2e1556904933"
|
||||
digest = "1:a6a85fc81f2a06ccac3d45005523afbeee45138d781d4f3cb7ad9889d5c65aab"
|
||||
name = "github.com/prometheus/procfs"
|
||||
packages = [
|
||||
".",
|
||||
@ -514,7 +589,7 @@
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:75e2c10fd48881dc9400b7b70281270923e01c44f1f5cb4bbc5ba8cac8ca3026"
|
||||
digest = "1:3ac248add5bb40a3c631c5334adcd09aa72d15af2768a5bc0274084ea7b2e5ba"
|
||||
name = "github.com/sirupsen/logrus"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -522,14 +597,23 @@
|
||||
version = "v1.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:11705e15791a8855c4b81839cbd71722b82f0304bf5e4225c878e6961c0d4c25"
|
||||
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 = "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
|
||||
revision = "9a97c102cda95a86cec2345a6f09f55a939babf5"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ba8fed52de60135b7efd5d832b997fb5b10fa09f227fa385174faa69f4219e4e"
|
||||
digest = "1:306417ea2f31ea733df356a2b895de63776b6a5107085b33458e5cd6eb1d584d"
|
||||
name = "github.com/stretchr/objx"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
@ -537,7 +621,7 @@
|
||||
version = "v0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a70d585d45f695f2e8e6782569bdf181419667a35e6035ceb086706b495aa21a"
|
||||
digest = "1:a30066593578732a356dc7e5d7f78d69184ca65aeeff5939241a3ab10559bb06"
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
@ -558,21 +642,53 @@
|
||||
revision = "ac974c61c2f990f4115b119354b5e0b47550e888"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f98e0b7c7bd110a49d8bb56c9eefcef4f547f5d789025d3bfe9bd6b83125221b"
|
||||
digest = "1:cb2800cd5716e9d6172888e0e3ffe1f9c07b7f142eb83d49a391029bcf4f6cc1"
|
||||
name = "github.com/ugorji/go"
|
||||
packages = ["codec"]
|
||||
pruneopts = ""
|
||||
revision = "ded73eae5db7e7a0ef6f55aace87a2873c5d2b74"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d275cbe5049a91bd638e89ad365617be7eefc6d371fe8873fc658eba81dcfd24"
|
||||
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 = [
|
||||
".",
|
||||
"buffer",
|
||||
"internal/bufferpool",
|
||||
"internal/color",
|
||||
"internal/exit",
|
||||
"zapcore",
|
||||
"zapgrpc",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "ff33455a0e382e8a81d14dd7c922020b6b5e7982"
|
||||
version = "v1.9.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0f67b4bbcdf1caaee0450f225a53fd2c2f8793578cc7810eb09c290e008e33ac"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["ssh/terminal"]
|
||||
pruneopts = ""
|
||||
revision = "d172538b2cfce0c13cee31e647d0367aa8cd2486"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:4a5f1ce99f596fe9e26a9d47d61b87642701197ce610100ea628796af88a6544"
|
||||
digest = "1:a18243d76a2a6a1ee8cfbbb1caea25fc61dffa4ca175ea7c8a9c2cf056336155"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
@ -580,14 +696,16 @@
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"internal/timeseries",
|
||||
"lex/httplex",
|
||||
"publicsuffix",
|
||||
"trace",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
revision = "bb807669a61aca6092d8137da1fab2150bb96ad7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2fef2e19e90f29efd775d58d66b5e100139fedbe24cf749f1c085c0a5aee86d3"
|
||||
digest = "1:dad5a319c4710358be1f2bf68f9fb7f90a71d7c641221b79801d5667b28f19e3"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
@ -600,11 +718,11 @@
|
||||
revision = "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3830eb23292100e91d0fad721390e075e23f7ba34ac757d1c237d78ab74dcdb2"
|
||||
digest = "1:39d88a855976e160babdd254802e1c2ae75ed380328c39742b57928852da6207"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
pruneopts = ""
|
||||
revision = "8f0908ab3b2457e2e15403d3697c9ef5cb4b57a9"
|
||||
revision = "13d03a9a82fba647c21a0ef8fba44a795d0f0835"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -615,7 +733,7 @@
|
||||
revision = "fbb02b2291d28baffd63558aa44b4b56f178d650"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ab84306e7e74b9f01b9f1480d46cca9325f8c512567a0e7b8888d04ff627a5ba"
|
||||
digest = "1:2ad38d79865e33dde6157b7048debd6e7d47e0709df7b5e11bb888168e316908"
|
||||
name = "google.golang.org/api"
|
||||
packages = [
|
||||
"dns/v1",
|
||||
@ -627,7 +745,7 @@
|
||||
revision = "a0ff90edab763c86aa88f2b1eb4f3301b82f6336"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0b45fac4876cbd496ed7b95406b05c8c1eba559b43c82f2dda1b0e1bbe6cd1b6"
|
||||
digest = "1:41e2b7e287117f6136f75286d48072ecf781ba54823ffeb2098e152e7dc45ef6"
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
".",
|
||||
@ -644,6 +762,49 @@
|
||||
pruneopts = ""
|
||||
revision = "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e43f1cb3f488a0c2be85939c2a594636f60b442a12a196c778bd2d6c9aca3df7"
|
||||
name = "google.golang.org/genproto"
|
||||
packages = ["googleapis/rpc/status"]
|
||||
pruneopts = ""
|
||||
revision = "11092d34479b07829b72e10713b159248caf5dad"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ca75b3775a5d4e5d1fb48f57ef0865b4aaa8b3f00e6b52be68db991c4594e0a7"
|
||||
name = "google.golang.org/grpc"
|
||||
packages = [
|
||||
".",
|
||||
"balancer",
|
||||
"balancer/base",
|
||||
"balancer/roundrobin",
|
||||
"codes",
|
||||
"connectivity",
|
||||
"credentials",
|
||||
"encoding",
|
||||
"encoding/proto",
|
||||
"grpclog",
|
||||
"internal",
|
||||
"internal/backoff",
|
||||
"internal/channelz",
|
||||
"internal/envconfig",
|
||||
"internal/grpcrand",
|
||||
"internal/transport",
|
||||
"keepalive",
|
||||
"metadata",
|
||||
"naming",
|
||||
"peer",
|
||||
"resolver",
|
||||
"resolver/dns",
|
||||
"resolver/passthrough",
|
||||
"stats",
|
||||
"status",
|
||||
"tap",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "32fb0ac620c32ba40a4626ddf94d90d12cce3455"
|
||||
version = "v1.14.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e5d1fb981765b6f7513f793a3fcaac7158408cca77f75f7311ac82cc88e9c445"
|
||||
name = "gopkg.in/inf.v0"
|
||||
@ -653,15 +814,46 @@
|
||||
version = "v0.9.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:10cf86195bddd2e0d686eec4fb35f35510baf6ce8393cbcfb664b9b88db7d747"
|
||||
digest = "1:f0620375dd1f6251d9973b5f2596228cc8042e887cd7f827e4220bc1ce8c30e2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = ""
|
||||
revision = "53feefa2559fb8dfa8d81baad31be332c97d6c77"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:6043867e27773bdc28ff2739d3743ad7d52472e356b6fc9406e4a175939a6ecc"
|
||||
branch = "release-1.0"
|
||||
digest = "1:bc43af6616d8ca12a7b8e806874387f0f1e181c08f547e9cd77f6cbac8cefd86"
|
||||
name = "istio.io/api"
|
||||
packages = [
|
||||
"authentication/v1alpha1",
|
||||
"mesh/v1alpha1",
|
||||
"mixer/v1",
|
||||
"mixer/v1/config/client",
|
||||
"networking/v1alpha3",
|
||||
"rbac/v1alpha1",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "76349c53b87f03f1e610b3aa3843dba3c38138d7"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7eb25280e1f610470bb0c43ab6c91573cfc78672a58542106b9b71705581429a"
|
||||
name = "istio.io/istio"
|
||||
packages = [
|
||||
"pilot/pkg/config/kube/crd",
|
||||
"pilot/pkg/model",
|
||||
"pilot/pkg/model/test",
|
||||
"pilot/pkg/serviceregistry/kube",
|
||||
"pkg/cache",
|
||||
"pkg/kube",
|
||||
"pkg/log",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "42773aacced474d97159902d20579a25b1f98106"
|
||||
version = "1.0.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f420c8548c93242d8e5dcfa5b34e0243883b4e660f65076e869daafac877144d"
|
||||
name = "k8s.io/api"
|
||||
packages = [
|
||||
"admissionregistration/v1alpha1",
|
||||
@ -695,15 +887,31 @@
|
||||
"storage/v1beta1",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "183f3326a9353bd6d41430fc80f96259331d029c"
|
||||
revision = "072894a440bdee3a891dea811fe42902311cd2a3"
|
||||
version = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a855f74be59f83ed0950a9a2b70d8c8af01fb5782d060c7dec67ae39033f30dc"
|
||||
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",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "8e7f43002fec5394a8d96ebca781aa9d4b37aaef"
|
||||
version = "kubernetes-1.10.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:b6b2fb7b4da1ac973b64534ace2299a02504f16bc7820cb48edb8ca4077183e1"
|
||||
name = "k8s.io/apimachinery"
|
||||
packages = [
|
||||
"pkg/api/errors",
|
||||
"pkg/api/meta",
|
||||
"pkg/api/resource",
|
||||
"pkg/apis/meta/internalversion",
|
||||
"pkg/apis/meta/v1",
|
||||
"pkg/apis/meta/v1/unstructured",
|
||||
"pkg/apis/meta/v1beta1",
|
||||
@ -721,7 +929,9 @@
|
||||
"pkg/runtime/serializer/versioning",
|
||||
"pkg/selection",
|
||||
"pkg/types",
|
||||
"pkg/util/cache",
|
||||
"pkg/util/clock",
|
||||
"pkg/util/diff",
|
||||
"pkg/util/errors",
|
||||
"pkg/util/framer",
|
||||
"pkg/util/intstr",
|
||||
@ -742,10 +952,10 @@
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "103fd098999dc9c0c88536f5c9ad2e5da39373ae"
|
||||
version = "kubernetes-1.11.1"
|
||||
version = "kubernetes-1.11.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3c4611c2b28fdc62391698bba7f212050f0f9ed75f3648f37ec3bcf8a83bf96d"
|
||||
digest = "1:d04779a8de7d5465e0463bd986506348de5e89677c74777f695d3145a7a8d15e"
|
||||
name = "k8s.io/client-go"
|
||||
packages = [
|
||||
"discovery",
|
||||
@ -826,19 +1036,23 @@
|
||||
"testing",
|
||||
"third_party/forked/golang/template",
|
||||
"tools/auth",
|
||||
"tools/cache",
|
||||
"tools/clientcmd",
|
||||
"tools/clientcmd/api",
|
||||
"tools/clientcmd/api/latest",
|
||||
"tools/clientcmd/api/v1",
|
||||
"tools/metrics",
|
||||
"tools/pager",
|
||||
"tools/reference",
|
||||
"transport",
|
||||
"util/buffer",
|
||||
"util/cert",
|
||||
"util/connrotation",
|
||||
"util/flowcontrol",
|
||||
"util/homedir",
|
||||
"util/integer",
|
||||
"util/jsonpath",
|
||||
"util/retry",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "7d04d0e2a0a1a4d4a1cd6baa432a2301492e4e65"
|
||||
@ -846,7 +1060,7 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d93d8bcb5f04d6b59eafdb9fa1a80f187d2542611670bfabc0ea8e031ab874a2"
|
||||
digest = "1:526095379da1098c3f191a0008cc59c9bf9927492e63da7689e5de424219c162"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = ["pkg/util/proto"]
|
||||
pruneopts = ""
|
||||
@ -906,6 +1120,9 @@
|
||||
"google.golang.org/api/dns/v1",
|
||||
"google.golang.org/api/googleapi",
|
||||
"gopkg.in/yaml.v2",
|
||||
"istio.io/api/networking/v1alpha3",
|
||||
"istio.io/istio/pilot/pkg/config/kube/crd",
|
||||
"istio.io/istio/pilot/pkg/model",
|
||||
"k8s.io/api/core/v1",
|
||||
"k8s.io/api/extensions/v1beta1",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
|
40
Gopkg.toml
40
Gopkg.toml
@ -46,7 +46,7 @@ ignored = ["github.com/kubernetes/repo-infra/kazel"]
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/prometheus/client_golang"
|
||||
version = "0.8.0"
|
||||
version = "0.9.0-pre1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/sirupsen/logrus"
|
||||
@ -56,10 +56,6 @@ ignored = ["github.com/kubernetes/repo-infra/kazel"]
|
||||
name = "github.com/stretchr/testify"
|
||||
version = "~1.2.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
version = "~8.0.0"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/kubernetes/repo-infra"
|
||||
revision = "c2f9667a4c29e70a39b0e89db2d4f0cab907dbee"
|
||||
@ -82,4 +78,36 @@ ignored = ["github.com/kubernetes/repo-infra/kazel"]
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/aliyun/alibaba-cloud-sdk-go"
|
||||
version = "1.27.7"
|
||||
version = "1.27.7"
|
||||
|
||||
[[constraint]]
|
||||
name = "istio.io/istio"
|
||||
version = "1.0.0"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/golang/protobuf"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
version = "8.0.0"
|
||||
|
||||
[[override]]
|
||||
name = "k8s.io/apimachinery"
|
||||
version = "kubernetes-1.11.0"
|
||||
|
||||
[[override]]
|
||||
name = "k8s.io/api"
|
||||
version = "kubernetes-1.11.0"
|
||||
|
||||
[[override]]
|
||||
name = "golang.org/x/sys"
|
||||
revision = "13d03a9a82fba647c21a0ef8fba44a795d0f0835"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/spf13/pflag"
|
||||
version = "1.0.2"
|
||||
|
||||
[[override]]
|
||||
name = "golang.org/x/net"
|
||||
revision = "bb807669a61aca6092d8137da1fab2150bb96ad7"
|
||||
|
@ -21,6 +21,7 @@ All sources live in package `source`.
|
||||
|
||||
* `ServiceSource`: collects all Services that have an external IP and returns them as Endpoint objects. The desired DNS name corresponds to an annotation set on the Service or is compiled from the Service attributes via the FQDN Go template string.
|
||||
* `IngressSource`: collects all Ingresses that have an external IP and returns them as Endpoint objects. The desired DNS name corresponds to the host rules defined in the Ingress object.
|
||||
* `IstioGatewaySource`: collects all Istio Gateways and returns them as Endpoint objects. The desired DNS name corresponds to the hosts listed within the servers spec of each Gateway object.
|
||||
* `FakeSource`: returns a random list of Endpoints for the purpose of testing providers without having access to a Kubernetes cluster.
|
||||
* `ConnectorSource`: returns a list of Endpoint objects which are served by a tcp server configured through `connector-source-server` flag.
|
||||
* `CRDSource`: returns a list of Endpoint objects sourced from the spec of CRD objects. For more details refer to [CRD source](../crd-source.md) documentation.
|
||||
|
191
docs/tutorials/istio.md
Normal file
191
docs/tutorials/istio.md
Normal file
@ -0,0 +1,191 @@
|
||||
# Configuring ExternalDNS to use the Istio Gateway Source
|
||||
This tutorial describes how to configure ExternalDNS to use the Istio Gateway source.
|
||||
It is meant to supplement the other provider-specific setup tutorials.
|
||||
|
||||
**Note:** Using the Istio Gateway source requires Istio >=1.0.0.
|
||||
|
||||
### Manifest (for clusters without RBAC enabled)
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: external-dns
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: external-dns
|
||||
spec:
|
||||
containers:
|
||||
- name: external-dns
|
||||
image: registry.opensource.zalan.do/teapot/external-dns:latest
|
||||
args:
|
||||
- --source=service
|
||||
- --source=ingress
|
||||
- --source=istio-gateway
|
||||
- --istio-ingress-gateway=custom-istio-namespace/custom-istio-ingressgateway # omit to use the default (istio-system/istio-ingressgateway)
|
||||
- --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
|
||||
- --provider=aws
|
||||
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
|
||||
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
|
||||
- --registry=txt
|
||||
- --txt-owner-id=my-identifier
|
||||
```
|
||||
|
||||
### Manifest (for clusters with RBAC enabled)
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: external-dns
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: external-dns
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["services"]
|
||||
verbs: ["get","watch","list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get","watch","list"]
|
||||
- apiGroups: ["extensions"]
|
||||
resources: ["ingresses"]
|
||||
verbs: ["get","watch","list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["list"]
|
||||
- apiGroups: ["networking.istio.io"]
|
||||
resources: ["gateways"]
|
||||
verbs: ["get","watch","list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: external-dns-viewer
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: external-dns
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: external-dns
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: external-dns
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: external-dns
|
||||
spec:
|
||||
serviceAccountName: external-dns
|
||||
containers:
|
||||
- name: external-dns
|
||||
image: registry.opensource.zalan.do/teapot/external-dns:latest
|
||||
args:
|
||||
- --source=service
|
||||
- --source=ingress
|
||||
- --source=istio-gateway
|
||||
- --istio-ingress-gateway=custom-istio-namespace/custom-istio-ingressgateway # omit to use the default (istio-system/istio-ingressgateway)
|
||||
- --domain-filter=external-dns-test.my-org.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
|
||||
- --provider=aws
|
||||
- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
|
||||
- --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
|
||||
- --registry=txt
|
||||
- --txt-owner-id=my-identifier
|
||||
```
|
||||
|
||||
### Verify External DNS works (Gateway example)
|
||||
Follow the [Istio ingress traffic tutorial](https://istio.io/docs/tasks/traffic-management/ingress/)
|
||||
to deploy a sample service that will be exposed outside of the service mesh.
|
||||
The following are relevant snippets from that tutorial.
|
||||
|
||||
#### Install a sample service
|
||||
With automatic sidecar injection:
|
||||
```bash
|
||||
$ kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.0/samples/httpbin/httpbin.yaml
|
||||
```
|
||||
|
||||
Otherwise:
|
||||
```bash
|
||||
$ kubectl apply -f <(istioctl kube-inject -f https://raw.githubusercontent.com/istio/istio/release-1.0/samples/httpbin/httpbin.yaml)
|
||||
```
|
||||
|
||||
#### Create an Istio Gateway:
|
||||
```bash
|
||||
$ cat <<EOF | kubectl apply -f -
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: httpbin-gateway
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway # use Istio default gateway implementation
|
||||
servers:
|
||||
- port:
|
||||
number: 80
|
||||
name: http
|
||||
protocol: HTTP
|
||||
hosts:
|
||||
- "httpbin.example.com"
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Configure routes for traffic entering via the Gateway:
|
||||
```bash
|
||||
$ cat <<EOF | kubectl apply -f -
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: httpbin
|
||||
spec:
|
||||
hosts:
|
||||
- "httpbin.example.com"
|
||||
gateways:
|
||||
- httpbin-gateway
|
||||
http:
|
||||
- match:
|
||||
- uri:
|
||||
prefix: /status
|
||||
- uri:
|
||||
prefix: /delay
|
||||
route:
|
||||
- destination:
|
||||
port:
|
||||
number: 8000
|
||||
host: httpbin
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Access the sample service using `curl`
|
||||
```bash
|
||||
$ curl -I http://httpbin.example.com/status/200
|
||||
HTTP/1.1 200 OK
|
||||
server: envoy
|
||||
date: Tue, 28 Aug 2018 15:26:47 GMT
|
||||
content-type: text/html; charset=utf-8
|
||||
access-control-allow-origin: *
|
||||
access-control-allow-credentials: true
|
||||
content-length: 0
|
||||
x-envoy-upstream-service-time: 5
|
||||
```
|
||||
|
||||
Accessing any other URL that has not been explicitly exposed should return an HTTP 404 error:
|
||||
```bash
|
||||
$ curl -I http://httpbin.example.com/headers
|
||||
HTTP/1.1 404 Not Found
|
||||
date: Tue, 28 Aug 2018 15:27:48 GMT
|
||||
server: envoy
|
||||
transfer-encoding: chunked
|
||||
```
|
||||
|
||||
**Note:** The `-H` flag in the original Istio tutorial is no longer necessary in the `curl` commands.
|
1
main.go
1
main.go
@ -80,6 +80,7 @@ func main() {
|
||||
KubeConfig: cfg.KubeConfig,
|
||||
KubeMaster: cfg.Master,
|
||||
ServiceTypeFilter: cfg.ServiceTypeFilter,
|
||||
IstioIngressGateway: cfg.IstioIngressGateway,
|
||||
}
|
||||
|
||||
// Lookup all the selected sources by names and pass them the desired configuration.
|
||||
|
@ -39,6 +39,7 @@ type Config struct {
|
||||
Master string
|
||||
KubeConfig string
|
||||
RequestTimeout time.Duration
|
||||
IstioIngressGateway string
|
||||
Sources []string
|
||||
Namespace string
|
||||
AnnotationFilter string
|
||||
@ -102,6 +103,7 @@ var defaultConfig = &Config{
|
||||
Master: "",
|
||||
KubeConfig: "",
|
||||
RequestTimeout: time.Second * 30,
|
||||
IstioIngressGateway: "istio-system/istio-ingressgateway",
|
||||
Sources: nil,
|
||||
Namespace: "",
|
||||
AnnotationFilter: "",
|
||||
@ -196,8 +198,11 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
app.Flag("kubeconfig", "Retrieve target cluster configuration from a Kubernetes configuration file (default: auto-detect)").Default(defaultConfig.KubeConfig).StringVar(&cfg.KubeConfig)
|
||||
app.Flag("request-timeout", "Request timeout when calling Kubernetes APIs. 0s means no timeout").Default(defaultConfig.RequestTimeout.String()).DurationVar(&cfg.RequestTimeout)
|
||||
|
||||
// Flags related to Istio
|
||||
app.Flag("istio-ingress-gateway", "The fully-qualified name of the Istio ingress gateway service (default: istio-system/istio-ingressgateway)").Default(defaultConfig.IstioIngressGateway).StringVar(&cfg.IstioIngressGateway)
|
||||
|
||||
// Flags related to processing sources
|
||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, fake, connector)").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "fake", "connector", "crd")
|
||||
app.Flag("source", "The resource types that are queried for endpoints; specify multiple times for multiple sources (required, options: service, ingress, fake, connector, istio-gateway, crd").Required().PlaceHolder("source").EnumsVar(&cfg.Sources, "service", "ingress", "istio-gateway", "fake", "connector", "crd")
|
||||
app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||
app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
||||
|
@ -32,6 +32,7 @@ var (
|
||||
Master: "",
|
||||
KubeConfig: "",
|
||||
RequestTimeout: time.Second * 30,
|
||||
IstioIngressGateway: "istio-system/istio-ingressgateway",
|
||||
Sources: []string{"service"},
|
||||
Namespace: "",
|
||||
FQDNTemplate: "",
|
||||
@ -81,6 +82,7 @@ var (
|
||||
Master: "http://127.0.0.1:8080",
|
||||
KubeConfig: "/some/path",
|
||||
RequestTimeout: time.Second * 77,
|
||||
IstioIngressGateway: "istio-other/istio-otheringressgateway",
|
||||
Sources: []string{"service", "ingress", "connector"},
|
||||
Namespace: "namespace",
|
||||
FQDNTemplate: "{{.Name}}.service.example.com",
|
||||
@ -153,6 +155,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"--master=http://127.0.0.1:8080",
|
||||
"--kubeconfig=/some/path",
|
||||
"--request-timeout=77s",
|
||||
"--istio-ingress-gateway=istio-other/istio-otheringressgateway",
|
||||
"--source=service",
|
||||
"--source=ingress",
|
||||
"--source=connector",
|
||||
@ -215,6 +218,7 @@ func TestParseFlags(t *testing.T) {
|
||||
"EXTERNAL_DNS_MASTER": "http://127.0.0.1:8080",
|
||||
"EXTERNAL_DNS_KUBECONFIG": "/some/path",
|
||||
"EXTERNAL_DNS_REQUEST_TIMEOUT": "77s",
|
||||
"EXTERNAL_DNS_ISTIO_INGRESS_GATEWAY": "istio-other/istio-otheringressgateway",
|
||||
"EXTERNAL_DNS_SOURCE": "service\ningress\nconnector",
|
||||
"EXTERNAL_DNS_NAMESPACE": "namespace",
|
||||
"EXTERNAL_DNS_FQDN_TEMPLATE": "{{.Name}}.service.example.com",
|
||||
|
285
source/gateway.go
Normal file
285
source/gateway.go
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package source
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
istionetworking "istio.io/api/networking/v1alpha3"
|
||||
istiomodel "istio.io/istio/pilot/pkg/model"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
||||
"github.com/kubernetes-incubator/external-dns/endpoint"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
)
|
||||
|
||||
// gatewaySource is an implementation of Source for Istio Gateway objects.
|
||||
// The gateway implementation uses the spec.servers.hosts values for the hostnames.
|
||||
// Use targetAnnotationKey to explicitly set Endpoint.
|
||||
type gatewaySource struct {
|
||||
kubeClient kubernetes.Interface
|
||||
istioClient istiomodel.ConfigStore
|
||||
istioNamespace string
|
||||
istioIngressGatewayName string
|
||||
namespace string
|
||||
annotationFilter string
|
||||
fqdnTemplate *template.Template
|
||||
combineFQDNAnnotation bool
|
||||
}
|
||||
|
||||
// NewIstioGatewaySource creates a new gatewaySource with the given config.
|
||||
func NewIstioGatewaySource(
|
||||
kubeClient kubernetes.Interface,
|
||||
istioClient istiomodel.ConfigStore,
|
||||
istioIngressGateway string,
|
||||
namespace string,
|
||||
annotationFilter string,
|
||||
fqdnTemplate string,
|
||||
combineFqdnAnnotation bool,
|
||||
) (Source, error) {
|
||||
var (
|
||||
tmpl *template.Template
|
||||
err error
|
||||
)
|
||||
istioNamespace, istioIngressGatewayName, err := parseIngressGateway(istioIngressGateway)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fqdnTemplate != "" {
|
||||
tmpl, err = template.New("endpoint").Funcs(template.FuncMap{
|
||||
"trimPrefix": strings.TrimPrefix,
|
||||
}).Parse(fqdnTemplate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &gatewaySource{
|
||||
kubeClient: kubeClient,
|
||||
istioClient: istioClient,
|
||||
istioNamespace: istioNamespace,
|
||||
istioIngressGatewayName: istioIngressGatewayName,
|
||||
namespace: namespace,
|
||||
annotationFilter: annotationFilter,
|
||||
fqdnTemplate: tmpl,
|
||||
combineFQDNAnnotation: combineFqdnAnnotation,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Endpoints returns endpoint objects for each host-target combination that should be processed.
|
||||
// Retrieves all gateway resources in the source's namespace(s).
|
||||
func (sc *gatewaySource) Endpoints() ([]*endpoint.Endpoint, error) {
|
||||
configs, err := sc.istioClient.List(istiomodel.Gateway.Type, sc.namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configs, err = sc.filterByAnnotations(configs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
endpoints := []*endpoint.Endpoint{}
|
||||
|
||||
for _, config := range configs {
|
||||
// Check controller annotation to see if we are responsible.
|
||||
controller, ok := config.Annotations[controllerAnnotationKey]
|
||||
if ok && controller != controllerAnnotationValue {
|
||||
log.Debugf("Skipping gateway %s/%s because controller value does not match, found: %s, required: %s",
|
||||
config.Namespace, config.Name, controller, controllerAnnotationValue)
|
||||
continue
|
||||
}
|
||||
|
||||
gwEndpoints, err := sc.endpointsFromGatewayConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// apply template if host is missing on gateway
|
||||
if (sc.combineFQDNAnnotation || len(gwEndpoints) == 0) && sc.fqdnTemplate != nil {
|
||||
iEndpoints, err := sc.endpointsFromTemplate(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sc.combineFQDNAnnotation {
|
||||
gwEndpoints = append(gwEndpoints, iEndpoints...)
|
||||
} else {
|
||||
gwEndpoints = iEndpoints
|
||||
}
|
||||
}
|
||||
|
||||
if len(gwEndpoints) == 0 {
|
||||
log.Debugf("No endpoints could be generated from gateway %s/%s", config.Namespace, config.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("Endpoints generated from gateway: %s/%s: %v", config.Namespace, config.Name, gwEndpoints)
|
||||
sc.setResourceLabel(config, gwEndpoints)
|
||||
endpoints = append(endpoints, gwEndpoints...)
|
||||
}
|
||||
|
||||
for _, ep := range endpoints {
|
||||
sort.Sort(ep.Targets)
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func (sc *gatewaySource) endpointsFromTemplate(config *istiomodel.Config) ([]*endpoint.Endpoint, error) {
|
||||
// Process the whole template string
|
||||
var buf bytes.Buffer
|
||||
err := sc.fqdnTemplate.Execute(&buf, config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to apply template on istio config %s: %v", config, err)
|
||||
}
|
||||
|
||||
hostnames := buf.String()
|
||||
|
||||
ttl, err := getTTLFromAnnotations(config.Annotations)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
|
||||
targets := getTargetsFromTargetAnnotation(config.Annotations)
|
||||
|
||||
if len(targets) == 0 {
|
||||
targets, err = sc.targetsFromIstioIngressStatus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var endpoints []*endpoint.Endpoint
|
||||
// splits the FQDN template and removes the trailing periods
|
||||
hostnameList := strings.Split(strings.Replace(hostnames, " ", "", -1), ",")
|
||||
for _, hostname := range hostnameList {
|
||||
hostname = strings.TrimSuffix(hostname, ".")
|
||||
endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl)...)
|
||||
}
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
// filterByAnnotations filters a list of configs by a given annotation selector.
|
||||
func (sc *gatewaySource) filterByAnnotations(configs []istiomodel.Config) ([]istiomodel.Config, error) {
|
||||
labelSelector, err := metav1.ParseToLabelSelector(sc.annotationFilter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// empty filter returns original list
|
||||
if selector.Empty() {
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
filteredList := []istiomodel.Config{}
|
||||
|
||||
for _, config := range configs {
|
||||
// convert the annotations to an equivalent label selector
|
||||
annotations := labels.Set(config.Annotations)
|
||||
|
||||
// include if the annotations match the selector
|
||||
if selector.Matches(annotations) {
|
||||
filteredList = append(filteredList, config)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredList, nil
|
||||
}
|
||||
|
||||
func (sc *gatewaySource) setResourceLabel(config istiomodel.Config, endpoints []*endpoint.Endpoint) {
|
||||
for _, ep := range endpoints {
|
||||
ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("gateway/%s/%s", config.Namespace, config.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (sc *gatewaySource) targetsFromIstioIngressStatus() (targets endpoint.Targets, err error) {
|
||||
if svc, e := sc.kubeClient.CoreV1().Services(sc.istioNamespace).Get(sc.istioIngressGatewayName, metav1.GetOptions{}); e != nil {
|
||||
err = e
|
||||
} else {
|
||||
for _, lb := range svc.Status.LoadBalancer.Ingress {
|
||||
if lb.IP != "" {
|
||||
targets = append(targets, lb.IP)
|
||||
}
|
||||
if lb.Hostname != "" {
|
||||
targets = append(targets, lb.Hostname)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// endpointsFromGatewayConfig extracts the endpoints from an Istio Gateway Config object
|
||||
func (sc *gatewaySource) endpointsFromGatewayConfig(config istiomodel.Config) ([]*endpoint.Endpoint, error) {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
||||
ttl, err := getTTLFromAnnotations(config.Annotations)
|
||||
if err != nil {
|
||||
log.Warn(err)
|
||||
}
|
||||
|
||||
targets := getTargetsFromTargetAnnotation(config.Annotations)
|
||||
|
||||
if len(targets) == 0 {
|
||||
targets, err = sc.targetsFromIstioIngressStatus()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
gateway := config.Spec.(*istionetworking.Gateway)
|
||||
|
||||
for _, server := range gateway.Servers {
|
||||
for _, host := range server.Hosts {
|
||||
if host == "" {
|
||||
continue
|
||||
}
|
||||
endpoints = append(endpoints, endpointsForHostname(host, targets, ttl)...)
|
||||
}
|
||||
}
|
||||
|
||||
hostnameList := getHostnamesFromAnnotations(config.Annotations)
|
||||
for _, hostname := range hostnameList {
|
||||
endpoints = append(endpoints, endpointsForHostname(hostname, targets, ttl)...)
|
||||
}
|
||||
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
func parseIngressGateway(ingressGateway string) (namespace, name string, err error) {
|
||||
parts := strings.Split(ingressGateway, "/")
|
||||
if len(parts) != 2 {
|
||||
err = fmt.Errorf("invalid ingress gateway service (namespace/name) found '%v'", ingressGateway)
|
||||
} else {
|
||||
namespace, name = parts[0], parts[1]
|
||||
}
|
||||
|
||||
return
|
||||
}
|
1159
source/gateway_test.go
Normal file
1159
source/gateway_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -125,24 +125,6 @@ func (sc *ingressSource) Endpoints() ([]*endpoint.Endpoint, error) {
|
||||
return endpoints, nil
|
||||
}
|
||||
|
||||
// get endpoints from optional "target" annotation
|
||||
// Returns empty endpoints array if none are found.
|
||||
func getTargetsFromTargetAnnotation(ing *v1beta1.Ingress) endpoint.Targets {
|
||||
var targets endpoint.Targets
|
||||
|
||||
// Get the desired hostname of the ingress from the annotation.
|
||||
targetAnnotation, exists := ing.Annotations[targetAnnotationKey]
|
||||
if exists && targetAnnotation != "" {
|
||||
// splits the hostname annotation and removes the trailing periods
|
||||
targetsList := strings.Split(strings.Replace(targetAnnotation, " ", "", -1), ",")
|
||||
for _, targetHostname := range targetsList {
|
||||
targetHostname = strings.TrimSuffix(targetHostname, ".")
|
||||
targets = append(targets, targetHostname)
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
func (sc *ingressSource) endpointsFromTemplate(ing *v1beta1.Ingress) ([]*endpoint.Endpoint, error) {
|
||||
// Process the whole template string
|
||||
var buf bytes.Buffer
|
||||
@ -158,7 +140,7 @@ func (sc *ingressSource) endpointsFromTemplate(ing *v1beta1.Ingress) ([]*endpoin
|
||||
log.Warn(err)
|
||||
}
|
||||
|
||||
targets := getTargetsFromTargetAnnotation(ing)
|
||||
targets := getTargetsFromTargetAnnotation(ing.Annotations)
|
||||
|
||||
if len(targets) == 0 {
|
||||
targets = targetsFromIngressStatus(ing.Status)
|
||||
@ -220,7 +202,7 @@ func endpointsFromIngress(ing *v1beta1.Ingress) []*endpoint.Endpoint {
|
||||
log.Warn(err)
|
||||
}
|
||||
|
||||
targets := getTargetsFromTargetAnnotation(ing)
|
||||
targets := getTargetsFromTargetAnnotation(ing.Annotations)
|
||||
|
||||
if len(targets) == 0 {
|
||||
targets = targetsFromIngressStatus(ing.Status)
|
||||
@ -250,46 +232,6 @@ func endpointsFromIngress(ing *v1beta1.Ingress) []*endpoint.Endpoint {
|
||||
return endpoints
|
||||
}
|
||||
|
||||
func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoint.TTL) []*endpoint.Endpoint {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
||||
var aTargets endpoint.Targets
|
||||
var cnameTargets endpoint.Targets
|
||||
|
||||
for _, t := range targets {
|
||||
switch suitableType(t) {
|
||||
case endpoint.RecordTypeA:
|
||||
aTargets = append(aTargets, t)
|
||||
default:
|
||||
cnameTargets = append(cnameTargets, t)
|
||||
}
|
||||
}
|
||||
|
||||
if len(aTargets) > 0 {
|
||||
epA := &endpoint.Endpoint{
|
||||
DNSName: strings.TrimSuffix(hostname, "."),
|
||||
Targets: aTargets,
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
Labels: endpoint.NewLabels(),
|
||||
}
|
||||
endpoints = append(endpoints, epA)
|
||||
}
|
||||
|
||||
if len(cnameTargets) > 0 {
|
||||
epCNAME := &endpoint.Endpoint{
|
||||
DNSName: strings.TrimSuffix(hostname, "."),
|
||||
Targets: cnameTargets,
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeCNAME,
|
||||
Labels: endpoint.NewLabels(),
|
||||
}
|
||||
endpoints = append(endpoints, epCNAME)
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
||||
func targetsFromIngressStatus(status v1beta1.IngressStatus) endpoint.Targets {
|
||||
var targets endpoint.Targets
|
||||
|
||||
|
@ -74,6 +74,24 @@ func getHostnamesFromAnnotations(annotations map[string]string) []string {
|
||||
return strings.Split(strings.Replace(hostnameAnnotation, " ", "", -1), ",")
|
||||
}
|
||||
|
||||
// getTargetsFromTargetAnnotation gets endpoints from optional "target" annotation.
|
||||
// Returns empty endpoints array if none are found.
|
||||
func getTargetsFromTargetAnnotation(annotations map[string]string) endpoint.Targets {
|
||||
var targets endpoint.Targets
|
||||
|
||||
// Get the desired hostname of the ingress from the annotation.
|
||||
targetAnnotation, exists := annotations[targetAnnotationKey]
|
||||
if exists && targetAnnotation != "" {
|
||||
// splits the hostname annotation and removes the trailing periods
|
||||
targetsList := strings.Split(strings.Replace(targetAnnotation, " ", "", -1), ",")
|
||||
for _, targetHostname := range targetsList {
|
||||
targetHostname = strings.TrimSuffix(targetHostname, ".")
|
||||
targets = append(targets, targetHostname)
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
// suitableType returns the DNS resource record type suitable for the target.
|
||||
// In this case type A for IPs and type CNAME for everything else.
|
||||
func suitableType(target string) string {
|
||||
@ -82,3 +100,44 @@ func suitableType(target string) string {
|
||||
}
|
||||
return endpoint.RecordTypeCNAME
|
||||
}
|
||||
|
||||
// endpointsForHostname returns the endpoint objects for each host-target combination.
|
||||
func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoint.TTL) []*endpoint.Endpoint {
|
||||
var endpoints []*endpoint.Endpoint
|
||||
|
||||
var aTargets endpoint.Targets
|
||||
var cnameTargets endpoint.Targets
|
||||
|
||||
for _, t := range targets {
|
||||
switch suitableType(t) {
|
||||
case endpoint.RecordTypeA:
|
||||
aTargets = append(aTargets, t)
|
||||
default:
|
||||
cnameTargets = append(cnameTargets, t)
|
||||
}
|
||||
}
|
||||
|
||||
if len(aTargets) > 0 {
|
||||
epA := &endpoint.Endpoint{
|
||||
DNSName: strings.TrimSuffix(hostname, "."),
|
||||
Targets: aTargets,
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
Labels: endpoint.NewLabels(),
|
||||
}
|
||||
endpoints = append(endpoints, epA)
|
||||
}
|
||||
|
||||
if len(cnameTargets) > 0 {
|
||||
epCNAME := &endpoint.Endpoint{
|
||||
DNSName: strings.TrimSuffix(hostname, "."),
|
||||
Targets: cnameTargets,
|
||||
RecordTTL: ttl,
|
||||
RecordType: endpoint.RecordTypeCNAME,
|
||||
Labels: endpoint.NewLabels(),
|
||||
}
|
||||
endpoints = append(endpoints, epCNAME)
|
||||
}
|
||||
|
||||
return endpoints
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import (
|
||||
|
||||
"github.com/linki/instrumented_http"
|
||||
log "github.com/sirupsen/logrus"
|
||||
istiocrd "istio.io/istio/pilot/pkg/config/kube/crd"
|
||||
istiomodel "istio.io/istio/pilot/pkg/model"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
@ -49,11 +51,13 @@ type Config struct {
|
||||
KubeConfig string
|
||||
KubeMaster string
|
||||
ServiceTypeFilter []string
|
||||
IstioIngressGateway string
|
||||
}
|
||||
|
||||
// ClientGenerator provides clients
|
||||
type ClientGenerator interface {
|
||||
KubeClient() (kubernetes.Interface, error)
|
||||
IstioClient() (istiomodel.ConfigStore, error)
|
||||
}
|
||||
|
||||
// SingletonClientGenerator stores provider clients and guarantees that only one instance of client
|
||||
@ -62,17 +66,28 @@ type SingletonClientGenerator struct {
|
||||
KubeConfig string
|
||||
KubeMaster string
|
||||
RequestTimeout time.Duration
|
||||
client kubernetes.Interface
|
||||
sync.Once
|
||||
kubeClient kubernetes.Interface
|
||||
istioClient istiomodel.ConfigStore
|
||||
kubeOnce sync.Once
|
||||
istioOnce sync.Once
|
||||
}
|
||||
|
||||
// KubeClient generates a kube client if it was not created before
|
||||
func (p *SingletonClientGenerator) KubeClient() (kubernetes.Interface, error) {
|
||||
var err error
|
||||
p.Once.Do(func() {
|
||||
p.client, err = NewKubeClient(p.KubeConfig, p.KubeMaster, p.RequestTimeout)
|
||||
p.kubeOnce.Do(func() {
|
||||
p.kubeClient, err = NewKubeClient(p.KubeConfig, p.KubeMaster, p.RequestTimeout)
|
||||
})
|
||||
return p.client, err
|
||||
return p.kubeClient, err
|
||||
}
|
||||
|
||||
// IstioClient generates an istio client if it was not created before
|
||||
func (p *SingletonClientGenerator) IstioClient() (istiomodel.ConfigStore, error) {
|
||||
var err error
|
||||
p.istioOnce.Do(func() {
|
||||
p.istioClient, err = NewIstioClient(p.KubeConfig)
|
||||
})
|
||||
return p.istioClient, err
|
||||
}
|
||||
|
||||
// ByNames returns multiple Sources given multiple names.
|
||||
@ -104,6 +119,16 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
|
||||
return nil, err
|
||||
}
|
||||
return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation)
|
||||
case "istio-gateway":
|
||||
kubernetesClient, err := p.KubeClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
istioClient, err := p.IstioClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewIstioGatewaySource(kubernetesClient, istioClient, cfg.IstioIngressGateway, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation)
|
||||
case "fake":
|
||||
return NewFakeSource(cfg.FQDNTemplate)
|
||||
case "connector":
|
||||
@ -153,7 +178,37 @@ func NewKubeClient(kubeConfig, kubeMaster string, requestTimeout time.Duration)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Infof("Connected to cluster at %s", config.Host)
|
||||
log.Infof("Created Kubernetes client %s", config.Host)
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NewIstioClient returns a new Istio client object. It uses the configured
|
||||
// KubeConfig attribute to connect to the cluster. If KubeConfig isn't provided
|
||||
// it defaults to using the recommended default.
|
||||
// NB: Istio controls the creation of the underlying Kubernetes client, so we
|
||||
// have no ability to tack on transport wrappers (e.g., Prometheus request
|
||||
// wrappers) to the client's config at this level. Furthermore, the Istio client
|
||||
// constructor does not expose the ability to override the Kubernetes master,
|
||||
// so the Master config attribute has no effect.
|
||||
func NewIstioClient(kubeConfig string) (*istiocrd.Client, error) {
|
||||
if kubeConfig == "" {
|
||||
if _, err := os.Stat(clientcmd.RecommendedHomeFile); err == nil {
|
||||
kubeConfig = clientcmd.RecommendedHomeFile
|
||||
}
|
||||
}
|
||||
|
||||
client, err := istiocrd.NewClient(
|
||||
kubeConfig,
|
||||
"",
|
||||
istiomodel.ConfigDescriptor{istiomodel.Gateway},
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Info("Created Istio client")
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
istiomodel "istio.io/istio/pilot/pkg/model"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
@ -29,14 +30,24 @@ import (
|
||||
|
||||
type MockClientGenerator struct {
|
||||
mock.Mock
|
||||
client kubernetes.Interface
|
||||
kubeClient kubernetes.Interface
|
||||
istioClient istiomodel.ConfigStore
|
||||
}
|
||||
|
||||
func (m *MockClientGenerator) KubeClient() (kubernetes.Interface, error) {
|
||||
args := m.Called()
|
||||
if args.Error(1) == nil {
|
||||
m.client = args.Get(0).(kubernetes.Interface)
|
||||
return m.client, nil
|
||||
m.kubeClient = args.Get(0).(kubernetes.Interface)
|
||||
return m.kubeClient, nil
|
||||
}
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockClientGenerator) IstioClient() (istiomodel.ConfigStore, error) {
|
||||
args := m.Called()
|
||||
if args.Error(1) == nil {
|
||||
m.istioClient = args.Get(0).(istiomodel.ConfigStore)
|
||||
return m.istioClient, nil
|
||||
}
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
@ -48,28 +59,29 @@ type ByNamesTestSuite struct {
|
||||
func (suite *ByNamesTestSuite) TestAllInitialized() {
|
||||
mockClientGenerator := new(MockClientGenerator)
|
||||
mockClientGenerator.On("KubeClient").Return(fake.NewSimpleClientset(), nil)
|
||||
mockClientGenerator.On("IstioClient").Return(NewFakeConfigStore(), nil)
|
||||
|
||||
sources, err := ByNames(mockClientGenerator, []string{"service", "ingress", "fake"}, &Config{})
|
||||
sources, err := ByNames(mockClientGenerator, []string{"service", "ingress", "istio-gateway", "fake"}, minimalConfig)
|
||||
suite.NoError(err, "should not generate errors")
|
||||
suite.Len(sources, 3, "should generate all three sources")
|
||||
suite.Len(sources, 4, "should generate all four sources")
|
||||
}
|
||||
|
||||
func (suite *ByNamesTestSuite) TestOnlyFake() {
|
||||
mockClientGenerator := new(MockClientGenerator)
|
||||
mockClientGenerator.On("KubeClient").Return(fake.NewSimpleClientset(), nil)
|
||||
|
||||
sources, err := ByNames(mockClientGenerator, []string{"fake"}, &Config{})
|
||||
sources, err := ByNames(mockClientGenerator, []string{"fake"}, minimalConfig)
|
||||
suite.NoError(err, "should not generate errors")
|
||||
suite.Len(sources, 1, "should generate all three sources")
|
||||
suite.Nil(mockClientGenerator.client, "client should not be created")
|
||||
suite.Len(sources, 1, "should generate fake source")
|
||||
suite.Nil(mockClientGenerator.kubeClient, "client should not be created")
|
||||
}
|
||||
|
||||
func (suite *ByNamesTestSuite) TestSourceNotFound() {
|
||||
mockClientGenerator := new(MockClientGenerator)
|
||||
mockClientGenerator.On("KubeClient").Return(fake.NewSimpleClientset(), nil)
|
||||
|
||||
sources, err := ByNames(mockClientGenerator, []string{"foo"}, &Config{})
|
||||
suite.Equal(err, ErrSourceNotFound, "should return sourcen not found")
|
||||
sources, err := ByNames(mockClientGenerator, []string{"foo"}, minimalConfig)
|
||||
suite.Equal(err, ErrSourceNotFound, "should return source not found")
|
||||
suite.Len(sources, 0, "should not returns any source")
|
||||
}
|
||||
|
||||
@ -77,13 +89,29 @@ func (suite *ByNamesTestSuite) TestKubeClientFails() {
|
||||
mockClientGenerator := new(MockClientGenerator)
|
||||
mockClientGenerator.On("KubeClient").Return(nil, errors.New("foo"))
|
||||
|
||||
_, err := ByNames(mockClientGenerator, []string{"service"}, &Config{})
|
||||
suite.Error(err, "should return an error if client cannot be created")
|
||||
_, err := ByNames(mockClientGenerator, []string{"service"}, minimalConfig)
|
||||
suite.Error(err, "should return an error if kubernetes client cannot be created")
|
||||
|
||||
_, err = ByNames(mockClientGenerator, []string{"ingress"}, &Config{})
|
||||
suite.Error(err, "should return an error if client cannot be created")
|
||||
_, err = ByNames(mockClientGenerator, []string{"ingress"}, minimalConfig)
|
||||
suite.Error(err, "should return an error if kubernetes client cannot be created")
|
||||
|
||||
_, err = ByNames(mockClientGenerator, []string{"istio-gateway"}, minimalConfig)
|
||||
suite.Error(err, "should return an error if kubernetes client cannot be created")
|
||||
}
|
||||
|
||||
func (suite *ByNamesTestSuite) TestIstioClientFails() {
|
||||
mockClientGenerator := new(MockClientGenerator)
|
||||
mockClientGenerator.On("KubeClient").Return(fake.NewSimpleClientset(), nil)
|
||||
mockClientGenerator.On("IstioClient").Return(nil, errors.New("foo"))
|
||||
|
||||
_, err := ByNames(mockClientGenerator, []string{"istio-gateway"}, minimalConfig)
|
||||
suite.Error(err, "should return an error if istio client cannot be created")
|
||||
}
|
||||
|
||||
func TestByNames(t *testing.T) {
|
||||
suite.Run(t, new(ByNamesTestSuite))
|
||||
}
|
||||
|
||||
var minimalConfig = &Config{
|
||||
IstioIngressGateway: "istio-system/istio-ingressgateway",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user