You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

142 lines
7.4 KiB

Writing a Custom Source
=======================
Introduction
------------
Creating a custom source of record data for octoDNS is pretty simple and
involves a bit of boilerplate and then filling in a single method,
:py:meth:`octodns.source.base.BaseSource.populate`, with any logic required
to fetch or create the desired records. In this example records will be created
for the first 25 elements of the `Fibonacci Sequence`_. While contrived it
should illustrate the process and requirements.
.. _Fibonacci Sequence: https://en.wikipedia.org/wiki/Fibonacci_sequence
Some relevant documentation for this example is in comments in the YAML
configuration files and python code.
* :download:`config/octodns.yaml`
* :download:`config/dns.math.yaml`
* :download:`fibonacci.py`
From here on this README focuses on the custom source and the process of
running octoDNS with access to it.
Checking out the code and setting up the environment
----------------------------------------------------
You would not normally need to check out octoDNS itself, you instead would have
a git repo with only your configuration files. Here we're cloning the repo only
to get a copy of the example files::
$ git clone https://github.com/octodns/octodns.git
$ cd octodns/examples/basic/
$ python3 -mvenv env
$ source ../env.sh
$ source env/bin/activate
(env) $ pip install -r requirements.txt
Finally check out :ref:`running-powerdns` to get a local instance of PowerDNS
up and going before continuing.
Running octoDNS sync
--------------------
Once you have your custom source, configuration files, and octoDNS installed
you're ready to run the sync command to get it to plan an initial set of
changes. The main difference here compared to the :ref:`basic-setup` is setting
``PYTHONPATH`` so the source file can be located::
(env) $ export PYTHONPATH=.
(env) $ octodns-sync --config-file config/octodns.yaml
2025-08-17T17:14:58 [140224800168896] INFO Manager __init__: config_file=config/octodns.yaml, (octoDNS 1.13.0)
2025-08-17T17:14:58 [140224800168896] INFO Manager _config_executor: max_workers=1
2025-08-17T17:14:58 [140224800168896] INFO Manager _config_include_meta: include_meta=False
2025-08-17T17:14:58 [140224800168896] INFO Manager _config_enable_checksum: enable_checksum=False
2025-08-17T17:14:58 [140224800168896] INFO Manager _config_auto_arpa: auto_arpa=False
2025-08-17T17:14:58 [140224800168896] INFO Manager __init__: global_processors=[]
2025-08-17T17:14:58 [140224800168896] INFO Manager __init__: global_post_processors=[]
2025-08-17T17:14:58 [140224800168896] INFO Manager __init__: provider=config (octodns.provider.yaml 1.13.0)
2025-08-17T17:14:58 [140224800168896] INFO Manager __init__: provider=powerdns (octodns_powerdns 1.0.0)
2025-08-17T17:14:58 [140224800168896] INFO Manager __init__: provider=fibonacci (fibonacci n/a)
2025-08-17T17:14:58 [140224800168896] INFO Manager sync: eligible_zones=[], eligible_targets=[], dry_run=True, force=False, plan_output_fh=<stdout>, checksum=None
2025-08-17T17:14:58 [140224800168896] INFO Manager sync: zone=dns.math.
2025-08-17T17:14:58 [140224800168896] INFO Manager sync: sources=['config', 'fibonacci']
2025-08-17T17:14:58 [140224800168896] INFO Manager sync: processors=[]
2025-08-17T17:14:58 [140224800168896] INFO Manager sync: targets=['powerdns']
2025-08-17T17:14:58 [140224800168896] INFO YamlProvider[config] populate: found 1 records, exists=True
2025-08-17T17:14:58 [140224800168896] INFO FibonacciProvider[fibonacci] populate: found 25 records, exists=False
2025-08-17T17:14:58 [140224800168896] INFO PowerDnsProvider[powerdns] plan: desired=dns.math.
2025-08-17T17:14:58 [140224800168896] INFO PowerDnsProvider[powerdns] populate: found 1 records, exists=True
2025-08-17T17:14:58 [140224800168896] WARNING PowerDnsProvider[powerdns] root NS record supported, but no record is configured for dns.math.
2025-08-17T17:14:58 [140224800168896] INFO PowerDnsProvider[powerdns] plan: Creates=25, Updates=0, Deletes=0, Existing=1, Meta=False
2025-08-17T17:14:58 [140224800168896] INFO Plan
********************************************************************************
* dns.math.
********************************************************************************
* powerdns (PowerDnsProvider)
* Create <TxtRecord TXT 3600, fibonacci-0.dns.math., ['0']> ()
* Create <TxtRecord TXT 3600, fibonacci-1.dns.math., ['1']> ()
* Create <TxtRecord TXT 3600, fibonacci-10.dns.math., ['55']> ()
* Create <TxtRecord TXT 3600, fibonacci-11.dns.math., ['89']> ()
* Create <TxtRecord TXT 3600, fibonacci-12.dns.math., ['144']> ()
* Create <TxtRecord TXT 3600, fibonacci-13.dns.math., ['233']> ()
* Create <TxtRecord TXT 3600, fibonacci-14.dns.math., ['377']> ()
* Create <TxtRecord TXT 3600, fibonacci-15.dns.math., ['610']> ()
* Create <TxtRecord TXT 3600, fibonacci-16.dns.math., ['987']> ()
* Create <TxtRecord TXT 3600, fibonacci-17.dns.math., ['1597']> ()
* Create <TxtRecord TXT 3600, fibonacci-18.dns.math., ['2584']> ()
* Create <TxtRecord TXT 3600, fibonacci-19.dns.math., ['4181']> ()
* Create <TxtRecord TXT 3600, fibonacci-2.dns.math., ['1']> ()
* Create <TxtRecord TXT 3600, fibonacci-20.dns.math., ['6765']> ()
* Create <TxtRecord TXT 3600, fibonacci-21.dns.math., ['10946']> ()
* Create <TxtRecord TXT 3600, fibonacci-22.dns.math., ['17711']> ()
* Create <TxtRecord TXT 3600, fibonacci-23.dns.math., ['28657']> ()
* Create <TxtRecord TXT 3600, fibonacci-24.dns.math., ['46368']> ()
* Create <TxtRecord TXT 3600, fibonacci-3.dns.math., ['2']> ()
* Create <TxtRecord TXT 3600, fibonacci-4.dns.math., ['3']> ()
* Create <TxtRecord TXT 3600, fibonacci-5.dns.math., ['5']> ()
* Create <TxtRecord TXT 3600, fibonacci-6.dns.math., ['8']> ()
* Create <TxtRecord TXT 3600, fibonacci-7.dns.math., ['13']> ()
* Create <TxtRecord TXT 3600, fibonacci-8.dns.math., ['21']> ()
* Create <TxtRecord TXT 3600, fibonacci-9.dns.math., ['34']> ()
* Summary: Creates=25, Updates=0, Deletes=0, Existing=1, Meta=False
********************************************************************************
The log output
..............
Everything here matches the output and meaning of the first run in
:ref:`basic-setup`, with the important difference that both the statically
configured and dynamically generated records are listed as planned changes.
From here a ``--doit`` run can be executed to create the records in the
PowerDNS server, which can then be queried.
Viewing the results
-------------------
``dig`` can now be run to query for the records::
$ dig +short TXT dns.math.
"Try querying for TXT records named fibonacci-N where N is an integer 0-25"
$ dig +short TXT fibonacci-0.dns.math.
"0"
$ dig +short TXT fibonacci-23.dns.math.
"28657"
$ dig +short TXT fibonacci-99.dns.math.
Next Steps
----------
If the source will only be used in a single octoDNS setup and you're OK with it
living alongside your config, as was done in this example the
:download:`fibonacci.py` file can be used as a starting point. It is also
possible to create custom processors and providers that work in the same
manner, though the details of the code involved are outside the scope of this
example.
If the provider will be used more widely or published for others to use, see
`octodns-template`_.
.. _octodns-template: https://github.com/octodns/octodns-template