Repository URL to install this package:
|
Version:
6.0.0 ▾
|
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017-2021 Felix Fontein
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# This module_utils is PRIVATE and should only be used by this collection. Breaking changes can occur any time.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import traceback
from ansible.module_utils.common.text.converters import to_text
from ansible_collections.community.dns.plugins.module_utils.argspec import (
ArgumentSpec,
ModuleOptionProvider,
)
from ansible_collections.community.dns.plugins.module_utils.conversion.base import (
DNSConversionError,
)
from ansible_collections.community.dns.plugins.module_utils.conversion.converter import (
RecordConverter,
)
from ansible_collections.community.dns.plugins.module_utils.options import (
create_record_transformation_argspec,
)
from ansible_collections.community.dns.plugins.module_utils.record import (
DNSRecord,
format_record_for_output,
)
from ansible_collections.community.dns.plugins.module_utils.zone_record_api import (
DNSAPIError,
DNSAPIAuthenticationError,
NOT_PROVIDED,
filter_records,
)
from ._utils import (
normalize_dns_name,
get_prefix,
)
def create_module_argument_spec(provider_information):
return ArgumentSpec(
argument_spec=dict(
state=dict(type='str', choices=['present', 'absent'], required=True),
zone_name=dict(type='str', aliases=['zone']),
zone_id=dict(type=provider_information.get_zone_id_type()),
record=dict(type='str'),
prefix=dict(type='str'),
ttl=dict(type='int', default=provider_information.get_record_default_ttl()),
type=dict(choices=provider_information.get_supported_record_types(), required=True),
value=dict(type='str', required=True),
),
required_one_of=[
('zone_name', 'zone_id'),
('record', 'prefix'),
],
mutually_exclusive=[
('zone_name', 'zone_id'),
('record', 'prefix'),
],
).merge(create_record_transformation_argspec())
def run_module(module, create_api, provider_information):
option_provider = ModuleOptionProvider(module)
record_converter = RecordConverter(provider_information, option_provider)
record_in = normalize_dns_name(module.params.get('record'))
prefix_in = module.params.get('prefix')
type_in = module.params.get('type')
try:
# Create API
api = create_api()
# Get zone information
if module.params.get('zone_name') is not None:
zone_in = normalize_dns_name(module.params.get('zone_name'))
record_in, prefix = get_prefix(
normalized_zone=zone_in, normalized_record=record_in, prefix=prefix_in, provider_information=provider_information)
zone = api.get_zone_with_records_by_name(zone_in, prefix=prefix, record_type=type_in)
if zone is None:
module.fail_json(msg='Zone not found')
zone_id = zone.zone.id
records = zone.records
elif record_in is not None:
zone = api.get_zone_with_records_by_id(
module.params.get('zone_id'),
record_type=type_in,
prefix=provider_information.normalize_prefix(prefix_in) if prefix_in is not None else NOT_PROVIDED,
)
if zone is None:
module.fail_json(msg='Zone not found')
zone_in = normalize_dns_name(zone.zone.name)
record_in, prefix = get_prefix(
normalized_zone=zone_in, normalized_record=record_in, prefix=prefix_in, provider_information=provider_information)
zone_id = zone.zone.id
records = zone.records
else:
zone_id = module.params.get('zone_id')
prefix = provider_information.normalize_prefix(prefix_in)
records = api.get_zone_records(
zone_id,
record_type=type_in,
prefix=prefix,
)
if records is None:
module.fail_json(msg='Zone not found')
zone_in = None
record_in = None
# Find matching records
records = filter_records(records, prefix=prefix)
record_converter.process_multiple_from_api(records)
# Parse records
value_in = module.params.get('value')
value_in = record_converter.process_value_from_user(type_in, value_in)
# Compare records
existing_record = None
exact_match = False
ttl_in = module.params.get('ttl')
for record in records:
if record.target == value_in:
existing_record = record
exact_match = record.ttl == ttl_in
break
before = existing_record.clone() if existing_record else None
after = before
changed = False
if module.params.get('state') == 'present':
if existing_record is None:
# Create record
record = DNSRecord()
record.prefix = prefix
record.type = type_in
record.ttl = ttl_in
record.target = value_in
api_record = record_converter.clone_to_api(record)
if not module.check_mode:
new_api_record = api.add_record(zone_id, api_record)
record = record_converter.clone_from_api(new_api_record)
after = record
changed = True
elif not exact_match:
# Update record
record = existing_record
record.ttl = ttl_in
api_record = record_converter.clone_to_api(record)
if not module.check_mode:
new_api_record = api.update_record(zone_id, api_record)
record = record_converter.clone_from_api(new_api_record)
after = record
changed = True
else:
if existing_record is not None:
# Delete record
api_record = record_converter.clone_to_api(record)
if not module.check_mode:
api.delete_record(zone_id, api_record)
after = None
changed = True
# Compose result
result = dict(
changed=changed,
zone_id=zone_id,
)
if module._diff:
result['diff'] = dict(
before=format_record_for_output(before, record_in, prefix, record_converter=record_converter) if before else {},
after=format_record_for_output(after, record_in, prefix, record_converter=record_converter) if after else {},
)
module.exit_json(**result)
except DNSConversionError as e:
module.fail_json(msg='Error while converting DNS values: {0}'.format(e.error_message), error=e.error_message, exception=traceback.format_exc())
except DNSAPIAuthenticationError as e:
module.fail_json(msg='Cannot authenticate: {0}'.format(e), error=to_text(e), exception=traceback.format_exc())
except DNSAPIError as e:
module.fail_json(msg='Error: {0}'.format(e), error=to_text(e), exception=traceback.format_exc())