AnalogJ / lexicon

Manipulate DNS records on various DNS providers in a standardized way.
MIT License
1.47k stars 302 forks source link

Determine provider automatically from the domain #477

Open dmeranda opened 4 years ago

dmeranda commented 4 years ago

It would be useful if the provider plugin to use could be determined automatically based upon the domain; and also allow per-domain configuration options as well as per-provider options.

One idea is to have a new builtin "auto" provider which would look for a per-domain configuration file. So for the domain "example.com" it might look for a config file named "lexicon_domain_example.com.yml" in the config directory. Then that config file would need to include a "provider" key/value, as well as any other options.

This would also help solve another problem where you might have two distinct provider API authorization credentials for different domains. So if say you had both domains "example.com" and "example.org" hosted by the same DNS provider, but each was registered with a different account or API credentials.

This would allow you to run: $ lexicon auto example.com create ...

And then you would create a config file "lexicon_domain_example.com.yml" with:


provider: godaddy
auth-key: 1234567....
auth-secret: abcdefg...```
adferrand commented 4 years ago

Hello @dmeranda!

In fact, we implemented almost what your are proposing in a provider that is named auto ^^

The difference is that this provider choose the actual provider based on the known nameservers of the domain zone, so in theory you do not even need to explicitly associate the domain to the provider. You just pass the various credentials in the global lexicon yml config (or through cli flags that the auto exposes for all providers in lexicon), and you are good to go.

For pathologic cases, there is a dedicated flag/config parameter to explicit set some mappings between a domain and a provider.

dmeranda commented 4 years ago

@adferrand Thanks, the auto provider wasn't documented, but that does appear to solve many of the same use cases. There are some problems though:

• I'm not sure all the DNS servers for all providers are correct. For example GoDaddy often (always?) uses nameservers that are under the *.domaincontrol.com namespace, like "ns01.domaincontrol.com", not godaddy.,com. So at least for that provider the NAMESERVER_DOMAINS needs to be updated!

• This doesn't solve the potential problem where you want to provide different API auth credentials on a per-domain basis rather than a per-provider basis. I don't have an immediate need for that, but I could see that some users might.

dmeranda commented 4 years ago

Also, the auto provider doesn't support help (at least as of version 3.3.14):

$ lexicon auto --help
Traceback (most recent call last):
  File "/usr/local/bin/lexicon", line 8, in <module>
    sys.exit(main())
...
AssertionError
davidhrbac commented 4 years ago

Lexicon auto provider does not work for me too.

$ lexicon auto --auth-username=****** --auth-password=****** --output=JSON list ******.cz TXT

usage: lexicon [-h] [--version] [--delegated DELEGATED]
               [--config-dir CONFIG_DIR]
               {powerdns,cloudxns,sakuracloud,memset,dnspark,zonomi,namecheap,hover,hetzner,zilore,dnspod,vultr,gehirn,dnsimple,ovh,nfsn,henet,route53,linode,exoscale,plesk,googleclouddns,transip,dinahosting,cloudns,cloudflare,euserv,localzone,glesys,rackspace,rcodezero,nsone,infoblox,auto,aurora,online,conoha,onapp,easyname,gransy,namesilo,godaddy,subreg,aliyun,rage4,inwx,gandi,directadmin,easydns,luadns,hostingde,internetbs,softlayer,zeit,pointhq,safedns,dnsmadeeasy,netcup,constellix,linode4,digitalocean,azure,gratisdns,dreamhost,yandex}
               ...
lexicon: error: unrecognized arguments: --auth-username=****** --auth-password=******
$ lexicon auto  --output=JSON list ******.cz TXT

Traceback (most recent call last):
  File "/tmp/lexis/venv/bin/lexicon", line 8, in <module>
    sys.exit(main())
  File "/tmp/lexis/venv/local/lib/python2.7/site-packages/lexicon/cli.py", line 117, in main
    results = client.execute()
  File "/tmp/lexis/venv/local/lib/python2.7/site-packages/lexicon/client.py", line 77, in execute
    self.provider.authenticate()
  File "/tmp/lexis/venv/local/lib/python2.7/site-packages/lexicon/providers/auto.py", line 207, in authenticate
    self.proxy_provider.authenticate()
  File "/tmp/lexis/venv/local/lib/python2.7/site-packages/lexicon/providers/base.py", line 69, in authenticate
    return self._authenticate()
  File "/tmp/lexis/venv/local/lib/python2.7/site-packages/lexicon/providers/gransy.py", line 53, in _authenticate
    'No valid authentication data passed, expected: auth-username and auth-password')
Exception: No valid authentication data passed, expected: auth-username and auth-password