コード例 #1
0
    def test_populate_traffic_directors_empty(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # empty all around
        mock.side_effect = [
            # get traffic directors
            {
                'data': []
            },
            # get zone
            {
                'data': {}
            },
            # get records
            {
                'data': {}
            },
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        self.assertEquals(0, len(got.records))
        mock.assert_has_calls([
            call('/DSF/', 'GET', {'detail': 'Y'}),
            call('/Zone/unit.tests/', 'GET', {}),
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'}),
        ])
コード例 #2
0
 def setUpClass(self):
     # Get the DynectSession creation out of the way so that tests can
     # ignore it
     with patch('dyn.core.SessionEngine.execute',
                return_value={'status': 'success'}):
         provider = DynProvider('test', 'cust', 'user', 'pass')
         provider._check_dyn_sess()
コード例 #3
0
    def test_populate_traffic_directors_regular(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # only regular
        mock.side_effect = [
            # get traffic directors
            {
                'data': []
            },
            # get zone
            {
                'data': {}
            },
            # get records
            self.records_response
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        self.assertEquals(1, len(got.records))
        self.assertFalse(self.expected_regular.changes(got, provider))
        mock.assert_has_calls([
            call('/DSF/', 'GET', {'detail': 'Y'}),
            call('/Zone/unit.tests/', 'GET', {}),
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'}),
        ])
コード例 #4
0
    def test_populate_traffic_directors_both(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # both traffic director and regular, regular is ignored
        mock.side_effect = [
            # get traffic directors
            self.traffic_directors_reponse,
            # get traffic director
            self.traffic_director_response,
            # get zone
            {
                'data': {}
            },
            # get records
            self.records_response
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        self.assertEquals(1, len(got.records))
        self.assertFalse(self.expected_geo.changes(got, provider))
        mock.assert_has_calls([
            call('/DSF/2ERWXQNsb_IKG2YZgYqkPvk0PBM/', 'GET',
                 {'pending_changes': 'Y'}),
            call('/Zone/unit.tests/', 'GET', {}),
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'}),
        ])
コード例 #5
0
    def test_populate_traffic_director_busted(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        busted_traffic_director_response = {
            "status":
            "success",
            "data": {
                "notifiers": [],
                "rulesets": [],
                "ttl": "300",
                "active": "Y",
                "service_id": "oIRZ4lM-W64NUelJGuzuVziZ4MI",
                "nodes": [{
                    "fqdn": "unit.tests",
                    "zone": "unit.tests"
                }],
                "pending_change": "",
                "label": "unit.tests.:A"
            },
            "job_id":
            3376642606,
            "msgs": [{
                "INFO": "detail: Here is your service",
                "LVL": "INFO",
                "ERR_CD": None,
                "SOURCE": "BLL"
            }]
        }
        # busted traffic director
        mock.side_effect = [
            # get traffic directors
            self.traffic_directors_reponse,
            # get traffic director
            busted_traffic_director_response,
            # get zone
            {
                'data': {}
            },
            # get records
            {
                'data': {}
            },
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        self.assertEquals(1, len(got.records))
        # we expect a change here for the record, the values aren't important,
        # so just compare set contents (which does name and type)
        self.assertEquals(self.expected_geo.records, got.records)
        mock.assert_has_calls([
            call('/DSF/2ERWXQNsb_IKG2YZgYqkPvk0PBM/', 'GET',
                 {'pending_changes': 'Y'}),
            call('/Zone/unit.tests/', 'GET', {}),
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'}),
        ])
コード例 #6
0
    def test_sync(self, execute_mock):
        provider = DynProvider('test', 'cust', 'user', 'pass')

        # Test Zone create
        execute_mock.side_effect = [
            # No such zone, during populate
            DynectGetError('foo'),
            # No such zone, during sync
            DynectGetError('foo'),
            # get empty Zone
            {
                'data': {}
            },
            # get zone we can modify & delete with
            {
                'data': {
                    # A top-level to delete
                    'a_records': [{
                        'fqdn': 'www.unit.tests',
                        'rdata': {
                            'address': '1.2.3.4'
                        },
                        'record_id': 1,
                        'record_type': 'A',
                        'ttl': 300,
                        'zone': 'unit.tests',
                    }],
                    # A node to delete
                    'alias_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'alias': 'www.unit.tests.'
                        },
                        'record_id': 2,
                        'record_type': 'ALIAS',
                        'ttl': 300,
                        'zone': 'unit.tests',
                    }],
                }
            }
        ]

        # No existing records, create all
        with patch('dyn.tm.zones.Zone.add_record') as add_mock:
            with patch('dyn.tm.zones.Zone._update') as update_mock:
                plan = provider.plan(self.expected)
                update_mock.assert_not_called()
                provider.apply(plan)
                update_mock.assert_called()
            add_mock.assert_called()
            # Once for each dyn record
            self.assertEquals(2, len(add_mock.call_args_list))
        execute_mock.assert_has_calls([
            call('/Zone/unit.tests/', 'GET', {}),
            call('/Zone/unit.tests/', 'GET', {})
        ])
        self.assertEquals(2, len(plan.changes))
コード例 #7
0
    def test_traffic_directors(self, mock):
        provider = DynProvider('test', 'cust', 'user', 'pass', True)
        # short-circuit session checking
        provider._dyn_sess = True

        # no tds
        mock.side_effect = [{'data': []}]
        self.assertEquals({}, provider.traffic_directors)

        # a supported td and an ingored one
        response = {
            'data': [{
                'active': 'Y',
                'label': 'unit.tests.:A',
                'nodes': [],
                'notifiers': [],
                'pending_change': '',
                'rulesets': [],
                'service_id': '2ERWXQNsb_IKG2YZgYqkPvk0PBM',
                'ttl': '300'
            }, {
                'active': 'Y',
                'label': 'geo.unit.tests.:A',
                'nodes': [],
                'notifiers': [],
                'pending_change': '',
                'rulesets': [],
                'service_id': '3ERWXQNsb_IKG2YZgYqkPvk0PBM',
                'ttl': '300'
            }, {
                'active': 'Y',
                'label': 'something else',
                'nodes': [],
                'notifiers': [],
                'pending_change': '',
                'rulesets': [],
                'service_id': '4ERWXQNsb_IKG2YZgYqkPvk0PBM',
                'ttl': '300'
            }],
            'job_id':
            3376164583,
            'status':
            'success'
        }
        mock.side_effect = [response]
        # first make sure that we get the empty version from cache
        self.assertEquals({}, provider.traffic_directors)
        # reach in and bust the cache
        provider._traffic_directors = None
        tds = provider.traffic_directors
        self.assertEquals(set(['unit.tests.', 'geo.unit.tests.']),
                          set(tds.keys()))
        self.assertEquals(['A'], tds['unit.tests.'].keys())
        self.assertEquals(['A'], tds['geo.unit.tests.'].keys())
コード例 #8
0
    def test_apply_traffic_director(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # stubbing these out to avoid a lot of messy mocking, they'll be tested
        # individually, we'll check for expected calls
        provider._mod_geo_Create = MagicMock()
        provider._mod_geo_Update = MagicMock()
        provider._mod_geo_Delete = MagicMock()
        provider._mod_Create = MagicMock()
        provider._mod_Update = MagicMock()
        provider._mod_Delete = MagicMock()

        # busted traffic director
        mock.side_effect = [
            # get zone
            {
                'data': {}
            },
            # accept publish
            {
                'data': {}
            },
        ]
        desired = Zone('unit.tests.', [])
        geo = self.geo_record
        regular = self.regular_record

        changes = [
            Create(geo),
            Create(regular),
            Update(geo, geo),
            Update(regular, regular),
            Delete(geo),
            Delete(regular),
        ]
        plan = Plan(None, desired, changes)
        provider._apply(plan)
        mock.assert_has_calls([
            call('/Zone/unit.tests/', 'GET', {}),
            call('/Zone/unit.tests/', 'PUT', {'publish': True})
        ])
        # should have seen 1 call to each
        provider._mod_geo_Create.assert_called_once()
        provider._mod_geo_Update.assert_called_once()
        provider._mod_geo_Delete.assert_called_once()
        provider._mod_Create.assert_called_once()
        provider._mod_Update.assert_called_once()
        provider._mod_Delete.assert_called_once()
コード例 #9
0
    def test_populate_non_existent(self, execute_mock):
        provider = DynProvider('test', 'cust', 'user', 'pass')

        # Test Zone create
        execute_mock.side_effect = [
            DynectGetError('foo'),
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        execute_mock.assert_has_calls([
            call('/Zone/unit.tests/', 'GET', {}),
        ])
        self.assertEquals(set(), got.records)
コード例 #10
0
    def test_mod_geo_delete(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        td_mock = MagicMock()
        provider._traffic_directors = {
            'unit.tests.': {
                'A': td_mock,
            }
        }
        provider._mod_geo_Delete(None, Delete(self.geo_record))
        # delete called
        td_mock.delete.assert_called_once()
        # removed from cache
        self.assertFalse('A' in provider.traffic_directors['unit.tests.'])
コード例 #11
0
    def test_populate(self, execute_mock):
        provider = DynProvider('test', 'cust', 'user', 'pass')

        # Test Zone create
        execute_mock.side_effect = [
            # get Zone
            {
                'data': {}
            },
            # get_all_records
            {
                'data': {
                    'a_records': [{
                        'fqdn': 'www.unit.tests',
                        'rdata': {
                            'address': '1.2.3.4'
                        },
                        'record_id': 1,
                        'record_type': 'A',
                        'ttl': 300,
                        'zone': 'unit.tests',
                    }],
                    'alias_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'alias': 'www.unit.tests.'
                        },
                        'record_id': 2,
                        'record_type': 'ALIAS',
                        'ttl': 300,
                        'zone': 'unit.tests',
                    }],
                }
            }
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        execute_mock.assert_has_calls([
            call('/Zone/unit.tests/', 'GET', {}),
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'})
        ])
        changes = self.expected.changes(got, SimpleProvider())
        self.assertEquals([], changes)
コード例 #12
0
    def test_mod_geo_create(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # will be tested seperately
        provider._mod_rulesets = MagicMock()

        mock.side_effect = [
            # create traffic director
            self.traffic_director_response,
            # get traffic directors
            self.traffic_directors_reponse
        ]
        provider._mod_geo_Create(None, Create(self.geo_record))
        # td now lives in cache
        self.assertTrue('A' in provider.traffic_directors['unit.tests.'])
        # should have seen 1 gen call
        provider._mod_rulesets.assert_called_once()
コード例 #13
0
    def test_mod_geo_update_geo_geo(self):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # update of an existing td

        # pre-populate the cache with our mock td
        provider._traffic_directors = {
            'unit.tests.': {
                'A': 42,
            }
        }
        # mock _mod_rulesets
        provider._mod_rulesets = MagicMock()

        geo = self.geo_record
        change = Update(geo, geo)
        provider._mod_geo_Update(None, change)
        # still in cache
        self.assertTrue('A' in provider.traffic_directors['unit.tests.'])
        # should have seen 1 gen call
        provider._mod_rulesets.assert_called_once_with(42, change)
コード例 #14
0
    def test_mod_rulesets_create(self, _, ruleset_create_mock,
                                 add_response_pool_mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        td_mock = MagicMock()
        td_mock._rulesets = []
        provider._traffic_director_monitor = MagicMock()
        provider._find_or_create_pool = MagicMock()

        td_mock.all_response_pools = []

        provider._find_or_create_pool.side_effect = [
            _DummyPool('default'),
            _DummyPool(1),
            _DummyPool(2),
            _DummyPool(3),
            _DummyPool(4),
        ]

        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),
        ))
        add_response_pool_mock.assert_has_calls((
            # default
            call('default'),
            # first geo and it's fallback
            call(1),
            call('default', index=999),
            # 2nd geo and it's fallback
            call(2),
            call('default', index=999),
            # 3nd geo and it's fallback
            call(3),
            call('default', index=999),
            # 4th geo and it's 2 levels of fallback
            call(4),
            call(3, index=999),
            call('default', index=999),
        ))
コード例 #15
0
    def test_mod_geo_update_regular_geo(self, _):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        # convert a regular record to a td

        provider._mod_geo_Create = MagicMock()
        provider._mod_Delete = MagicMock()

        change = Update(self.regular_record, self.geo_record)
        provider._mod_geo_Update(42, change)
        # should have seen a call to create the new geo record
        provider._mod_geo_Create.assert_called_once_with(42, change)
        # should have seen a call to delete the old regular record
        provider._mod_Delete.assert_called_once_with(42, change)
コード例 #16
0
    def test_find_or_create_pool(self, mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        td = 42

        # no candidates cache miss, so create
        values = ['1.2.3.4', '1.2.3.5']
        pool = provider._find_or_create_pool(td, [], 'default', 'A', values)
        self.assertIsInstance(pool, DSFResponsePool)
        self.assertEquals(1, len(pool.rs_chains))
        records = pool.rs_chains[0].record_sets[0].records
        self.assertEquals(values, [r.address for r in records])
        mock.assert_called_once_with(td)

        # cache hit, use the one we just created
        mock.reset_mock()
        pools = [pool]
        cached = provider._find_or_create_pool(td, pools, 'default', 'A',
                                               values)
        self.assertEquals(pool, cached)
        mock.assert_not_called()

        # cache miss, non-matching label
        mock.reset_mock()
        miss = provider._find_or_create_pool(td, pools, 'NA-US-CA', 'A',
                                             values)
        self.assertNotEquals(pool, miss)
        self.assertEquals('NA-US-CA', miss.label)
        mock.assert_called_once_with(td)

        # cache miss, non-matching label
        mock.reset_mock()
        values = ['2.2.3.4.', '2.2.3.5']
        miss = provider._find_or_create_pool(td, pools, 'default', 'A', values)
        self.assertNotEquals(pool, miss)
        mock.assert_called_once_with(td)
コード例 #17
0
    def test_traffic_director_monitor(self, mock):
        provider = DynProvider('test', 'cust', 'user', 'pass', True)
        # short-circuit session checking
        provider._dyn_sess = True

        # no monitors, will try and create
        geo_monitor_id = '42x'
        mock.side_effect = [
            self.monitors_response, {
                'data': {
                    'active': 'Y',
                    'dsf_monitor_id': geo_monitor_id,
                    'endpoints': [],
                    'label': 'geo.unit.tests.',
                    'notifier': '',
                    'options': {
                        'expected': '',
                        'header': 'User-Agent: Dyn Monitor',
                        'host': 'geo.unit.tests.',
                        'path': '/_dns',
                        'port': '443',
                        'timeout': '10'
                    },
                    'probe_interval': '60',
                    'protocol': 'HTTPS',
                    'response_count': '2',
                    'retries': '2'
                },
                'job_id':
                3376259461,
                'msgs': [{
                    'ERR_CD': None,
                    'INFO': 'add: Here is the new monitor',
                    'LVL': 'INFO',
                    'SOURCE': 'BLL'
                }],
                'status':
                'success'
            }
        ]

        # ask for a monitor that doesn't exist
        monitor = provider._traffic_director_monitor('geo.unit.tests.')
        self.assertEquals(geo_monitor_id, monitor.dsf_monitor_id)
        # should see a request for the list and a create
        mock.assert_has_calls([
            call('/DSFMonitor/', 'GET', {'detail': 'Y'}),
            call(
                '/DSFMonitor/', 'POST', {
                    'retries': 2,
                    'protocol': 'HTTPS',
                    'response_count': 2,
                    'label': 'geo.unit.tests.',
                    'probe_interval': 60,
                    'active': 'Y',
                    'options': {
                        'path': '/_dns',
                        'host': 'geo.unit.tests',
                        'header': 'User-Agent: Dyn Monitor',
                        'port': 443,
                        'timeout': 10
                    }
                })
        ])
        # created monitor is now cached
        self.assertTrue(
            'geo.unit.tests.' in provider._traffic_director_monitors)
        # pre-existing one is there too
        self.assertTrue('unit.tests.' in provider._traffic_director_monitors)

        # now ask for a monitor that does exist
        mock.reset_mock()
        monitor = provider._traffic_director_monitor('unit.tests.')
        self.assertEquals(self.monitor_id, monitor.dsf_monitor_id)
        # should have resulted in no calls b/c exists & we've cached the list
        mock.assert_not_called()
コード例 #18
0
    def test_mod_rulesets_existing(self, _, ruleset_create_mock,
                                   add_response_pool_mock,
                                   get_response_pool_mock):
        provider = DynProvider('test',
                               'cust',
                               'user',
                               'pass',
                               traffic_directors_enabled=True)

        ruleset_mock = MagicMock()
        ruleset_mock.response_pools = [_DummyPool(3)]

        td_mock = MagicMock()
        td_mock._rulesets = [
            ruleset_mock,
        ]
        provider._traffic_director_monitor = MagicMock()
        provider._find_or_create_pool = MagicMock()

        unused_pool = _DummyPool('unused')
        td_mock.all_response_pools = \
            ruleset_mock.response_pools + [unused_pool]
        get_response_pool_mock.return_value = unused_pool

        provider._find_or_create_pool.side_effect = [
            _DummyPool('default'),
            _DummyPool(1),
            _DummyPool(2),
            ruleset_mock.response_pools[0],
            _DummyPool(4),
        ]

        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),
        ))
        add_response_pool_mock.assert_has_calls((
            # default
            call('default'),
            # first geo and it's fallback
            call(1),
            call('default', index=999),
            # 2nd geo and it's fallback
            call(2),
            call('default', index=999),
            # 3nd geo, from existing, and it's fallback
            call(3),
            call('default', index=999),
            # 4th geo and it's 2 levels of fallback
            call(4),
            call(3, index=999),
            call('default', index=999),
        ))
        # unused poll should have been deleted
        self.assertTrue(unused_pool.deleted)
        # old ruleset ruleset should be deleted, it's pool will have been
        # reused
        ruleset_mock.delete.assert_called_once()
コード例 #19
0
    def test_sync(self, execute_mock):
        provider = DynProvider('test', 'cust', 'user', 'pass')

        # Test Zone create
        execute_mock.side_effect = [
            # No such zone, during populate
            DynectGetError('foo'),
            # No such zone, during sync
            DynectGetError('foo'),
            # get empty Zone
            {
                'data': {}
            },
            # get zone we can modify & delete with
            {
                'data': {
                    # A top-level to delete
                    'a_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'address': '1.2.3.4'
                        },
                        'record_id': 1,
                        'record_type': 'A',
                        'ttl': 30,
                        'zone': 'unit.tests',
                    }, {
                        'fqdn': 'a.unit.tests',
                        'rdata': {
                            'address': '2.3.4.5'
                        },
                        'record_id': 2,
                        'record_type': 'A',
                        'ttl': 30,
                        'zone': 'unit.tests',
                    }],
                    # A node to delete
                    'cname_records': [{
                        'fqdn': 'cname.unit.tests',
                        'rdata': {
                            'cname': 'unit.tests.'
                        },
                        'record_id': 3,
                        'record_type': 'CNAME',
                        'ttl': 30,
                        'zone': 'unit.tests',
                    }],
                    # A record to leave alone
                    'ptr_records': [{
                        'fqdn': 'ptr.unit.tests',
                        'rdata': {
                            'ptrdname': 'xx.unit.tests.'
                        },
                        'record_id': 4,
                        'record_type': 'PTR',
                        'ttl': 30,
                        'zone': 'unit.tests',
                    }],
                    # A record to modify
                    'srv_records': [{
                        'fqdn': '_srv._tcp.unit.tests',
                        'rdata': {
                            'port': 10,
                            'priority': 11,
                            'target': 'foo-1.unit.tests.',
                            'weight': 12
                        },
                        'record_id': 5,
                        'record_type': 'SRV',
                        'ttl': 30,
                        'zone': 'unit.tests',
                    }, {
                        'fqdn': '_srv._tcp.unit.tests',
                        'rdata': {
                            'port': 20,
                            'priority': 21,
                            'target': 'foo-2.unit.tests.',
                            'weight': 22
                        },
                        'record_id': 6,
                        'record_type': 'SRV',
                        'ttl': 30,
                        'zone': 'unit.tests',
                    }],
                }
            }
        ]

        # No existing records, create all
        with patch('dyn.tm.zones.Zone.add_record') as add_mock:
            with patch('dyn.tm.zones.Zone._update') as update_mock:
                plan = provider.plan(self.expected)
                update_mock.assert_not_called()
                provider.apply(plan)
                update_mock.assert_called()
            add_mock.assert_called()
            # Once for each dyn record (8 Records, 2 of which have dual values)
            self.assertEquals(15, len(add_mock.call_args_list))
        execute_mock.assert_has_calls([
            call('/Zone/unit.tests/', 'GET', {}),
            call('/Zone/unit.tests/', 'GET', {})
        ])
        self.assertEquals(10, len(plan.changes))

        execute_mock.reset_mock()

        # Delete one and modify another
        new = Zone('unit.tests.', [])
        for name, data in (('a', {
                'type': 'A',
                'ttl': 30,
                'value': '2.3.4.5'
        }), ('ptr', {
                'type': 'PTR',
                'ttl': 30,
                'value': 'xx.unit.tests.'
        }), ('_srv._tcp', {
                'type':
                'SRV',
                'ttl':
                30,
                'values': [{
                    'priority': 31,
                    'weight': 12,
                    'port': 10,
                    'target': 'foo-1.unit.tests.'
                }, {
                    'priority': 21,
                    'weight': 22,
                    'port': 20,
                    'target': 'foo-2.unit.tests.'
                }]
        })):
            new.add_record(Record.new(new, name, data))

        with patch('dyn.tm.zones.Zone.add_record') as add_mock:
            with patch('dyn.tm.records.DNSRecord.delete') as delete_mock:
                with patch('dyn.tm.zones.Zone._update') as update_mock:
                    plan = provider.plan(new)
                    provider.apply(plan)
                    update_mock.assert_called()
                # we expect 4 deletes, 2 from actual deletes and 2 from
                # updates which delete and recreate
                self.assertEquals(4, len(delete_mock.call_args_list))
            # the 2 (re)creates
            self.assertEquals(2, len(add_mock.call_args_list))
        execute_mock.assert_has_calls([
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'})
        ])
        self.assertEquals(3, len(plan.changes))
コード例 #20
0
    def test_populate(self, execute_mock):
        provider = DynProvider('test', 'cust', 'user', 'pass')

        # Test Zone create
        execute_mock.side_effect = [
            # get Zone
            {
                'data': {}
            },
            # get_all_records
            {
                'data': {
                    'a_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'address': '1.2.3.4'
                        },
                        'record_id': 1,
                        'record_type': 'A',
                        'ttl': 300,
                        'zone': 'unit.tests',
                    }],
                    'cname_records': [{
                        'fqdn': 'cname.unit.tests',
                        'rdata': {
                            'cname': 'unit.tests.'
                        },
                        'record_id': 2,
                        'record_type': 'CNAME',
                        'ttl': 301,
                        'zone': 'unit.tests',
                    }],
                    'ns_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'nsdname': 'ns1.p10.dynect.net.'
                        },
                        'record_id': 254597562,
                        'record_type': 'NS',
                        'service_class': '',
                        'ttl': 3600,
                        'zone': 'unit.tests'
                    }, {
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'nsdname': 'ns2.p10.dynect.net.'
                        },
                        'record_id': 254597563,
                        'record_type': 'NS',
                        'service_class': '',
                        'ttl': 3600,
                        'zone': 'unit.tests'
                    }, {
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'nsdname': 'ns3.p10.dynect.net.'
                        },
                        'record_id': 254597564,
                        'record_type': 'NS',
                        'service_class': '',
                        'ttl': 3600,
                        'zone': 'unit.tests'
                    }, {
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'nsdname': 'ns4.p10.dynect.net.'
                        },
                        'record_id': 254597565,
                        'record_type': 'NS',
                        'service_class': '',
                        'ttl': 3600,
                        'zone': 'unit.tests'
                    }, {
                        'fqdn': 'sub.unit.tests',
                        'rdata': {
                            'nsdname': 'ns3.p10.dynect.net.'
                        },
                        'record_id': 254597564,
                        'record_type': 'NS',
                        'service_class': '',
                        'ttl': 3600,
                        'zone': 'unit.tests'
                    }, {
                        'fqdn': 'sub.unit.tests',
                        'rdata': {
                            'nsdname': 'ns3.p10.dynect.net.'
                        },
                        'record_id': 254597564,
                        'record_type': 'NS',
                        'service_class': '',
                        'ttl': 3600,
                        'zone': 'unit.tests'
                    }],
                    'mx_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'exchange': 'smtp-1.unit.tests.',
                            'preference': 10
                        },
                        'record_id': 3,
                        'record_type': 'MX',
                        'ttl': 302,
                        'zone': 'unit.tests',
                    }, {
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'exchange': 'smtp-2.unit.tests.',
                            'preference': 20
                        },
                        'record_id': 4,
                        'record_type': 'MX',
                        'ttl': 302,
                        'zone': 'unit.tests',
                    }],
                    'naptr_records': [{
                        'fqdn': 'naptr.unit.tests',
                        'rdata': {
                            'flags': 'U',
                            'order': 100,
                            'preference': 101,
                            'regexp': '!^.*$!sip:[email protected]!',
                            'replacement': '.',
                            'services': 'SIP+D2U'
                        },
                        'record_id': 5,
                        'record_type': 'MX',
                        'ttl': 303,
                        'zone': 'unit.tests',
                    }, {
                        'fqdn': 'naptr.unit.tests',
                        'rdata': {
                            'flags': 'U',
                            'order': 200,
                            'preference': 201,
                            'regexp': '!^.*$!sip:[email protected]!',
                            'replacement': '.',
                            'services': 'SIP+D2U'
                        },
                        'record_id': 6,
                        'record_type': 'MX',
                        'ttl': 303,
                        'zone': 'unit.tests',
                    }],
                    'ptr_records': [{
                        'fqdn': 'ptr.unit.tests',
                        'rdata': {
                            'ptrdname': 'xx.unit.tests.'
                        },
                        'record_id': 7,
                        'record_type': 'PTR',
                        'ttl': 304,
                        'zone': 'unit.tests',
                    }],
                    'soa_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'txtdata':
                            'ns1.p16.dynect.net. '
                            'hostmaster.unit.tests. 4 3600 600 604800 1800'
                        },
                        'record_id': 99,
                        'record_type': 'SOA',
                        'ttl': 299,
                        'zone': 'unit.tests',
                    }],
                    'spf_records': [{
                        'fqdn': 'spf.unit.tests',
                        'rdata': {
                            'txtdata': 'v=spf1 ip4:192.168.0.1/16-all'
                        },
                        'record_id': 8,
                        'record_type': 'SPF',
                        'ttl': 305,
                        'zone': 'unit.tests',
                    }, {
                        'fqdn': 'spf.unit.tests',
                        'rdata': {
                            'txtdata': 'v=spf1 -all'
                        },
                        'record_id': 8,
                        'record_type': 'SPF',
                        'ttl': 305,
                        'zone': 'unit.tests',
                    }],
                    'sshfp_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'algorithm': 1,
                            'fingerprint':
                            'bf6b6825d2977c511a475bbefb88aad54a92ac73',
                            'fptype': 1
                        },
                        'record_id': 9,
                        'record_type': 'SSHFP',
                        'ttl': 306,
                        'zone': 'unit.tests',
                    }],
                    'srv_records': [{
                        'fqdn': '_srv._tcp.unit.tests',
                        'rdata': {
                            'port': 10,
                            'priority': 11,
                            'target': 'foo-1.unit.tests.',
                            'weight': 12
                        },
                        'record_id': 10,
                        'record_type': 'SRV',
                        'ttl': 307,
                        'zone': 'unit.tests',
                    }, {
                        'fqdn': '_srv._tcp.unit.tests',
                        'rdata': {
                            'port': 20,
                            'priority': 21,
                            'target': 'foo-2.unit.tests.',
                            'weight': 22
                        },
                        'record_id': 11,
                        'record_type': 'SRV',
                        'ttl': 307,
                        'zone': 'unit.tests',
                    }],
                    'caa_records': [{
                        'fqdn': 'unit.tests',
                        'rdata': {
                            'flags': 0,
                            'tag': 'issue',
                            'value': 'ca.unit.tests'
                        },
                        'record_id': 12,
                        'record_type': 'cAA',
                        'ttl': 308,
                        'zone': 'unit.tests',
                    }],
                }
            }
        ]
        got = Zone('unit.tests.', [])
        provider.populate(got)
        execute_mock.assert_has_calls([
            call('/Zone/unit.tests/', 'GET', {}),
            call('/AllRecord/unit.tests/unit.tests./', 'GET', {'detail': 'Y'})
        ])
        changes = self.expected.changes(got, SimpleProvider())
        self.assertEquals([], changes)