mgruener suggested that the --events flag could be wired to control whether or
not the CRD source created and started its informer. This commit makes that
change; good idea!
If e.g the ambassador service annotation points to an nonexisting service, external-dns will not update any DNS records. This PR makes external-dns ignore the host and carry on instead.
If external-dns.alpha.kubernetes.io/target annotation is present on a
pod, it's value will be used as the target for the headless service.
If annotation external-dns.alpha.kubernetes.io/access=public is present,
NodeExternalIP of the node running the pod is used as the target for the
headless service.
This change disables the CRD source's informer during tests. I made the mistake
of not running `make test` before the previous commit, and thus didn't realize
that leaving the informer enabled during the tests introduced a race condition:
WARNING: DATA RACE
Write at 0x00c0005aa130 by goroutine 59:
k8s.io/client-go/rest/fake.(*RESTClient).do()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/fake/fake.go:113 +0x69
k8s.io/client-go/rest/fake.(*RESTClient).do-fm()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/fake/fake.go:109 +0x64
k8s.io/client-go/rest/fake.roundTripperFunc.RoundTrip()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/fake/fake.go:43 +0x3d
net/http.send()
/usr/local/go/src/net/http/client.go:251 +0x6da
net/http.(*Client).send()
/usr/local/go/src/net/http/client.go:175 +0x1d5
net/http.(*Client).do()
/usr/local/go/src/net/http/client.go:717 +0x2cb
net/http.(*Client).Do()
/usr/local/go/src/net/http/client.go:585 +0x68b
k8s.io/client-go/rest.(*Request).request()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/request.go:855 +0x209
k8s.io/client-go/rest.(*Request).Do()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/request.go:928 +0xf0
sigs.k8s.io/external-dns/source.(*crdSource).List()
/Users/erath/go/src/github.com/ericrrath/external-dns/source/crd.go:250 +0x28c
sigs.k8s.io/external-dns/source.NewCRDSource.func1()
/Users/erath/go/src/github.com/ericrrath/external-dns/source/crd.go:125 +0x10a
k8s.io/client-go/tools/cache.(*ListWatch).List()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/listwatch.go:106 +0x94
k8s.io/client-go/tools/cache.(*Reflector).ListAndWatch.func1.1.2()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:233 +0xf4
k8s.io/client-go/tools/pager.SimplePageFunc.func1()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/pager/pager.go:40 +0x94
k8s.io/client-go/tools/pager.(*ListPager).List()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/pager/pager.go:91 +0x1f4
k8s.io/client-go/tools/cache.(*Reflector).ListAndWatch.func1.1()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:258 +0x2b7
Previous write at 0x00c0005aa130 by goroutine 37:
k8s.io/client-go/rest/fake.(*RESTClient).do()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/fake/fake.go:113 +0x69
k8s.io/client-go/rest/fake.(*RESTClient).do-fm()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/fake/fake.go:109 +0x64
k8s.io/client-go/rest/fake.roundTripperFunc.RoundTrip()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/fake/fake.go:43 +0x3d
net/http.send()
/usr/local/go/src/net/http/client.go:251 +0x6da
net/http.(*Client).send()
/usr/local/go/src/net/http/client.go:175 +0x1d5
net/http.(*Client).do()
/usr/local/go/src/net/http/client.go:717 +0x2cb
net/http.(*Client).Do()
/usr/local/go/src/net/http/client.go:585 +0x68b
k8s.io/client-go/rest.(*Request).request()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/request.go:855 +0x209
k8s.io/client-go/rest.(*Request).Do()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/rest/request.go:928 +0xf0
sigs.k8s.io/external-dns/source.(*crdSource).List()
/Users/erath/go/src/github.com/ericrrath/external-dns/source/crd.go:250 +0x28c
sigs.k8s.io/external-dns/source.(*crdSource).Endpoints()
/Users/erath/go/src/github.com/ericrrath/external-dns/source/crd.go:171 +0x13c4
sigs.k8s.io/external-dns/source.testCRDSourceEndpoints.func1()
/Users/erath/go/src/github.com/ericrrath/external-dns/source/crd_test.go:388 +0x4f6
testing.tRunner()
/usr/local/go/src/testing/testing.go:1193 +0x202
Goroutine 59 (running) created at:
k8s.io/client-go/tools/cache.(*Reflector).ListAndWatch.func1()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:224 +0x36f
k8s.io/client-go/tools/cache.(*Reflector).ListAndWatch()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:316 +0x1ab
k8s.io/client-go/tools/cache.(*Reflector).Run.func1()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:177 +0x4a
k8s.io/apimachinery/pkg/util/wait.BackoffUntil.func1()
/Users/erath/go/pkg/mod/k8s.io/apimachinery@v0.18.8/pkg/util/wait/wait.go:155 +0x75
k8s.io/apimachinery/pkg/util/wait.BackoffUntil()
/Users/erath/go/pkg/mod/k8s.io/apimachinery@v0.18.8/pkg/util/wait/wait.go:156 +0xba
k8s.io/client-go/tools/cache.(*Reflector).Run()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:176 +0xee
k8s.io/client-go/tools/cache.(*Reflector).Run-fm()
/Users/erath/go/pkg/mod/k8s.io/client-go@v0.18.8/tools/cache/reflector.go:174 +0x54
k8s.io/apimachinery/pkg/util/wait.(*Group).StartWithChannel.func1()
/Users/erath/go/pkg/mod/k8s.io/apimachinery@v0.18.8/pkg/util/wait/wait.go:56 +0x45
k8s.io/apimachinery/pkg/util/wait.(*Group).Start.func1()
/Users/erath/go/pkg/mod/k8s.io/apimachinery@v0.18.8/pkg/util/wait/wait.go:73 +0x6d
Goroutine 37 (running) created at:
testing.(*T).Run()
/usr/local/go/src/testing/testing.go:1238 +0x5d7
sigs.k8s.io/external-dns/source.testCRDSourceEndpoints()
/Users/erath/go/src/github.com/ericrrath/external-dns/source/crd_test.go:376 +0x1fcf
testing.tRunner()
/usr/local/go/src/testing/testing.go:1193 +0x202
It looks like client-go's fake.RESTClient (used by crd_test.go) is known to
cause race conditions when used with informers:
<https://github.com/kubernetes/kubernetes/issues/95372>. None of the CRD tests
_depend_ on the informer yet, so disabling the informer at least allows the
existing tests to pass without race conditions. I'll look into further changes
that 1) test the new event-handler behavior, and 2) allow all tests to pass
without race conditions.
When the --events flag is passed at startup, Source.AddEventHandler() is called
on each configured source. Most sources provide AddEventHandler()
implementations that invoke the reconciliation loop when the configured source
changes, but the CRD source had a no-op implementation. I.e. when a custom
resource was created, updated, or deleted, external-dns remained unware, and the
reconciliation loop would not fire until the configured interval had passed.
This change adds an informer (on the CRD specified by --crd-source-apiversion
and --crd-source-kind=DNSEndpoint), and a Source.AddEventHandler()
implementation that calls Informer.AddEventHandler(). Now when a custom
resource is created, updated, or deleted, the reconciliation loop is invoked.
This feature adds a router field to the OCP Route Source so that a user can add an ingress controller name in flag --ocp-router-name which will be used to pick up the respective routerCanonicalHostname from Route's Status Ingress Object.
Signed-off-by: Miheer Salunke <miheer.salunke@gmail.com>
Currently the `--label-filter` flag can only be used to filter CRDs
which match the label selector passed through that flag. This change
extends the functionality to the Ingress, Service and Openshift Route
type objects. When the flag is not specified the default value is
`labels.Everything()` which is an empty string, the same as before.
Annotation based filter is inefficient because the filtering has to be
done in the controller instead of the API server like with label
filtering.
we don't want to get incompatible restrictions by letting someone set
"--ingress-class" and --annotation-filter="kubernetes.io/ingress.class"
at the same time
source/ocproute_test.go:
New file for source/ocproute.go unit tests.
Inspired by the service source unit tests,
this commit adds basic unit tests to verify
basic functionality of the OCP route source.
Signed-off-by: Stephen Greene <sgreene@redhat.com>
source/ocproute.go:
Add/clean up godocs and general in-line comments.
Change `routeapi` named import to `routev1`.
Update `routev1` calling sites accordingly.
Signed-off-by: Stephen Greene <sgreene@redhat.com>
Ambassador can be configured with `Host` resources (based on the
`Host` CRD) for defining the external DNS host name.
This code adds a new source, `ambassador-host`, that looks for the
`ambassador/ambassador` Service and and uses the `hostname` from the
`Host` resource.
Signed-off-by: Alvaro Saurin <alvaro.saurin@gmail.com>
Signed-off-by: Flynn <flynn@datawire.io>
* adds tests for shouldUpdateProviderSpecific
Signed-off-by: Raffaele Di Fazio <difazio.raffaele@gmail.com>
* move AWS health to where it belongs
Signed-off-by: Raffaele Di Fazio <difazio.raffaele@gmail.com>
* add test that breaks things
Signed-off-by: Raffaele Di Fazio <difazio.raffaele@gmail.com>
* adds adjustendpoints method
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* fix controller
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* actually pass the provider where needed
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* OMG goland do your go fmt thing
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* use registry as proxy
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* make linter happy
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* change AdjustEndpoints signature
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* fix typo
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* actually use adjusted endpoints
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* revert cloudflare change
Signed-off-by: Raffaele Di Fazio <raffo@github.com>
* Update provider/cloudflare/cloudflare.go
Co-authored-by: Nick Jüttner <nick@juni.io>
Co-authored-by: Nick Jüttner <nick@juni.io>
Currently, the endpoints of headless services are retrieved
by querying pods using the pod selector of the service.
Instead, we now query for an Endpoints resource with the
same name as the Service object to get the endpoints for the
service. This is needed in order to support the
spec.publishNotReadyPods attribute of a service.
One feature that's supported for the Istio Gateway resource is the
ability to restrict what namespace may provide a VirtualService for
a given hostname/domain by specifying it in the form
`my-namespace/my-domain.com` which restricts the availability of
`my-domain.com` to the `my-namespace` namespace.
When creating the associated DNS records, the namespace should not
be included.
In its current state, ttlMaximum causes make to fail build with error:
source/source.go:71:39: constant 4294967295 overflows int
Because math.MaxUint32 is an untyped integer constant it is converted
to type int when used as an interface param, type int is signed,
MaxUint32 is larger than MaxInt32 and causes the type int to overflow.
Converting ttlMaximum to MaxInt32 stops this overflow.
Added warning when CR has a target with a "." in the end, which would make external-dns contantly add and remove the record
Signed-off-by: João Marçal <joao.marcal12@gmail.com>