diff --git a/octodns/provider/ns1.py b/octodns/provider/ns1.py index 8f13ee5..5cb7c2e 100644 --- a/octodns/provider/ns1.py +++ b/octodns/provider/ns1.py @@ -614,9 +614,9 @@ class Ns1Provider(BaseProvider): def _uuid(self): return uuid4().hex - def _create_feed(self, monitor): + def _feed_create(self, monitor): monitor_id = monitor['id'] - self.log.debug('_create_feed: monitor=%s', monitor_id) + self.log.debug('_feed_create: monitor=%s', monitor_id) # TODO: looks like length limit is 64 char name = '{} - {}'.format(monitor['name'], self._uuid()[:6]) @@ -627,12 +627,12 @@ class Ns1Provider(BaseProvider): feed = self._client.datafeed_create(self._client.datasource_id, name, config) feed_id = feed['id'] - self.log.debug('_create_feed: feed=%s', feed_id) + self.log.debug('_feed_create: feed=%s', feed_id) return feed_id - def _create_monitor(self, monitor): - self.log.debug('_create_monitor: monitor="%s"', monitor['name']) + def _monitor_create(self, monitor): + self.log.debug('_monitor_create: monitor="%s"', monitor['name']) # Create the notify list notify_list = [{ 'config': { @@ -643,15 +643,15 @@ class Ns1Provider(BaseProvider): nl = self._client.notifylists_create(name=monitor['name'], notify_list=notify_list) nl_id = nl['id'] - self.log.debug('_create_monitor: notify_list=%s', nl_id) + self.log.debug('_monitor_create: notify_list=%s', nl_id) # Create the monitor monitor['notify_list'] = nl_id monitor = self._client.monitors_create(**monitor) monitor_id = monitor['id'] - self.log.debug('_create_monitor: monitor=%s', monitor_id) + self.log.debug('_monitor_create: monitor=%s', monitor_id) - return monitor_id, self._create_feed(monitor) + return monitor_id, self._feed_create(monitor) def _monitor_gen(self, record, value): host = record.fqdn[:-1] @@ -718,11 +718,11 @@ class Ns1Provider(BaseProvider): if feed_id is None: self.log.warn('_monitor_sync: %s (%s) missing feed, creating', existing['name'], monitor_id) - feed_id = self._create_feed(existing) + feed_id = self._feed_create(existing) else: self.log.debug('_monitor_sync: needs create') # We don't have an existing monitor create it (and related bits) - monitor_id, feed_id = self._create_monitor(expected) + monitor_id, feed_id = self._monitor_create(expected) return monitor_id, feed_id diff --git a/tests/test_octodns_provider_ns1.py b/tests/test_octodns_provider_ns1.py index ea7dcf2..994b84a 100644 --- a/tests/test_octodns_provider_ns1.py +++ b/tests/test_octodns_provider_ns1.py @@ -619,7 +619,7 @@ class TestNs1ProviderDynamic(TestCase): @patch('octodns.provider.ns1.Ns1Provider._uuid') @patch('ns1.rest.data.Feed.create') - def test_create_feed(self, datafeed_create_mock, uuid_mock): + def test_feed_create(self, datafeed_create_mock, uuid_mock): provider = Ns1Provider('test', 'api-key') # pre-fill caches to avoid extranious calls (things we're testing @@ -642,15 +642,15 @@ class TestNs1ProviderDynamic(TestCase): }, 'notes': 'host:unit.tests type:A', } - self.assertEquals('feed', provider._create_feed(monitor)) + self.assertEquals('feed', provider._feed_create(monitor)) datafeed_create_mock.assert_has_calls([call('foo', 'one name - xxxxxx', {'jobid': 'one'})]) - @patch('octodns.provider.ns1.Ns1Provider._create_feed') + @patch('octodns.provider.ns1.Ns1Provider._feed_create') @patch('octodns.provider.ns1.Ns1Client.monitors_create') @patch('octodns.provider.ns1.Ns1Client.notifylists_create') - def test_create_monitor(self, notifylists_create_mock, - monitors_create_mock, create_feed_mock): + def test_monitor_create(self, notifylists_create_mock, + monitors_create_mock, feed_create_mock): provider = Ns1Provider('test', 'api-key') # pre-fill caches to avoid extranious calls (things we're testing @@ -660,18 +660,18 @@ class TestNs1ProviderDynamic(TestCase): notifylists_create_mock.reset_mock() monitors_create_mock.reset_mock() - create_feed_mock.reset_mock() + feed_create_mock.reset_mock() notifylists_create_mock.side_effect = [{ 'id': 'nl-id', }] monitors_create_mock.side_effect = [{ 'id': 'mon-id', }] - create_feed_mock.side_effect = ['feed-id'] + feed_create_mock.side_effect = ['feed-id'] monitor = { 'name': 'test monitor', } - monitor_id, feed_id = provider._create_monitor(monitor) + monitor_id, feed_id = provider._monitor_create(monitor) self.assertEquals('mon-id', monitor_id) self.assertEquals('feed-id', feed_id) monitors_create_mock.assert_has_calls([call(name='test monitor', @@ -691,6 +691,144 @@ class TestNs1ProviderDynamic(TestCase): monitor = provider._monitor_gen(self.record, value) self.assertTrue(monitor['config']['ssl']) + def test_monitor_is_match(self): + provider = Ns1Provider('test', 'api-key') + + # Empty matches empty + self.assertTrue(provider._monitor_is_match({}, {})) + + # Anything matches empty + self.assertTrue(provider._monitor_is_match({}, { + 'anything': 'goes' + })) + + # Missing doesn't match + self.assertFalse(provider._monitor_is_match({ + 'exepct': 'this', + }, { + 'anything': 'goes' + })) + + # Identical matches + self.assertTrue(provider._monitor_is_match({ + 'exepct': 'this', + }, { + 'exepct': 'this', + })) + + # Different values don't match + self.assertFalse(provider._monitor_is_match({ + 'exepct': 'this', + }, { + 'exepct': 'that', + })) + + # Different sub-values don't match + self.assertFalse(provider._monitor_is_match({ + 'exepct': { + 'this': 'to-be', + }, + }, { + 'exepct': { + 'this': 'something-else', + }, + })) + + @patch('octodns.provider.ns1.Ns1Provider._feed_create') + @patch('octodns.provider.ns1.Ns1Client.monitors_update') + @patch('octodns.provider.ns1.Ns1Provider._monitor_create') + @patch('octodns.provider.ns1.Ns1Provider._monitor_gen') + def test_monitor_sync(self, monitor_gen_mock, monitor_create_mock, + monitors_update_mock, feed_create_mock): + provider = Ns1Provider('test', 'api-key') + + # pre-fill caches to avoid extranious calls (things we're testing + # elsewhere) + provider._client._datasource_id = 'foo' + provider._client._feeds_for_monitors = { + 'mon-id': 'feed-id', + } + + # No existing monitor + monitor_gen_mock.reset_mock() + monitor_create_mock.reset_mock() + monitors_update_mock.reset_mock() + feed_create_mock.reset_mock() + monitor_gen_mock.side_effect = [{'key': 'value'}] + monitor_create_mock.side_effect = [('mon-id', 'feed-id')] + value = '1.2.3.4' + monitor_id, feed_id = provider._monitor_sync(self.record, value, None) + self.assertEquals('mon-id', monitor_id) + self.assertEquals('feed-id', feed_id) + monitor_gen_mock.assert_has_calls([call(self.record, value)]) + monitor_create_mock.assert_has_calls([call({'key': 'value'})]) + monitors_update_mock.assert_not_called() + feed_create_mock.assert_not_called() + + # Existing monitor that doesn't need updates + monitor_gen_mock.reset_mock() + monitor_create_mock.reset_mock() + monitors_update_mock.reset_mock() + feed_create_mock.reset_mock() + monitor = { + 'id': 'mon-id', + 'key': 'value', + 'name': 'monitor name', + } + monitor_gen_mock.side_effect = [monitor] + monitor_id, feed_id = provider._monitor_sync(self.record, value, + monitor) + self.assertEquals('mon-id', monitor_id) + self.assertEquals('feed-id', feed_id) + monitor_gen_mock.assert_called_once() + monitor_create_mock.assert_not_called() + monitors_update_mock.assert_not_called() + feed_create_mock.assert_not_called() + + # Existing monitor that doesn't need updates, but is missing its feed + monitor_gen_mock.reset_mock() + monitor_create_mock.reset_mock() + monitors_update_mock.reset_mock() + feed_create_mock.reset_mock() + monitor = { + 'id': 'mon-id2', + 'key': 'value', + 'name': 'monitor name', + } + monitor_gen_mock.side_effect = [monitor] + feed_create_mock.side_effect = ['feed-id2'] + monitor_id, feed_id = provider._monitor_sync(self.record, value, + monitor) + self.assertEquals('mon-id2', monitor_id) + self.assertEquals('feed-id2', feed_id) + monitor_gen_mock.assert_called_once() + monitor_create_mock.assert_not_called() + monitors_update_mock.assert_not_called() + feed_create_mock.assert_has_calls([call(monitor)]) + + # Existing monitor that needs updates + monitor_gen_mock.reset_mock() + monitor_create_mock.reset_mock() + monitors_update_mock.reset_mock() + feed_create_mock.reset_mock() + monitor = { + 'id': 'mon-id', + 'key': 'value', + 'name': 'monitor name', + } + gened = { + 'other': 'thing', + } + monitor_gen_mock.side_effect = [gened] + monitor_id, feed_id = provider._monitor_sync(self.record, value, + monitor) + self.assertEquals('mon-id', monitor_id) + self.assertEquals('feed-id', feed_id) + monitor_gen_mock.assert_called_once() + monitor_create_mock.assert_not_called() + monitors_update_mock.assert_has_calls([call('mon-id', other='thing')]) + feed_create_mock.assert_not_called() + class TestNs1Client(TestCase):