How Do I Test A New External DNS Provider

I’m in the process of writing an external-dns provider for DNSMadeEasy but I have no idea on how to go about testing it. I’ve puled the rancher/external-dns got repository, forked it and adding in my code. What is the next step?

Bumping this as I would really like an answer. We want to use Rancher as a production environment and this is the final hurdle the we need to overcome before this can happen.

Build and publish somewhere:

docker build -t qtzar/external-dns:latest .
docker push qtzar/external-dns:latest

Then deploy a service using it:

Image: qtzar/external-dns:latest
Entrypoint: /usr/bin/external-dns
Command: -provider=yourprovider
Environment vars:
  NAME_TEMPLATE=%{{service_name}}.%{{stack_name}}.%{{environment_name}}
  ROOT_DOMAIN=somedomain.com
  TTL=120
  YOURPROVIDER_OPTION=value
  YOURPROVIDER_OTHEROPTION=optionvalue

The Dockerfile doesn’t seem to do anything. it copies scripts/bootstrap and then runs it.

Nowhere in the dockerfile does it copy any code over to the container image.

What am I missing ?

I had this same problem when I wrote the DigitalOcean provider. This code is a little less well documented than I personally would prefer, but once I got my mind around the architecture everything went well.

Here is how I got around that problem:

#!/bin/bash
./scripts/build
cd bin/
tar cf ../packaging/external-dns.tar external-dns
gzip -f9 ../packaging/external-dns.tar
docker build -t registry.twilley.org/mathuin/external-dns ../packaging
docker push registry.twilley.org/mathuin/external-dns

This script basically builds the binary then archives it in a place where the packaging Dockerfile can access it, then it builds an image based on that Dockerfile and pushes it to my private registry where I can run tests against the image.

I also modified the packaging/Dockerfile to look like this:

FROM alpine:3.2
MAINTAINER Rancher Labs, Inc.
RUN apk add --update ca-certificates 

ENV EXT_DNS_RELEASE v0.6.1
#ADD https://github.com/rancher/external-dns/releases/download/${EXT_DNS_RELEASE}/external-dns.tar.gz /external-dns.tar.gz
COPY external-dns.tar.gz /external-dns.tar.gz
RUN tar -zxvf /external-dns.tar.gz -C /usr/bin

ENTRYPOINT ["/usr/bin/external-dns"]

This change uses the archived binary mentioned above instead of downloading straight from Rancher’s releases.

Let me know if there’s something I can do to help!

Thanks, I had just noticed the Dockerfile in the packaging directory and was trying to figure out how to adjust it. I was going to pull a tar.gz file from my github fork of the code but your method seems a lot easier.

Now that I have a build I’m getting a weird error of ‘exec: “-provider=dnsme”: executable file not found in $PATH’ so back to the drawing board. My guess is the entry=point is not registering correctly.

I forgot the entrypoint above, updated…

Here’s my docker-compose.yml file:

version: '2'

services:
    external-dns:
        image: registry.twilley.org/mathuin/external-dns
        command: -provider digitalocean
        labels:
            io.rancher.container.agent.role: environment
            io.rancher.container.create_agent: 'true'
            io.rancher.container.pull_image: always
        environment:
            - DO_PAT=secret
            - ROOT_DOMAIN=example.org

apparently building Go binaries on a Mac and then trying to run them in linux does not work very well. I’ll throw in an update once I have a linux box ready to test building with.

As you can tell this isn’t really developed on macOS much… but you don’t actually need a Linux machine, Go can cross-compile: GOOS=linux GOARCH=amd64 go build ...

Many thanks for the help with this so far.

I’ve now been able to build a working prototype and deploy it to my Rancher environment. It is not working 100% yet but I have been able to get Rancher to create record in my DNSMadeEasy domain.

Now I just need to iron out the kinks and test all scenarios.

What does a correct external-dns-adminproject TXT record look like when you have multiple containers running?

I have gotten to the stage where if I start one container it will correctly create the A record and TXT record and if I stop that container it will remove the A and TXT records as expected.

If, however, I start a second container I am currently ending up with 2 A records ( as expected ) but just one TXT record that only lists a single A record in the value part. Looking at the logs it looks like I run two updates on the TXT record, one to set the value as the first container and then another that overwrites that value with the second container. My guess that this is somehow incorrect.

I think i figured it out. I am now deleting the old TXT record(s) and then recreating them when there is an update so that there are multiple TXT records for external-dns-adminproject and in my get records block I create a single record for that combining all the record values as an array.

So looks like I have addition, deletion, updating and getting of records all working perfectly against DNSMadeEasy. Now I just need to optimize it, add in a rate limiter and then do some additional testing.

Do I need to sign a CCLA to allow it to be pulled in to Rancher?

We do not require CLAs.