From 7a755d15be842f4910cb0ead7d7edc2f1e358b24 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sat, 24 Mar 2018 10:28:09 -0700 Subject: [PATCH 1/4] Make sure to insert new rulesets at the "end" Dyn will still match them, even while they're empty before we've had a chance to add the respons pools to them which is BAD and caused a medium-size outage (thankfully not as bad as it could have been.) Ideally we'd use publish=False and stage things, but that seems broken in the client lib, there's no way to send publish=N. I also tried sending the response_pool_ids as part of the create calls and response pool config if one didn't exist, but neither of those routes worked :-( --- octodns/provider/dyn.py | 16 ++++++++++++++-- tests/test_octodns_provider_dyn.py | 10 +++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/octodns/provider/dyn.py b/octodns/provider/dyn.py index 2799368..ef989bd 100644 --- a/octodns/provider/dyn.py +++ b/octodns/provider/dyn.py @@ -547,10 +547,22 @@ class DynProvider(BaseProvider): # Rulesets + # We need to make sure and insert the new rules after any existing + # rules so they won't take effect before we've had a chance to add + # response pools to them. I've tried both publish=False (which is + # completely broken in the client) and creating the rulesets with + # response_pool_ids neither of which appear to work from the client + # library. If there are no existing rulesets fallback to 0 + insert_at = max([ + int(r._ordering) + for r in existing_rulesets + ] + [-1]) + 1 + self.log.debug('_mod_rulesets: insert_at=%d', insert_at) + # add the default label = 'default:{}'.format(uuid4().hex) ruleset = DSFRuleset(label, 'always', []) - ruleset.create(td, index=0) + ruleset.create(td, index=insert_at) pool = self._find_or_create_pool(td, pools, 'default', new._type, new.values) # There's no way in the client lib to create a ruleset with an existing @@ -583,7 +595,7 @@ class DynProvider(BaseProvider): 'geoip': criteria }) # Something you have to call create others the constructor does it - ruleset.create(td, index=0) + ruleset.create(td, index=insert_at) first = geo.values[0] pool = self._find_or_create_pool(td, pools, first, new._type, diff --git a/tests/test_octodns_provider_dyn.py b/tests/test_octodns_provider_dyn.py index 85de59c..edb604a 100644 --- a/tests/test_octodns_provider_dyn.py +++ b/tests/test_octodns_provider_dyn.py @@ -1151,11 +1151,11 @@ class TestDynProviderGeo(TestCase): change = Create(self.geo_record) provider._mod_rulesets(td_mock, change) ruleset_create_mock.assert_has_calls(( - call(td_mock, index=0), - call(td_mock, index=0), - call(td_mock, index=0), - call(td_mock, index=0), - call(td_mock, index=0), + call(td_mock, index=2), + call(td_mock, index=2), + call(td_mock, index=2), + call(td_mock, index=2), + call(td_mock, index=2), )) add_response_pool_mock.assert_has_calls(( # default From 4904a0ea202d4c476f11e165450dbac40e740482 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sat, 24 Mar 2018 17:58:08 -0700 Subject: [PATCH 2/4] Sort existing_rulesets by _ordering desc, so default is removed first --- octodns/provider/dyn.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/octodns/provider/dyn.py b/octodns/provider/dyn.py index ef989bd..cb0dabf 100644 --- a/octodns/provider/dyn.py +++ b/octodns/provider/dyn.py @@ -535,6 +535,12 @@ class DynProvider(BaseProvider): for ruleset in existing_rulesets: for pool in ruleset.response_pools: pools[pool.response_pool_id] = pool + # Reverse sort the existing_rulesets by _ordering so that we'll remove + # them in that order later, this will ensure that we remove the old + # default before any of the old geo rules preventing it from catching + # everything. + existing_rulesets.sort(key=lambda r: r._ordering, reverse=True) + # Now we need to find any pools that aren't referenced by rules for pool in td.all_response_pools: rpid = pool.response_pool_id From 76f01f9f26ab770c41c365100c71d21f7ff91a63 Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Mon, 26 Mar 2018 08:28:49 -0700 Subject: [PATCH 3/4] 0.9.0 version bump and (partial) changelog updates --- CHANGELOG.md | 15 +++++++++++++++ octodns/__init__.py | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d8b441..11d984c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +## v0.9.0 - 2018-03-26 - Way too long since we last met + +* Way way way too much to list out here, shouldn't have waited so long +* Initial NS1 geo support +* Major reworking of `CloudflareProvider`'s update process, was only partially + functional before, also ignore proxied records +* Fixes and improvements to better support non-ascii records and zones +* Plans indicate when Zones are going to be created +* Fix for `GoogleCloudProvider` handling of ; escapes +* Skip Alias recordsets for Route53 (unsupported concept/type) +* Make sure that Record geo values are sorted to prevent false diffs that can + never be fixed +* `DynProvider` fix to safely roll rulesets, things could end up on rules + without a pool and/or hitting the default rule previously. + ## v0.8.8 - 2017-10-24 - Google Cloud DNS, Large TXT Record support * Added support for "chunking" TXT records where individual values were larger diff --git a/octodns/__init__.py b/octodns/__init__.py index 2166778..da72790 100644 --- a/octodns/__init__.py +++ b/octodns/__init__.py @@ -3,4 +3,4 @@ from __future__ import absolute_import, division, print_function, \ unicode_literals -__VERSION__ = '0.8.8' +__VERSION__ = '0.9.0' From 0b4f32e3630ac50d80a51fc5412a160ca47d9ccd Mon Sep 17 00:00:00 2001 From: Ross McFarland Date: Sat, 31 Mar 2018 12:09:05 -0700 Subject: [PATCH 4/4] Add twine dev requirement, use it in script/release --- script/release | 3 ++- setup.cfg | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/script/release b/script/release index bcc0ba3..eadd2e1 100755 --- a/script/release +++ b/script/release @@ -10,5 +10,6 @@ VERSION=$(grep __VERSION__ $ROOT/octodns/__init__.py | sed -e "s/.* = '//" -e "s git tag -s v$VERSION -m "Release $VERSION" git push origin v$VERSION echo "Tagged and pushed v$VERSION" -python setup.py sdist upload +python setup.py sdist +twine upload dist/*$VERSION.tar.gz echo "Uploaded $VERSION" diff --git a/setup.cfg b/setup.cfg index 51a1c69..15fed62 100644 --- a/setup.cfg +++ b/setup.cfg @@ -58,6 +58,7 @@ dev = ovh>=0.4.7 s3transfer>=0.1.10 six>=1.10.0 + twine>=1.11.0 test = coverage mock