def test_retrieve_zones_cluster_relation(self):
     relation = mock.MagicMock()
     self.patch(designate_bind.DesignateBindCharm, 'get_sync_time')
     self.patch(designate_bind.DesignateBindCharm, 'get_sync_src')
     self.patch(designate_bind.DesignateBindCharm, 'service_control')
     self.patch(designate_bind.hookenv, 'log')
     self.patch(designate_bind.reactive, 'set_state')
     self.patch(designate_bind.reactive, 'remove_state')
     self.patch(designate_bind.os, 'remove')
     self.patch(designate_bind.subprocess, 'check_call')
     self.patch_object(designate_bind.DesignateBindCharm, 'wget_file')
     self.get_sync_src.return_value = 'http://ip1/tarfile.tar'
     ctrl_calls = [
         mock.call('stop', ['bind9']),
         mock.call('start', ['bind9'])
     ]
     a = designate_bind.DesignateBindCharm()
     # Using cluster_relation, no sync needed
     relation.retrieve_local.return_value = ['30']
     self.get_sync_time.return_value = '20'
     a.retrieve_zones(relation)
     self.assertFalse(self.service_control.called)
     # Using cluster_relation, sync needed
     self.service_control.reset_mock()
     relation.retrieve_local.return_value = ['10']
     self.get_sync_time.return_value = '20'
     a.retrieve_zones(relation)
     self.service_control.assert_has_calls(ctrl_calls)
     self.check_call.assert_called_once_with(['tar', 'xf', 'tarfile.tar'],
                                             cwd='/var/cache/bind')
     self.wget_file.assert_called_once_with('http://ip1/tarfile.tar',
                                            '/var/cache/bind')
 def test_create_sync_src_info_file(self):
     self.patch(designate_bind.hookenv, 'local_unit', return_value='unit/1')
     a = designate_bind.DesignateBindCharm()
     with mock.patch('builtins.open') as bob:
         a.create_sync_src_info_file()
     bob.assert_called_once_with('/var/cache/bind/juju-zone-src-unit_1',
                                 'w+')
 def test_wget_file(self):
     # retry_on_exception patched out in __init__.py
     self.patch(designate_bind.subprocess, 'check_call')
     a = designate_bind.DesignateBindCharm()
     a.wget_file('http://ip1/tarfile.tar', '/tmp')
     self.check_call.assert_called_once_with([
         'wget', 'http://ip1/tarfile.tar', '--retry-connrefused', '-t', '10'
     ],
                                             cwd='/tmp')
 def test_request_sync(self):
     self.patch(designate_bind.time, 'time')
     relation = mock.MagicMock()
     self.patch(designate_bind.reactive, 'set_state')
     self.time.return_value = 100
     a = designate_bind.DesignateBindCharm()
     a.request_sync(relation)
     relation.send_all.assert_called_once_with({'sync_request': '100'},
                                               store_local=True)
     self.set_state.assert_called_once_with('sync.request.sent')
 def test_setup_sync_dir(self):
     self.patch(designate_bind.os, 'mkdir')
     self.patch(designate_bind.os, 'chmod')
     a = designate_bind.DesignateBindCharm()
     a.setup_sync_dir('100')
     self.mkdir.assert_called_once_with('/var/www/html/zone-syncs', 493)
     self.assertFalse(self.chmod.called)
     # Test dir does not exist
     self.mkdir.side_effect = FileExistsError
     a.setup_sync_dir('100')
     self.chmod.assert_called_once_with('/var/www/html/zone-syncs', 493)
 def test_generate_rndc_key(self):
     hmac_mock = mock.MagicMock()
     self.patch(designate_bind.os, 'urandom', return_value='seed')
     self.patch(designate_bind.hmac, 'new', return_value=hmac_mock)
     self.patch(designate_bind.base64, 'b64encode', return_value=hmac_mock)
     self.patch_object(designate_bind.hashlib, 'md5', new='md5lib')
     a = designate_bind.DesignateBindCharm()
     a.generate_rndc_key()
     self.new.assert_called_once_with('seed',
                                      digestmod='md5lib',
                                      msg=b'RNDC Secret')
 def test_set_apparmor(self):
     self.patch(designate_bind.os.path, 'isfile')
     a = designate_bind.DesignateBindCharm()
     self.isfile.return_value = True
     with mock.patch('builtins.open') as bob:
         a.set_apparmor()
     self.assertFalse(bob.called)
     self.isfile.return_value = False
     with mock.patch('builtins.open') as bob:
         a.set_apparmor()
     bob.assert_called_once_with('/etc/apparmor.d/disable/usr.sbin.named',
                                 'w')
 def test_retrieve_zones_cluster_relation_nourl(self):
     relation = mock.MagicMock()
     self.patch(designate_bind.DesignateBindCharm, 'get_sync_time')
     self.patch(designate_bind.DesignateBindCharm, 'get_sync_src')
     self.patch_object(designate_bind.DesignateBindCharm, 'wget_file')
     self.patch(designate_bind.hookenv, 'log')
     self.get_sync_src.return_value = None
     relation.retrieve_local.return_value = ['10']
     self.get_sync_time.return_value = '20'
     a = designate_bind.DesignateBindCharm()
     a.retrieve_zones(relation)
     self.assertFalse(self.wget_file.called)
 def test_set_sync_info(self):
     self.patch(designate_bind.hookenv, 'leader_set')
     self.patch(designate_bind.hookenv, 'unit_private_ip')
     self.unit_private_ip.return_value = 'ip1'
     a = designate_bind.DesignateBindCharm()
     a.set_sync_info('20', '/tmp/tarball.tar')
     self.leader_set.assert_called_once_with({
         'sync_time':
         '20',
         'sync_src':
         'http://ip1:80/zone-syncs//tmp/tarball.tar'
     })
 def test_create_zone_tarball(self):
     self.patch(designate_bind.glob, 'glob')
     self.patch(designate_bind.subprocess, 'check_call')
     _files = {
         '/var/cache/bind/juju*': ['jujufile1'],
         '/var/cache/bind/slave*': ['slavefile1'],
         '/var/cache/bind/*nzf': ['nsffile']
     }
     self.glob.side_effect = lambda x: _files[x]
     a = designate_bind.DesignateBindCharm()
     a.create_zone_tarball('/tmp/tarball.tar')
     self.check_call.assert_called_once_with([
         'tar', 'zcvf', '/tmp/tarball.tar', 'jujufile1', 'slavefile1',
         'nsffile'
     ],
                                             cwd='/var/cache/bind')
 def test_init_rndckey(self):
     self.patch(designate_bind.hookenv, 'log')
     self.patch(designate_bind.DesignateBindCharm, 'get_rndc_secret')
     self.patch(designate_bind.DesignateBindCharm, 'generate_rndc_key')
     self.patch(designate_bind.hookenv, 'leader_set')
     self.patch(designate_bind.hookenv, 'is_leader')
     a = designate_bind.DesignateBindCharm()
     # Test secret already stored
     self.get_rndc_secret.return_value = 'mysecret'
     self.assertEqual(a.init_rndckey(), 'mysecret')
     # Test need new secret (Leader)
     self.get_rndc_secret.return_value = None
     self.generate_rndc_key.return_value = 'newsecret'
     self.is_leader.return_value = True
     self.assertEqual(a.init_rndckey(), 'newsecret')
     self.leader_set.assert_called_once_with({'rndc_key': 'newsecret'})
     # Test need new secret (Not Leader)
     self.get_rndc_secret.return_value = None
     self.is_leader.return_value = False
     self.assertEqual(a.init_rndckey(), None)
 def test_setup_sync(self):
     self.patch(designate_bind.hookenv, 'log')
     self.patch(designate_bind.DesignateBindCharm, 'setup_sync_dir')
     self.patch(designate_bind.time, 'time')
     self.patch(designate_bind.DesignateBindCharm,
                'create_sync_src_info_file')
     self.patch(designate_bind.DesignateBindCharm, 'service_control')
     self.patch(designate_bind.DesignateBindCharm, 'create_zone_tarball')
     self.patch(designate_bind.DesignateBindCharm, 'set_sync_info')
     self.setup_sync_dir.return_value = '/tmp/zonefiles'
     self.time.return_value = 100
     a = designate_bind.DesignateBindCharm()
     a.setup_sync()
     self.setup_sync_dir.assert_called_once_with('100')
     self.create_sync_src_info_file.assert_called_once_with()
     ctrl_calls = [
         mock.call('stop', ['bind9']),
         mock.call('start', ['bind9'])
     ]
     self.service_control.assert_has_calls(ctrl_calls)
     self.create_zone_tarball.assert_called_once_with(
         '/tmp/zonefiles/100.tar.gz')
     self.set_sync_info.assert_called_once_with('100', '100.tar.gz')
 def test_process_requests(self):
     hacluster = mock.MagicMock()
     self.patch(designate_bind.hookenv, 'log')
     self.patch(designate_bind.DesignateBindCharm, 'setup_sync')
     self.patch(designate_bind.DesignateBindCharm, 'get_sync_time')
     a = designate_bind.DesignateBindCharm()
     # No queued requests
     hacluster.retrieve_remote.return_value = []
     self.get_sync_time.return_value = 20
     a.process_requests(hacluster)
     self.assertFalse(self.setup_sync.called)
     # No request since last sync
     self.setup_sync.reset_mock()
     hacluster.retrieve_remote.return_value = ['10']
     self.get_sync_time.return_value = 20
     a.process_requests(hacluster)
     self.assertFalse(self.setup_sync.called)
     # New request present
     self.setup_sync.reset_mock()
     hacluster.retrieve_remote.return_value = ['10', '30']
     self.get_sync_time.return_value = 20
     a.process_requests(hacluster)
     self.assertTrue(self.setup_sync.called)
 def test_service_control(self):
     self.patch(designate_bind.host, 'service_stop')
     a = designate_bind.DesignateBindCharm()
     a.service_control('stop', ['svc1', 'svc2'])
     ctrl_calls = [mock.call('svc1'), mock.call('svc2')]
     self.service_stop.assert_has_calls(ctrl_calls)