def setUp(self): """ mocking up """ super(TestPFSenseLookup, self).setUp() self.build_definitions() # self.fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'pfsense.yaml') self.mock_get_hostname = patch('ansible_collections.pfsensible.core.plugins.lookup.pfsense.LookupModule.get_hostname') get_hostname = self.mock_get_hostname.start() get_hostname.return_value = ('pf_test1') self.mock_get_definitions = patch('ansible_collections.pfsensible.core.plugins.lookup.pfsense.LookupModule.get_definitions') self.get_definitions = self.mock_get_definitions.start() self.get_definitions.return_value = self.definitions
def setUp(self): """ mocking up """ super(TestPFSenseSetupModule, self).setUp() self.mock_validate_webguicss = patch( 'ansible_collections.pfsensible.core.plugins.modules.pfsense_setup.PFSenseSetupModule._validate_webguicss' ) self.validate_webguicss = self.mock_validate_webguicss.start() self.mock_run_command = patch( 'ansible.module_utils.basic.AnsibleModule.run_command') self.run_command = self.mock_run_command.start() self.run_command.return_value = (0, '', '')
def test_get_single(self): open_url = OpenUrlProxy([ OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), expect_value([ lxmletree.QName('https://ns1.hosttech.eu/public/api', 'getZone').text, 'sZoneName' ], 'example.com', ('http://www.w3.org/2001/XMLSchema', 'string')), ])).result_str(DEFAULT_ZONE_RESULT), ]) with patch( 'ansible_collections.felixfontein.hosttech_dns.plugins.module_utils.wsdl.open_url', open_url): with pytest.raises(AnsibleExitJson) as e: set_module_args({ 'hosttech_username': '******', 'hosttech_password': '******', 'zone': 'example.com', 'record': 'example.com', 'type': 'A', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }) hosttech_dns_record_info.main() print(e.value.args[0]) assert e.value.args[0]['changed'] is False assert 'set' in e.value.args[0] assert e.value.args[0]['set']['record'] == 'example.com' assert e.value.args[0]['set']['ttl'] == 3600 assert e.value.args[0]['set']['type'] == 'A' assert e.value.args[0]['set']['value'] == ['1.2.3.4'] assert 'sets' not in e.value.args[0]
def test_timeout_failure(): resolver = mock_resolver(['1.1.1.1'], {}) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'raise': dns.exception.Timeout(timeout=1), }, { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'raise': dns.exception.Timeout(timeout=2), }, { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'raise': dns.exception.Timeout(timeout=3), }, { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'raise': dns.exception.Timeout(timeout=4), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): with pytest.raises(dns.exception.Timeout) as exc: resolver = ResolveDirectlyFromNameServers() resolver.resolve_nameservers('example.com') assert exc.value.kwargs['timeout'] == 4
def test_get_single_txt_quoted(self, mocker): with patch('time.sleep', mock_sleep): result = self.run_module_success( mocker, hetzner_dns_record_info, { 'hetzner_token': 'foo', 'zone_name': 'example.com', 'prefix': 'foo', 'type': 'TXT', 'txt_transformation': 'quoted', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }, [ FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Retry-After', '5').result_str(''), FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Retry-After', '10').result_str(''), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Content-Type', 'application/json'). result_json(HETZNER_JSON_ZONE_LIST_RESULT), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/records', without_query=True).expect_query_values( 'zone_id', '42').expect_query_values( 'page', '1').expect_query_values( 'per_page', '100').return_header( 'Content-Type', 'application/json'). result_json(HETZNER_JSON_ZONE_RECORDS_GET_RESULT), ]) assert result['changed'] is False assert result['zone_id'] == '42' assert result['records'] == [{ 'record': 'foo.example.com', 'prefix': 'foo', 'ttl': None, 'type': 'TXT', 'value': u'"b\\303\\244r \\"with quotes\\" (use \\\\ to escape)"', 'extra': { 'created': '2021-07-09T11:18:37Z', 'modified': '2021-07-09T11:18:37Z', }, }]
def setUp(self): """ mocking up """ super(TestPFSenseRouteModule, self).setUp() self.mock_run_command = patch( 'ansible.module_utils.basic.AnsibleModule.run_command') self.run_command = self.mock_run_command.start() self.run_command.return_value = (0, '', '')
def setUp(self): """ mocking up """ super(TestPFSenseSetupModule, self).setUp() self.mock_validate_webguicss = patch( 'ansible_collections.pfsensible.core.plugins.modules.pfsense_setup.PFSenseSetupModule._validate_webguicss' ) self.validate_webguicss = self.mock_validate_webguicss.start()
def setUp(self): self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json) self.mock_module.start() self.mock_sleep = patch('time.sleep') self.mock_sleep.start() set_module_args({}) self.addCleanup(self.mock_module.stop) self.addCleanup(self.mock_sleep.stop)
def test_get_single(self, mocker): with patch('time.sleep', mock_sleep): result = self.run_module_success( mocker, hetzner_dns_record_set_info, { 'hetzner_token': 'foo', 'zone_name': 'example.com', 'record': 'example.com', 'type': 'A', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }, [ FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Retry-After', '5').result_str(''), FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Retry-After', '10').result_str(''), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Content-Type', 'application/json'). result_json(HETZNER_JSON_ZONE_LIST_RESULT), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/records', without_query=True).expect_query_values( 'zone_id', '42').expect_query_values( 'page', '1').expect_query_values( 'per_page', '100').return_header( 'Content-Type', 'application/json'). result_json(HETZNER_JSON_ZONE_RECORDS_GET_RESULT), ]) assert result['changed'] is False assert result['zone_id'] == '42' assert 'set' in result assert result['set']['record'] == 'example.com' assert result['set']['prefix'] == '' assert result['set']['ttl'] == 3600 assert result['set']['type'] == 'A' assert result['set']['value'] == ['1.2.3.4'] assert 'sets' not in result
def test_error_servfail(): resolver = mock_resolver(['1.1.1.1'], {}) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.SERVFAIL), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): with pytest.raises(ResolverError) as exc: resolver = ResolveDirectlyFromNameServers() resolver.resolve_nameservers('example.com') assert exc.value.args[0] == 'Error SERVFAIL'
def test_get_single(self, mocker): with patch('time.sleep', mock_sleep): result = self.run_module_success( mocker, hosttech_dns_record_info, { 'hosttech_token': 'foo', 'zone_name': 'example.com', 'record': 'example.com', 'type': 'A', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }, [ FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'authorization', 'Bearer foo'). expect_url('https://api.ns1.hosttech.eu/api/user/v1/zones', without_query=True).expect_query_values( 'query', 'example.com').return_header( 'Retry-After', '5').result_str(''), FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'authorization', 'Bearer foo'). expect_url('https://api.ns1.hosttech.eu/api/user/v1/zones', without_query=True).expect_query_values( 'query', 'example.com').return_header( 'Retry-After', '10').result_str(''), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json' ).expect_header('authorization', 'Bearer foo').expect_url( 'https://api.ns1.hosttech.eu/api/user/v1/zones', without_query=True).expect_query_values( 'query', 'example.com').return_header( 'Content-Type', 'application/json' ).result_json(HOSTTECH_JSON_ZONE_LIST_RESULT), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json' ).expect_header('authorization', 'Bearer foo').expect_url( 'https://api.ns1.hosttech.eu/api/user/v1/zones/42'). return_header('Content-Type', 'application/json' ).result_json(HOSTTECH_JSON_ZONE_GET_RESULT), ]) assert result['changed'] is False assert result['zone_id'] == 42 assert len(result['records']) == 1 assert result['records'][0] == { 'record': 'example.com', 'prefix': '', 'ttl': 3600, 'type': 'A', 'value': '1.2.3.4', 'extra': { 'comment': '', }, }
def test_too_many_retries(self, mocker): sleep_values = [5, 10, 1, 1, 1, 60, 10, 1, 10, 3.1415] def sleep_check(delay): expected = sleep_values.pop(0) assert delay == expected with patch('time.sleep', sleep_check): result = self.run_module_failed( mocker, hetzner_dns_record_set_info, { 'hetzner_token': 'foo', 'zone_name': 'example.com', 'record': 'example.com', 'type': 'A', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }, [ FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Retry-After', '5').result_str(''), FetchUrlCall('GET', 429).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Retry-After', '10').result_str(''), FetchUrlCall('GET', 429).return_header('Retry-After', '1').result_str(''), FetchUrlCall('GET', 429).return_header('Retry-After', '0').result_str(''), FetchUrlCall('GET', 429).return_header( 'Retry-After', '-1').result_str(''), FetchUrlCall('GET', 429).return_header( 'Retry-After', '61').result_str(''), FetchUrlCall('GET', 429).return_header( 'Retry-After', 'foo').result_str(''), FetchUrlCall('GET', 429).return_header( 'Retry-After', '0.9').result_str(''), FetchUrlCall('GET', 429).result_str(''), FetchUrlCall('GET', 429).return_header( 'Retry-After', '3.1415').result_str(''), FetchUrlCall('GET', 429).return_header( 'Retry-After', '42').result_str(''), ]) print(sleep_values) assert result[ 'msg'] == 'Error: Stopping after 10 failed retries with 429 Too Many Attempts' assert len(sleep_values) == 0
def test_conversion_error(self, mocker): with patch('time.sleep', mock_sleep): result = self.run_module_failed( mocker, hetzner_dns_record_set_info, { 'hetzner_token': 'foo', 'zone_name': 'example.com', 'record': 'example.com', 'type': 'TXT', 'txt_transformation': 'quoted', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }, [ FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/zones', without_query=True).expect_query_values( 'name', 'example.com').return_header( 'Content-Type', 'application/json'). result_json(HETZNER_JSON_ZONE_LIST_RESULT), FetchUrlCall('GET', 200).expect_header( 'accept', 'application/json').expect_header( 'auth-api-token', 'foo').expect_url( 'https://dns.hetzner.com/api/v1/records', without_query=True).expect_query_values( 'zone_id', '42').expect_query_values( 'page', '1'). expect_query_values('per_page', '100').return_header( 'Content-Type', 'application/json').result_json({ 'records': [ { 'id': '201', 'type': 'TXT', 'name': '@', 'value': u'"hellö', 'zone_id': '42', 'created': '2021-07-09T11:18:37Z', 'modified': '2021-07-09T11:18:37Z', }, ] }), ]) assert result['msg'] == ( 'Error while converting DNS values: While processing record from API: Missing double quotation mark at the end of value' )
def test_change_modify_list_fail(self): open_url = OpenUrlProxy([ OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), expect_value([ lxmletree.QName('https://ns1.hosttech.eu/public/api', 'getZone').text, 'sZoneName' ], 'example.com', ('http://www.w3.org/2001/XMLSchema', 'string')), ])).result_str(DEFAULT_ZONE_RESULT), ]) with patch( 'ansible_collections.felixfontein.hosttech_dns.plugins.module_utils.wsdl.open_url', open_url): with pytest.raises(AnsibleFailJson) as e: set_module_args({ 'hosttech_username': '******', 'hosttech_password': '******', 'state': 'present', 'zone': 'example.com', 'record': 'example.com', 'type': 'NS', 'ttl': 10800, 'value': [ 'ns1.hostserv.eu', 'ns4.hostserv.eu', ], '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }) hosttech_dns_record.main() print(e.value.args[0]) assert e.value.args[0]['failed'] is True assert e.value.args[0][ 'msg'] == "Record already exists with different value. Set 'overwrite' to replace it"
def setUp(self): """ mocking up """ super(TestPFSenseModule, self).setUp() self.mock_parse = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.ET.parse' ) self.parse = self.mock_parse.start() self.mock_shutil_move = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.shutil.move' ) self.shutil_move = self.mock_shutil_move.start() self.mock_php = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.PFSenseModule.php' ) self.php = self.mock_php.start() self.php.return_value = ['vmx0', 'vmx1', 'vmx2', 'vmx3'] self.mock_phpshell = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.PFSenseModule.phpshell' ) self.phpshell = self.mock_phpshell.start() self.phpshell.return_value = (0, '', '') self.mock_mkstemp = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.mkstemp' ) self.mkstemp = self.mock_mkstemp.start() self.mkstemp.return_value = mkstemp() self.tmp_file = self.mkstemp.return_value[1] self.mock_chmod = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.os.chmod' ) self.chmod = self.mock_chmod.start() self.mock_get_version = patch( 'ansible_collections.pfsensible.core.plugins.module_utils.pfsense.PFSenseModule.get_version' ) self.get_version = self.mock_get_version.start() self.get_version.return_value = "2.5.0" self.maxDiff = None
def test_basic(self): open_url = OpenUrlProxy([ OpenUrlCall( 'GET', 200).result_str('hello').expect_form_value_absent('foo'). expect_header_unset('foo').expect_url('http://example.com'), ]) with patch( 'ansible_collections.community.internal_test_tools.plugins.lookup.open_url_test_lookup.open_url', open_url): result = self.lookup.run( ['http://example.com'], [], ) open_url.assert_is_done() assert len(result) == 1 assert result[0]['status'] == 200 assert result[0]['content'] == base64.b64encode( 'hello'.encode('utf-8')).decode('utf-8')
def test_error_in_test(self): open_url = OpenUrlProxy([ OpenUrlCall('GET', 204).expect_url( 'http://example.com#asdf', without_query=True).expect_query_values('foo', 'bar', 'baz'), ]) with patch( 'ansible_collections.community.internal_test_tools.plugins.lookup.open_url_test_lookup.open_url', open_url): with pytest.raises(AnsibleLookupError) as e: self.lookup.run( [ 'http://example.com?foo=bar&foo=baz#asdf', 'http://example.org' ], [], ) open_url.assert_is_done() print(e.value.message) assert e.value.message == 'Error while GETing http://example.com?foo=bar&foo=baz#asdf: OpenUrlCall data has neither body nor error data'
def test_change_add_one(self): new_entry = (131, 42, 'CAA', '', 'test', 3600, None, None) open_url = OpenUrlProxy([ OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), expect_value([ lxmletree.QName('https://ns1.hosttech.eu/public/api', 'getZone').text, 'sZoneName' ], 'example.com', ('http://www.w3.org/2001/XMLSchema', 'string')), ])).result_str(DEFAULT_ZONE_RESULT), OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), validate_add_request('example.com', new_entry), ])).result_str(create_add_result(new_entry)), ]) with patch( 'ansible_collections.felixfontein.hosttech_dns.plugins.module_utils.wsdl.open_url', open_url): with pytest.raises(AnsibleExitJson) as e: set_module_args({ 'hosttech_username': '******', 'hosttech_password': '******', 'state': 'present', 'zone': 'example.com', 'record': 'example.com', 'type': 'CAA', 'ttl': 3600, 'value': [ 'test', ], '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }) hosttech_dns_record.main() print(e.value.args[0]) assert e.value.args[0]['changed'] is True
def test_multiple(self): open_url = OpenUrlProxy([ OpenUrlCall('POST', 200).result_json({ '1': 2 }).return_header( 'content-type', 'application/json').expect_content( 'name=foo&[email protected]'.encode('utf-8')). expect_content_predicate(lambda content: True).expect_header( 'foo', 'bar').expect_header_unset('baz'), OpenUrlCall('POST', 500).result_error('Error!'.encode( 'utf-8')).expect_form_present('name').expect_form_value( 'email', '*****@*****.**').expect_form_value_absent( 'firstname').expect_url('http://example.org'), OpenUrlCall( 'POST', 400).result_error().expect_url('http://example.example'), ]) with patch( 'ansible_collections.community.internal_test_tools.plugins.lookup.open_url_test_lookup.open_url', open_url): result = self.lookup.run( [ 'http://example.com', 'http://example.org', 'http://example.example' ], [], method='POST', headers=dict(foo='bar'), data=base64.b64encode('name=foo&[email protected]'.encode( 'utf-8')).decode('utf-8'), ) open_url.assert_is_done() assert len(result) == 3 assert result[0]['status'] == 200 assert result[1]['status'] == 500 assert result[2]['status'] == 400 assert result[2]['content'] == ''
def test_error(self): open_url = OpenUrlProxy([ OpenUrlCall( 'PUT', 404).exception(lambda: Exception('foo bar!')).expect_header( 'foo', 'bar').expect_header_unset('baz').expect_url( 'http://example.com', without_query=True, without_fragment=True).expect_query_values('foo', ''), ]) with patch( 'ansible_collections.community.internal_test_tools.plugins.lookup.open_url_test_lookup.open_url', open_url): with pytest.raises(AnsibleLookupError) as e: self.lookup.run( ['http://example.com?foo', 'http://example.org'], [], method='PUT', headers=dict(foo='bar'), ) open_url.assert_is_done() print(e.value.message) assert e.value.message == 'Error while PUTing http://example.com?foo: foo bar!'
def test_resolver_non_default(): resolver = mock_resolver( ['1.1.1.1'], { ('1.1.1.1', ): [ { 'target': 'ns.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '2.2.2.2'), )), }, { 'target': 'ns.example.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '3.3.3.3'), )), }, { 'target': 'ns.org', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '2.2.3.3'), )), }, { 'target': 'ns.example.org', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.org', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '4.4.4.4'), )), }, ], ('3.3.3.3', ): [ { 'target': dns.name.from_unicode(u'example.org'), 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'example.org', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '1.2.3.4'), )), }, ], ('4.4.4.4', ): [ { 'target': dns.name.from_unicode(u'example.org'), 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'example.org', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '1.2.3.4'), )), }, ], }) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.com'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '2.2.2.2', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com'), ) ]), }, { 'query_target': dns.name.from_unicode(u'www.example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '3.3.3.3', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'www.example.com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.SOA, 'ns.example.com. ns.example.com. 12345 7200 120 2419200 10800' ), ), dns.rrset.from_rdata( 'www.example.com', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'example.org')) ]), }, { 'query_target': dns.name.from_unicode(u'org'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'org', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.org'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.org'), 'query_type': dns.rdatatype.NS, 'nameserver': '2.2.3.3', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.org', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.org'), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com'), ) ]), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): resolver = ResolveDirectlyFromNameServers( always_ask_default_resolver=False) assert resolver.resolve_nameservers('example.com') == [ 'ns.example.com' ] # www.example.com is a CNAME for example.org rrset_dict = resolver.resolve('www.example.com') assert sorted( rrset_dict.keys()) == ['ns.example.com', 'ns.example.org'] rrset = rrset_dict['ns.example.com'] assert len(rrset) == 1 assert rrset.name == dns.name.from_unicode(u'example.org', origin=None) assert rrset.rdtype == dns.rdatatype.A assert rrset[0].to_text() == u'1.2.3.4' rrset = rrset_dict['ns.example.org'] assert len(rrset) == 1 assert rrset.name == dns.name.from_unicode(u'example.org', origin=None) assert rrset.rdtype == dns.rdatatype.A assert rrset[0].to_text() == u'1.2.3.4' # The following results should be cached: assert resolver.resolve_nameservers('com') == ['ns.com'] print( resolver.resolve_nameservers('example.com', resolve_addresses=True)) assert resolver.resolve_nameservers( 'example.com', resolve_addresses=True) == ['3.3.3.3'] print( resolver.resolve_nameservers('example.org', resolve_addresses=True)) assert resolver.resolve_nameservers( 'example.org', resolve_addresses=True) == ['3.3.3.3', '4.4.4.4']
def test_cname_loop(): resolver = mock_resolver( ['1.1.1.1'], { ('1.1.1.1', ): [ { 'target': 'ns.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '2.2.2.2'), )), }, { 'target': 'ns.example.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '3.3.3.3'), )), }, { 'target': 'ns.org', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '2.2.3.3'), )), }, { 'target': 'ns.example.org', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.org', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '4.4.4.4'), )), }, ], }) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.com'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com'), ) ]), }, { 'query_target': dns.name.from_unicode(u'www.example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'www.example.com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.SOA, 'ns.example.com. ns.example.com. 12345 7200 120 2419200 10800' ), ), dns.rrset.from_rdata( 'www.example.com', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'example.org')) ]), }, { 'query_target': dns.name.from_unicode(u'org'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'org', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.org'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.org'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.org', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.org'), ), dns.rrset.from_rdata( 'example.org', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'www.example.com')) ]), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): resolver = ResolveDirectlyFromNameServers() with pytest.raises(ResolverError) as exc: resolver.resolve('www.example.com') assert exc.value.args[ 0] == 'Found CNAME loop starting at www.example.com'
def test_no_response(): fake_query = MagicMock() fake_query.question = 'Doctor Who?' resolver = mock_resolver( ['1.1.1.1'], { ('1.1.1.1', ): [ { 'target': 'ns.example.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '3.3.3.3'), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '5.5.5.5'), )), }, { 'target': 'ns2.example.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '4.4.4.4'), )), }, ], ('3.3.3.3', '5.5.5.5'): [ { 'target': dns.name.from_unicode(u'example.com'), 'lifetime': 10, 'result': create_mock_answer(), }, ], ('4.4.4.4', ): [ { 'target': dns.name.from_unicode(u'example.com'), 'lifetime': 10, 'raise': dns.resolver.NoAnswer(response=fake_query), }, ], }) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.com'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.com', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com'), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2.example.com'), ) ]), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): resolver = ResolveDirectlyFromNameServers() rrset_dict = resolver.resolve('example.com') assert sorted(rrset_dict.keys()) == [ 'ns.example.com', 'ns2.example.com' ] assert rrset_dict['ns.example.com'] is None assert rrset_dict['ns2.example.com'] is None # Verify nameserver IPs assert resolver.resolve_nameservers('example.com') == [ 'ns.example.com', 'ns2.example.com' ] assert resolver.resolve_nameservers( 'example.com', resolve_addresses=True) == [ '3.3.3.3', '4.4.4.4', '5.5.5.5' ]
def test_lookup_ns_names(): resolver = mock_resolver(['1.1.1.1'], {}) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.com', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.org.'), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com.'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '3.3.3.3', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response( dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'example.com', 60, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'foo.bar.'), ) ], authority=[ dns.rrset.from_rdata( 'example.com', 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com.'), ) ]), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): resolver = ResolveDirectlyFromNameServers( always_ask_default_resolver=False) # Use default resolver ns, cname = resolver._lookup_ns_names( dns.name.from_unicode(u'example.com')) assert ns == ['ns.example.com.', 'ns.example.org.'] assert cname is None # Provide nameserver IPs ns, cname = resolver._lookup_ns_names( dns.name.from_unicode(u'example.com'), nameserver_ips=['3.3.3.3', '1.1.1.1']) assert ns == ['ns.example.com.'] assert cname == dns.name.from_unicode(u'foo.bar.') # Provide empty nameserver list with pytest.raises(ResolverError) as exc: resolver._lookup_ns_names( dns.name.from_unicode(u'example.com'), nameservers=[]) assert exc.value.args[ 0] == 'Have neither nameservers nor nameserver IPs'
def test_timeout_handling(): resolver = mock_resolver( ['1.1.1.1'], { ('1.1.1.1', ): [ { 'target': 'ns.example.com', 'lifetime': 10, 'raise': dns.exception.Timeout(timeout=10), }, { 'target': 'ns.example.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.example.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '3.3.3.3'), )), }, { 'target': 'ns.com', 'lifetime': 10, 'raise': dns.exception.Timeout(timeout=10), }, { 'target': 'ns.com', 'lifetime': 10, 'raise': dns.exception.Timeout(timeout=10), }, { 'target': 'ns.com', 'lifetime': 10, 'result': create_mock_answer( dns.rrset.from_rdata( 'ns.com', 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '2.2.2.2'), )), }, ], }) udp_sequence = [ { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'raise': dns.exception.Timeout(timeout=10), }, { 'query_target': dns.name.from_unicode(u'com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, answer=[ dns.rrset.from_rdata( 'com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.com'), ) ]), }, { 'query_target': dns.name.from_unicode(u'example.com'), 'query_type': dns.rdatatype.NS, 'nameserver': '1.1.1.1', 'kwargs': { 'timeout': 10, }, 'result': create_mock_response(dns.rcode.NOERROR, authority=[ dns.rrset.from_rdata( 'example.com', 3600, dns.rdata.from_text( dns.rdataclass.IN, dns.rdatatype.NS, 'ns.example.com'), ) ]), }, ] with patch('dns.resolver.get_default_resolver', resolver): with patch('dns.resolver.Resolver', resolver): with patch('dns.query.udp', mock_query_udp(udp_sequence)): resolver = ResolveDirectlyFromNameServers() assert resolver.resolve_nameservers( 'example.com', resolve_addresses=True) == ['3.3.3.3'] # The following results should be cached: assert resolver.resolve_nameservers('com') == ['ns.com'] assert resolver.resolve_nameservers( 'com', resolve_addresses=True) == ['2.2.2.2'] assert resolver.resolve_nameservers('example.com') == [ 'ns.example.com' ] assert resolver.resolve_nameservers( 'example.com', resolve_addresses=True) == ['3.3.3.3']
def test_get_all(self): open_url = OpenUrlProxy([ OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), expect_value([ lxmletree.QName('https://ns1.hosttech.eu/public/api', 'getZone').text, 'sZoneName' ], 'example.com', ('http://www.w3.org/2001/XMLSchema', 'string')), ])).result_str(DEFAULT_ZONE_RESULT), ]) with patch( 'ansible_collections.felixfontein.hosttech_dns.plugins.module_utils.wsdl.open_url', open_url): with pytest.raises(AnsibleExitJson) as e: set_module_args({ 'hosttech_username': '******', 'hosttech_password': '******', 'what': 'all_records', 'zone': 'example.com.', '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }) hosttech_dns_record_info.main() print(e.value.args[0]) assert e.value.args[0]['changed'] is False assert 'set' not in e.value.args[0] assert 'sets' in e.value.args[0] sets = e.value.args[0]['sets'] assert len(sets) == 6 assert sets[0] == { 'record': '*.example.com', 'ttl': 3600, 'type': 'A', 'value': ['1.2.3.5'], } assert sets[1] == { 'record': '*.example.com', 'ttl': 3600, 'type': 'AAAA', 'value': ['2001:1:2::4'], } assert sets[2] == { 'record': 'example.com', 'ttl': 3600, 'type': 'A', 'value': ['1.2.3.4'], } assert sets[3] == { 'record': 'example.com', 'ttl': 3600, 'type': 'AAAA', 'value': ['2001:1:2::3'], } assert sets[4] == { 'record': 'example.com', 'ttl': 3600, 'type': 'MX', 'value': ['example.com'], } assert sets[5] == { 'record': 'example.com', 'ttl': 10800, 'type': 'NS', 'value': ['ns3.hostserv.eu', 'ns2.hostserv.eu', 'ns1.hostserv.eu'], }
def test_change_modify_list(self): del_entry = (130, 42, 'NS', '', 'ns3.hostserv.eu', 10800, None, None) update_entry = (131, 42, 'NS', '', 'ns4.hostserv.eu', 10800, None, None) open_url = OpenUrlProxy([ OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), expect_value([ lxmletree.QName('https://ns1.hosttech.eu/public/api', 'getZone').text, 'sZoneName' ], 'example.com', ('http://www.w3.org/2001/XMLSchema', 'string')), ])).result_str(DEFAULT_ZONE_RESULT), OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), validate_del_request(del_entry), ])).result_str(create_del_result(True)), OpenUrlCall('POST', 200).expect_content_predicate( validate_wsdl_call([ expect_authentication('foo', 'bar'), validate_update_request(update_entry), ])).result_str(create_update_result(update_entry)), ]) with patch( 'ansible_collections.felixfontein.hosttech_dns.plugins.module_utils.wsdl.open_url', open_url): with pytest.raises(AnsibleExitJson) as e: set_module_args({ 'hosttech_username': '******', 'hosttech_password': '******', 'state': 'present', 'zone': 'example.com', 'record': 'example.com', 'type': 'NS', 'ttl': 10800, 'value': [ 'ns1.hostserv.eu', 'ns4.hostserv.eu', ], 'overwrite': True, '_ansible_diff': True, '_ansible_remote_tmp': '/tmp/tmp', '_ansible_keep_remote_files': True, }) hosttech_dns_record.main() print(e.value.args[0]) assert e.value.args[0]['changed'] is True assert 'diff' in e.value.args[0] assert 'before' in e.value.args[0]['diff'] assert 'after' in e.value.args[0]['diff'] assert e.value.args[0]['diff']['before'] == { 'record': 'example.com', 'type': 'NS', 'ttl': 10800, 'value': ['ns1.hostserv.eu', 'ns2.hostserv.eu', 'ns3.hostserv.eu'], } assert e.value.args[0]['diff']['after'] == { 'record': 'example.com', 'type': 'NS', 'ttl': 10800, 'value': ['ns1.hostserv.eu', 'ns4.hostserv.eu'], }