예제 #1
0
    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
예제 #2
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()

        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]
예제 #4
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',
         },
     }]
예제 #6
0
    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, '', '')
예제 #7
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()
예제 #8
0
 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
예제 #10
0
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"
예제 #15
0
    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
예제 #16
0
    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')
예제 #17
0
    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
예제 #19
0
    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'] == ''
예제 #20
0
    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!'
예제 #21
0
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']
예제 #22
0
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'
예제 #23
0
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'
                    ]
예제 #24
0
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'
예제 #25
0
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'],
        }