1
0
mirror of https://github.com/github/octodns.git synced 2024-05-11 05:55:00 +00:00

Add Processor.process_source_and_target_zones

This commit is contained in:
Ross McFarland
2023-11-28 15:42:53 -08:00
parent 62ca2ec34c
commit 93a00f12a9
4 changed files with 80 additions and 2 deletions

View File

@ -1,6 +1,8 @@
## v1.?.0 - 2023-??-?? -
* Record.lenient property added similar to other common/standard _octodns data
* Processor.process_source_and_target_zones added to support modifying both the
desired and/or existing zones just prior to computing changes.
## v1.3.0 - 2023-11-14 - New and improved processors

View File

@ -37,7 +37,7 @@ class BaseProcessor(object):
computed between `existing` and `desired`. This provides an opportunity
to modify the `existing` `Zone`.
- Will see `existing` after any modifrications done by processors
- Will see `existing` after any modifications done by processors
configured to run before this one.
- May modify `existing` directly.
- Must return `existing` which will normally be the `existing` param.
@ -48,6 +48,33 @@ class BaseProcessor(object):
'''
return existing
def process_source_and_target_zones(self, desired, existing, target):
'''
Called just prior to computing changes for `target` between `desired`
and `existing`. Provides an opportunity for the processor to modify
either the desired or existing `Zone`s that will be used to compute the
changes and create the initial plan.
- Will see `desired` after any modifications done by
`Provider._process_desired_zone` and all processors via
`Processor.process_source_zone`
- Will see `existing` after any modifications done by all processors
via `Processor.process_target_zone`
- Will see both `desired` and `existing` after any modifications done by
any processors configured to run before this one via
`Processor.process_source_and_target_zones`.
- May modify `desired` directly.
- Must return `desired` which will normally be the `desired` param.
- May modify `existing` directly.
- Must return `existing` which will normally be the `existing` param.
- Must not modify records directly, `record.copy` should be called,
the results of which can be modified, and then `Zone.add_record` may
be used with `replace=True`.
- May call `Zone.remove_record` to remove records from `desired`.
- May call `Zone.remove_record` to remove records from `existing`.
'''
return desired, existing
def process_plan(self, plan, sources, target):
'''
Called after the planning phase has completed. Provides an opportunity

View File

@ -243,6 +243,11 @@ class BaseProvider(BaseSource):
for processor in processors:
existing = processor.process_target_zone(existing, target=self)
for processor in processors:
desired, existing = processor.process_source_and_target_zones(
desired, existing, self
)
# compute the changes at the zone/record level
changes = existing.changes(desired, self)

View File

@ -25,7 +25,7 @@ from octodns.manager import (
_AggregateTarget,
)
from octodns.processor.base import BaseProcessor
from octodns.record import Create, Delete, Record
from octodns.record import Create, Delete, Record, Update
from octodns.yaml import safe_load
from octodns.zone import Zone
@ -723,6 +723,50 @@ class TestManager(TestCase):
# We got a delete for the thing added to the existing state (target)
self.assertIsInstance(plans[0][1].changes[0], Delete)
# source & target
record2 = Record.new(
zone, 'a2', {'ttl': 31, 'type': 'A', 'value': '1.2.3.4'}
)
record3 = Record.new(
zone, 'a3', {'ttl': 32, 'type': 'A', 'value': '1.2.3.4'}
)
class MockProcessor(BaseProcessor):
def process_source_and_target_zones(
self, desired, existing, target
):
# add something to desired
desired.add_record(record2)
# add something to existing
existing.add_record(record3)
# add something to both, but with a modification
desired.add_record(record)
mod = record.copy()
mod.ttl += 1
existing.add_record(mod)
return desired, existing
mock = MockProcessor('mock')
plans, zone = manager._populate_and_plan(
'unit.tests.', [mock], [], targets
)
# we should see a plan
self.assertTrue(plans)
plan = plans[0][1]
# it shoudl have a create, an update, and a delete
self.assertEqual(
'a',
next(c.record.name for c in plan.changes if isinstance(c, Update)),
)
self.assertEqual(
'a2',
next(c.record.name for c in plan.changes if isinstance(c, Create)),
)
self.assertEqual(
'a3',
next(c.record.name for c in plan.changes if isinstance(c, Delete)),
)
# muck with plans
class MockProcessor(BaseProcessor):
def process_target_zone(self, zone, target):