def test_get_single_prefix(self, mocker):
     result = self.run_module_success(
         mocker, hosttech_dns_record_set_info, {
             'hosttech_token': 'foo',
             'zone_name': 'example.com',
             'prefix': '*',
             'type': 'A',
             '_ansible_remote_tmp': '/tmp/tmp',
             '_ansible_keep_remote_files': True,
         }, [
             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 '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.5']
     assert 'sets' not in result
    def test_idempotency_absent_record(self, mocker):
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_token': 'foo',
                'state': 'absent',
                'zone_name': 'example.com.',
                'record': 'somewhere.example.com.',
                'type': 'A',
                'ttl': 3600,
                'value': '1.2.3.6',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                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 'warnings' not in result
예제 #3
0
    def test_change_add_one_check_mode(self, mocker):
        result = self.run_module_success(
            mocker, hetzner_dns_record, {
                'hetzner_token': 'foo',
                'state': 'present',
                'zone_id': '42',
                'record': 'example.com',
                'type': 'CAA',
                'ttl': 3600,
                'value': '0 issue "letsencrypt.org"',
                '_ansible_check_mode': True,
                '_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/42').return_header(
                        'Content-Type', 'application/json').result_json(
                            HETZNER_JSON_ZONE_GET_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 True
        assert result['zone_id'] == '42'
예제 #4
0
 def test_unrouted_to_routed(self, mocker):
     result = self.run_module_success(mocker, hetzner_failover_ip, {
         'hetzner_user': '',
         'hetzner_password': '',
         'failover_ip': '1.2.3.4',
         'state': 'routed',
         'value': '4.3.2.1',
     }, [
         FetchUrlCall('GET', 200)
         .result_json({
             'failover': {
                 'ip': '1.2.3.4',
                 'netmask': '255.255.255.255',
                 'server_ip': '2.3.4.5',
                 'server_number': 2345,
                 'active_server_ip': None,
             },
         })
         .expect_url('{0}/failover/1.2.3.4'.format(BASE_URL)),
         FetchUrlCall('POST', 200)
         .result_json({
             'failover': {
                 'ip': '1.2.3.4',
                 'netmask': '255.255.255.255',
                 'server_ip': '2.3.4.5',
                 'server_number': 2345,
                 'active_server_ip': '4.3.2.1',
             },
         })
         .expect_form_value('active_server_ip', '4.3.2.1')
         .expect_url('{0}/failover/1.2.3.4'.format(BASE_URL)),
     ])
     assert result['changed'] is True
     assert result['value'] == '4.3.2.1'
     assert result['state'] == 'routed'
    def test_absent(self, mocker):
        record = HOSTTECH_WSDL_DEFAULT_ENTRIES[0]
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_username': '******',
                'hosttech_password': '******',
                'state': 'absent',
                'zone_name': 'example.com',
                'record': record[3] + 'example.com',
                'type': record[2],
                'value': record[4],
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('POST', 200).expect_content_predicate(
                    validate_wsdl_call([
                        expect_wsdl_authentication('foo', 'bar'),
                        expect_wsdl_value(
                            [
                                lxml.etree.QName(
                                    'https://ns1.hosttech.eu/public/api',
                                    'getZone').text, 'sZoneName'
                            ], 'example.com',
                            ('http://www.w3.org/2001/XMLSchema', 'string')),
                    ])).result_str(HOSTTECH_WSDL_DEFAULT_ZONE_RESULT),
                FetchUrlCall('POST', 200).expect_content_predicate(
                    validate_wsdl_call([
                        expect_wsdl_authentication('foo', 'bar'),
                        validate_wsdl_del_request(record),
                    ])).result_str(create_wsdl_del_result(True)),
            ])

        assert result['changed'] is True
        assert result['zone_id'] == 42
예제 #6
0
    def test_idempotency_absent_record(self, mocker):
        result = self.run_module_success(
            mocker, hetzner_dns_record, {
                'hetzner_token': 'foo',
                'state': 'absent',
                'zone_name': 'example.com.',
                'record': 'somewhere.example.com.',
                'type': 'A',
                'ttl': 3600,
                'value': '1.2.3.6',
                '_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(HETZNER_JSON_ZONE_RECORDS_GET_RESULT),
            ])

        assert result['changed'] is False
        assert result['zone_id'] == '42'
 def test_get(self, mocker):
     result = self.run_module_success(mocker, hosttech_dns_zone_info, {
         'hosttech_token': 'foo',
         'zone_name': 'example.com',
         '_ansible_remote_tmp': '/tmp/tmp',
         '_ansible_keep_remote_files': True,
     }, [
         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 result['zone_name'] == 'example.com'
     assert result['zone_info'] == {
         'email': '*****@*****.**',
         'ttl': 10800,
         'dnssec': False,
         'dnssec_email': None,
         'ds_records': None,
     }
    def test_absent_check(self, mocker):
        record = HOSTTECH_JSON_DEFAULT_ENTRIES[0]
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_token': 'foo',
                'state': 'absent',
                'zone_name': 'example.com',
                'record': record['name'] + 'example.com',
                'type': record['type'],
                'value': record['ipv4'],
                '_ansible_check_mode': True,
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                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 True
        assert result['zone_id'] == 42
 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 test_get_all_for_one_record_prefix(self, mocker):
     result = self.run_module_success(
         mocker, hosttech_dns_record_set_info, {
             'hosttech_token': 'foo',
             'what': 'all_types_for_record',
             'zone_name': 'example.com.',
             'prefix': '',
             '_ansible_remote_tmp': '/tmp/tmp',
             '_ansible_keep_remote_files': True,
         }, [
             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 'set' not in result
     assert 'sets' in result
     sets = result['sets']
     assert len(sets) == 4
     assert sets[0] == {
         'record': 'example.com',
         'prefix': '',
         'ttl': 3600,
         'type': 'A',
         'value': ['1.2.3.4'],
     }
     assert sets[1] == {
         'record': 'example.com',
         'prefix': '',
         'ttl': 3600,
         'type': 'AAAA',
         'value': ['2001:1:2::3'],
     }
     assert sets[2] == {
         'record': 'example.com',
         'prefix': '',
         'ttl': 3600,
         'type': 'MX',
         'value': ['10 example.com'],
     }
     assert sets[3] == {
         'record': 'example.com',
         'prefix': '',
         'ttl': 10800,
         'type': 'NS',
         'value': ['ns3.hostserv.eu', 'ns2.hostserv.eu', 'ns1.hostserv.eu'],
     }
    def test_change_add_one_idn_prefix(self, mocker):
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_token': 'foo',
                'state': 'present',
                'zone_name': 'example.com',
                'prefix': '☺',
                'type': 'CAA',
                'ttl': 3600,
                'value': '128 issue "letsencrypt.org"',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                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),
                FetchUrlCall('POST', 201).expect_header(
                    'accept', 'application/json'
                ).expect_header('authorization', 'Bearer foo').expect_url(
                    'https://api.ns1.hosttech.eu/api/user/v1/zones/42/records'
                ).expect_json_value_absent(['id']).expect_json_value(
                    ['type'],
                    'CAA').expect_json_value(['ttl'], 3600).expect_json_value(
                        ['comment'], '').expect_json_value(
                            ['name'], 'xn--74h').expect_json_value(
                                ['flag'], '128').expect_json_value(
                                    ['tag'], 'issue').expect_json_value(
                                        ['value'],
                                        'letsencrypt.org').return_header(
                                            'Content-Type',
                                            'application/json').result_json({
                                                'data': {
                                                    'id': 133,
                                                    'type': 'CAA',
                                                    'name': 'xn--74h',
                                                    'flag': '128',
                                                    'tag': 'issue',
                                                    'value': 'letsencrypt.org',
                                                    'ttl': 3600,
                                                    'comment': '',
                                                },
                                            }),
            ])

        assert result['changed'] is True
        assert result['zone_id'] == 42
예제 #12
0
    def test_modify(self, mocker):
        result = self.run_module_success(
            mocker, hetzner_dns_record, {
                'hetzner_token': 'foo',
                'state': 'present',
                'zone_name': 'example.com',
                'record': '*.example.com',
                'type': 'A',
                'ttl': 300,
                'value': '1.2.3.5',
                '_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(HETZNER_JSON_ZONE_RECORDS_GET_RESULT),
                FetchUrlCall('PUT', 200).expect_header(
                    'accept', 'application/json').expect_header(
                        'auth-api-token', 'foo').expect_url(
                            'https://dns.hetzner.com/api/v1/records/126').
                expect_json_value_absent(['id']).expect_json_value(
                    ['type'], 'A').expect_json_value(
                        ['ttl'], 300).expect_json_value(
                            ['zone_id'], '42').expect_json_value(
                                ['name'], '*').expect_json_value(
                                    ['value'], '1.2.3.5').return_header(
                                        'Content-Type',
                                        'application/json').result_json({
                                            'record': {
                                                'id': '126',
                                                'type': 'A',
                                                'name': '*',
                                                'value': '1.2.3.5',
                                                'zone_id': '42',
                                            },
                                        }),
            ])

        assert result['changed'] is True
        assert result['zone_id'] == '42'
 def test_get_all_for_one_record(self, mocker):
     result = self.run_module_success(
         mocker, hetzner_dns_record_info, {
             'hetzner_token': 'foo',
             'what': 'all_types_for_record',
             'zone_name': 'example.com',
             'record': '*.example.com',
             '_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(HETZNER_JSON_ZONE_RECORDS_GET_RESULT),
         ])
     assert result['changed'] is False
     assert result['zone_id'] == '42'
     assert len(result['records']) == 2
     assert result['records'][0] == {
         'record': '*.example.com',
         'prefix': '*',
         'ttl': 3600,
         'type': 'A',
         'value': '1.2.3.5',
         'extra': {
             'created': '2021-07-09T11:18:37Z',
             'modified': '2021-07-09T11:18:37Z',
         },
     }
     assert result['records'][1] == {
         'record': '*.example.com',
         'prefix': '*',
         'ttl': 3600,
         'type': 'AAAA',
         'value': '2001:1:2::4',
         'extra': {
             'created': '2021-07-09T11:18:37Z',
             'modified': '2021-07-09T11:18:37Z',
         },
     }
 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_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_modify(self, mocker):
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_token': 'foo',
                'state': 'present',
                'zone_name': 'example.com',
                'record': '*.example.com',
                'type': 'A',
                'ttl': 300,
                'value': '1.2.3.5',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                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),
                FetchUrlCall('PUT', 200).expect_header(
                    'accept', 'application/json'
                ).expect_header('authorization', 'Bearer foo').expect_url(
                    'https://api.ns1.hosttech.eu/api/user/v1/zones/42/records/126'
                ).expect_json_value_absent(['id']).expect_json_value_absent([
                    'type'
                ]).expect_json_value(['ttl'], 300).expect_json_value(
                    ['name'], '*').expect_json_value(
                        ['ipv4'], '1.2.3.5').return_header(
                            'Content-Type', 'application/json').result_json({
                                'data': {
                                    'id': '126',
                                    'type': 'A',
                                    'name': '*',
                                    'ipv4': '1.2.3.5',
                                    'ttl': 300,
                                    'comment': '',
                                },
                            }),
            ])

        assert result['changed'] is True
        assert result['zone_id'] == 42
예제 #17
0
 def test_wait_get(self, mocker):
     mocker.patch('time.sleep', lambda duration: None)
     result = self.run_module_success(
         mocker, firewall_info, {
             'hetzner_user': '',
             'hetzner_password': '',
             'server_ip': '1.2.3.4',
             'wait_for_configured': True,
         }, [
             FetchUrlCall('GET', 200).result_json({
                 'firewall': {
                     'server_ip': '1.2.3.4',
                     'server_number': 1,
                     'status': 'in process',
                     'whitelist_hos': False,
                     'port': 'main',
                     'rules': {
                         'input': [],
                     },
                 },
             }).expect_url('{0}/firewall/1.2.3.4'.format(BASE_URL)),
             FetchUrlCall('GET', 200).result_json({
                 'firewall': {
                     'server_ip': '1.2.3.4',
                     'server_number': 1,
                     'status': 'in process',
                     'whitelist_hos': False,
                     'port': 'main',
                     'rules': {
                         'input': [],
                     },
                 },
             }).expect_url('{0}/firewall/1.2.3.4'.format(BASE_URL)),
             FetchUrlCall('GET', 200).result_json({
                 'firewall': {
                     'server_ip': '1.2.3.4',
                     'server_number': 1,
                     'status': 'active',
                     'whitelist_hos': False,
                     'port': 'main',
                     'rules': {
                         'input': [],
                     },
                 },
             }).expect_url('{0}/firewall/1.2.3.4'.format(BASE_URL)),
         ])
     assert result['changed'] is False
     assert result['firewall']['status'] == 'active'
     assert result['firewall']['server_ip'] == '1.2.3.4'
     assert result['firewall']['server_number'] == 1
예제 #18
0
    def test_absent(self, mocker):
        record = HETZNER_JSON_DEFAULT_ENTRIES[0]
        result = self.run_module_success(
            mocker, hetzner_dns_record, {
                'hetzner_token':
                'foo',
                'state':
                'absent',
                'zone_name':
                'example.com',
                'record':
                ((record['name'] + '.') if record['name'] != '@' else '') +
                'example.com',
                'type':
                record['type'],
                'value':
                record['value'],
                '_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(HETZNER_JSON_ZONE_RECORDS_GET_RESULT),
                FetchUrlCall('DELETE', 200).expect_header(
                    'accept', 'application/json').expect_header(
                        'auth-api-token', 'foo').expect_url(
                            'https://dns.hetzner.com/api/v1/records/{0}'.
                            format(record['id'])).result_str(''),
            ])

        assert result['changed'] is True
        assert result['zone_id'] == '42'
예제 #19
0
    def test_idempotency_present(self, mocker):
        result = self.run_module_success(
            mocker, hetzner_dns_record, {
                'hetzner_token': 'foo',
                'state': 'present',
                'zone_name': 'example.com',
                'record': 'example.com',
                'type': 'MX',
                'ttl': 3600,
                'value': '10 example.com',
                '_ansible_diff': True,
                '_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(HETZNER_JSON_ZONE_RECORDS_GET_RESULT),
            ])

        assert result['changed'] is False
        assert result['zone_id'] == '42'
        assert result['diff']['before'] == {
            'record': 'example.com',
            'prefix': '',
            'type': 'MX',
            'ttl': 3600,
            'value': '10 example.com',
            'extra': {
                'created': '2021-07-09T11:18:37Z',
                'modified': '2021-07-09T11:18:37Z',
            },
        }
        assert result['diff']['before'] == result['diff']['after']
    def test_get_id(self, mocker):
        result = self.run_module_success(mocker, hosttech_dns_zone_info, {
            'hosttech_username': '******',
            'hosttech_password': '******',
            'zone_id': '42',
            '_ansible_remote_tmp': '/tmp/tmp',
            '_ansible_keep_remote_files': True,
        }, [
            FetchUrlCall('POST', 200)
            .expect_content_predicate(validate_wsdl_call([
                expect_wsdl_authentication('foo', 'bar'),
                expect_wsdl_value(
                    [lxml.etree.QName('https://ns1.hosttech.eu/public/api', 'getZone').text, 'sZoneName'],
                    '42',
                    ('http://www.w3.org/2001/XMLSchema', 'string')
                ),
            ]))
            .result_str(HOSTTECH_WSDL_DEFAULT_ZONE_RESULT),
        ])

        assert result['changed'] is False
        assert result['zone_id'] == 42
        assert result['zone_name'] == 'example.com'
        assert result['zone_info'] == {
            'email': '*****@*****.**',
            'ttl': 10800,
        }
    def test_other_error(self, mocker):
        result = self.run_module_failed(
            mocker, hosttech_dns_record, {
                'hosttech_token': 'foo',
                'state': 'present',
                'zone_name': 'example.org',
                'record': 'example.org',
                'type': 'MX',
                'ttl': 3600,
                'value': '10 example.com',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('GET', 500).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.org').result_str(''),
            ])

        assert result['msg'].startswith(
            'Error: GET https://api.ns1.hosttech.eu/api/user/v1/zones?')
        assert 'did not yield JSON data, but HTTP status code 500 with Content-Type' in result[
            'msg']
    def test_change_add_one_check_mode(self, mocker):
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_username': '******',
                'hosttech_password': '******',
                'state': 'present',
                'zone_name': 'example.com',
                'record': 'example.com',
                'type': 'CAA',
                'ttl': 3600,
                'value': '0 issue "letsencrypt.org"',
                '_ansible_check_mode': True,
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('POST', 200).expect_content_predicate(
                    validate_wsdl_call([
                        expect_wsdl_authentication('foo', 'bar'),
                        expect_wsdl_value(
                            [
                                lxml.etree.QName(
                                    'https://ns1.hosttech.eu/public/api',
                                    'getZone').text, 'sZoneName'
                            ], 'example.com',
                            ('http://www.w3.org/2001/XMLSchema', 'string')),
                    ])).result_str(HOSTTECH_WSDL_DEFAULT_ZONE_RESULT),
            ])

        assert result['changed'] is True
        assert result['zone_id'] == 42
예제 #23
0
    def test_unknown_zone_id_prefix(self, mocker):
        result = self.run_module_failed(
            mocker, hetzner_dns_record, {
                'hetzner_token': 'foo',
                'state': 'present',
                'zone_id': '23',
                'prefix': '',
                'type': 'MX',
                'ttl': 3600,
                'value': '10 example.com',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('GET', 404).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', '23').expect_query_values(
                                    'page', '1').expect_query_values(
                                        'per_page', '100').return_header(
                                            'Content-Type',
                                            'application/json').result_json({
                                                'records': [],
                                                'error': {
                                                    'message':
                                                    'zone not found',
                                                    'code': 404
                                                }
                                            }),
            ])

        assert result['msg'] == 'Zone not found'
예제 #24
0
 def test_form(self, mocker):
     result = self.run_module_success(
         mocker, fetch_url_test_module, {
             'call_sequence': [{
                 'url':
                 'http://example.com?bar=foo&foo=bar&foo=baz#heyhey',
                 'data':
                 base64.b64encode('foo=bar&baz=baz%20baz'.encode(
                     'utf-8')).decode('utf-8'),
                 'headers': {
                     'Content-type': 'application/x-www-form-urlencoded',
                 },
             }],
         }, [
             FetchUrlCall(
                 'GET', 200).expect_form_present('foo').expect_form_value(
                     'baz',
                     'baz baz').expect_form_value_absent('bar').expect_url(
                         'http://example.com',
                         without_query=True,
                         without_fragment=True).expect_query_values(
                             'bar', 'foo').expect_query_values(
                                 'foo', 'bar', 'baz'),
         ])
     assert len(result['call_results']) == 1
     assert result['call_results'][0]['status'] == 200
    def test_get_single(self, mocker):
        result = self.run_module_success(
            mocker, hosttech_dns_record_set_info, {
                'hosttech_username': '******',
                'hosttech_password': '******',
                'zone_name': 'example.com',
                'record': 'example.com',
                'type': 'A',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('POST', 200).expect_content_predicate(
                    validate_wsdl_call([
                        expect_wsdl_authentication('foo', 'bar'),
                        expect_wsdl_value(
                            [
                                lxml.etree.QName(
                                    'https://ns1.hosttech.eu/public/api',
                                    'getZone').text, 'sZoneName'
                            ], 'example.com',
                            ('http://www.w3.org/2001/XMLSchema', 'string')),
                    ])).result_str(HOSTTECH_WSDL_DEFAULT_ZONE_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
예제 #26
0
    def test_auth_error(self, mocker):
        result = self.run_module_failed(
            mocker, hetzner_dns_record, {
                'hetzner_token': 'foo',
                'state': 'present',
                'zone_name': 'example.org',
                'record': 'example.org',
                'type': 'MX',
                'ttl': 3600,
                'value': '10 example.com',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('GET', 401).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.org').result_json({
                                    'message':
                                    'Invalid authentication credentials'
                                }),
            ])

        assert result['msg'] == (
            'Cannot authenticate: Unauthorized: the authentication parameters are incorrect (HTTP status 401): Invalid authentication credentials'
        )
    def test_unknown_zone_id(self, mocker):
        result = self.run_module_failed(
            mocker, hosttech_dns_record, {
                'hosttech_username': '******',
                'hosttech_password': '******',
                'state': 'present',
                'zone_id': 23,
                'record': 'example.org',
                'type': 'MX',
                'ttl': 3600,
                'value': '10 example.com',
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                FetchUrlCall('POST', 200).expect_content_predicate(
                    validate_wsdl_call([
                        expect_wsdl_authentication('foo', 'bar'),
                        expect_wsdl_value(
                            [
                                lxml.etree.QName(
                                    'https://ns1.hosttech.eu/public/api',
                                    'getZone').text, 'sZoneName'
                            ], '23',
                            ('http://www.w3.org/2001/XMLSchema', 'string')),
                    ])).result_str(HOSTTECH_WSDL_ZONE_NOT_FOUND),
            ])

        assert result['msg'] == 'Zone not found'
    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_idempotency_present(self, mocker):
        result = self.run_module_success(
            mocker, hosttech_dns_record, {
                'hosttech_token': 'foo',
                'state': 'present',
                'zone_name': 'example.com',
                'record': 'example.com',
                'type': 'MX',
                'ttl': 3600,
                'value': '10 example.com',
                '_ansible_diff': True,
                '_ansible_remote_tmp': '/tmp/tmp',
                '_ansible_keep_remote_files': True,
            }, [
                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 result['diff']['before'] == {
            'record': 'example.com',
            'prefix': '',
            'type': 'MX',
            'ttl': 3600,
            'value': '10 example.com',
            'extra': {
                'comment': '',
            },
        }
        assert result['diff']['before'] == result['diff']['after']
예제 #30
0
 def test_rerouting_already_routed(self, mocker):
     result = self.run_module_success(mocker, hetzner_failover_ip, {
         'hetzner_user': '',
         'hetzner_password': '',
         'failover_ip': '1.2.3.4',
         'state': 'routed',
         'value': '4.3.2.1',
     }, [
         FetchUrlCall('GET', 200)
         .result_json({
             'failover': {
                 'ip': '1.2.3.4',
                 'netmask': '255.255.255.255',
                 'server_ip': '2.3.4.5',
                 'server_number': 2345,
                 'active_server_ip': '5.4.3.2',
             },
         })
         .expect_url('{0}/failover/1.2.3.4'.format(BASE_URL)),
         FetchUrlCall('POST', 409)
         .result_json({
             'error': {
                 'status': 409,
                 'code': 'FAILOVER_ALREADY_ROUTED',
                 'message': 'Failover already routed',
             },
             'failover': {
                 'ip': '1.2.3.4',
                 'netmask': '255.255.255.255',
                 'server_ip': '2.3.4.5',
                 'server_number': 2345,
                 'active_server_ip': '4.3.2.1',
             },
         })
         .expect_form_value('active_server_ip', '4.3.2.1')
         .expect_url('{0}/failover/1.2.3.4'.format(BASE_URL)),
     ])
     assert result['changed'] is False
     assert result['value'] == '4.3.2.1'
     assert result['state'] == 'routed'