# # # from logging import getLogger from octodns.record import Record from octodns.source.base import BaseSource # Based on https://stackoverflow.com/a/3954407 def _fibonacci(n): a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b class FibonacciProvider(BaseSource): # Here only TXT records are supported SUPPORTS = ('TXT',) # Do-not support (deprecated) GEO records SUPPORTS_GEO = False # This is pretty much boilerplate, create a logger with a standard name, # call up to the parent class BaseSource's __init__, store our # attributes, and then calculate our fibonacci sequence def __init__(self, id, n, ttl=3600): klass = self.__class__.__name__ self.log = getLogger(f'{klass}[{id}]') self.log.debug( '__init__: id=%s, variable=%s, name=%s, ttl=%d', id, n, ttl ) super().__init__(id) self.n = n self.ttl = ttl # calculate the requested number of values self.values = list(_fibonacci(n)) def populate(self, zone, target=False, lenient=False): # This is the method adding records to the zone. For a source it's the # only thing that needs to be implemented. Again there's some best # practices wrapping our custom logic, mostly for logging/debug # purposes. self.log.debug( 'populate: name=%s, target=%s, lenient=%s', zone.name, target, lenient, ) before = len(zone.records) # This is where the logic of the source lives. Here it's simply # translated the previously calculated fibonacci sequence into # corresponding TXT records. It could be anything: reading data from # disk, calling APIs, ... for i, value in enumerate(self.values): # If there's a chance the generated record may result in validation # errors it would make sense to pass lenient to new txt = Record.new( zone, f'fibonacci-{i}', {'value': str(value), 'ttl': self.ttl, 'type': 'TXT'}, ) # lenient should always be passed to add_record. If there's a # chance the source will create records that conflict with # something previously added by another provider it may make sense # to include `replace` here, possibly with an additional provider # parameter `populate_should_replace` zone.add_record(txt, lenient=lenient) self.log.info( 'populate: found %s records, exists=False', len(zone.records) - before, )