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
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'
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
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
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
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
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'
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
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'
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
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']
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'