diff options
Diffstat (limited to 'roles/lib_dyn')
| -rw-r--r-- | roles/lib_dyn/README.md | 27 | ||||
| -rw-r--r-- | roles/lib_dyn/library/dyn_record.py | 351 | ||||
| -rw-r--r-- | roles/lib_dyn/meta/main.yml | 33 | ||||
| -rw-r--r-- | roles/lib_dyn/tasks/main.yml | 7 | 
4 files changed, 0 insertions, 418 deletions
diff --git a/roles/lib_dyn/README.md b/roles/lib_dyn/README.md deleted file mode 100644 index 1eec9f81c..000000000 --- a/roles/lib_dyn/README.md +++ /dev/null @@ -1,27 +0,0 @@ -lib_dyn -========= - -A role containing the dyn_record module for managing DNS records through Dyn's -API - -Requirements ------------- - -The module requires the `dyn` python module for interacting with the Dyn API. -https://github.com/dyninc/dyn-python - -Example Playbook ----------------- - -To make sure the `dyn_record` module is available for use include the role -before it is used. - -    - hosts: servers -      roles: -         - lib_dyn - -License -------- - -Apache - diff --git a/roles/lib_dyn/library/dyn_record.py b/roles/lib_dyn/library/dyn_record.py deleted file mode 100644 index 42d970060..000000000 --- a/roles/lib_dyn/library/dyn_record.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/python -# -# (c) 2015, Russell Harrison <rharriso@redhat.com> -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -#    http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# pylint: disable=too-many-branches -'''Ansible module to manage records in the Dyn Managed DNS service''' -DOCUMENTATION = ''' ---- -module: dyn_record -version_added: "1.9" -short_description: Manage records in the Dyn Managed DNS service. -description: -  - "Manages DNS records via the REST API of the Dyn Managed DNS service.  It -  - "handles records only; there is no manipulation of zones or account support" -  - "yet. See: U(https://help.dyn.com/dns-api-knowledge-base/)" -options: -  state: -    description: -      -"Whether the record should be c(present) or c(absent). Optionally the" -      - "state c(list) can be used to return the current value of a record." -    required: true -    choices: [ 'present', 'absent', 'list' ] -    default: present - -  customer_name: -    description: -      - "The Dyn customer name for your account.  If not set the value of the" -      - "c(DYNECT_CUSTOMER_NAME) environment variable is used." -    required: false -    default: nil - -  user_name: -    description: -      - "The Dyn user name to log in with. If not set the value of the" -      - "c(DYNECT_USER_NAME) environment variable is used." -    required: false -    default: null - -  user_password: -    description: -      - "The Dyn user's password to log in with. If not set the value of the" -      - "c(DYNECT_PASSWORD) environment variable is used." -    required: false -    default: null - -  zone: -    description: -      - "The DNS zone in which your record is located." -    required: true -    default: null - -  record_fqdn: -    description: -      - "Fully qualified domain name of the record name to get, create, delete," -      - "or update." -    required: true -    default: null - -  record_type: -    description: -      - "Record type." -    required: true -    choices: [ 'A', 'AAAA', 'CNAME', 'PTR', 'TXT' ] -    default: null - -  record_value: -    description: -      - "Record value. If record_value is not specified; no changes will be" -      - "made and the module will fail" -    required: false -    default: null - -  record_ttl: -    description: -      - 'Record's "Time to live".  Number of seconds the record remains cached' -      - 'in DNS servers or c(0) to use the default TTL for the zone.' -      - 'This option is mutually exclusive with use_zone_ttl' -    required: false -    default: 0 - -  use_zone_ttl: -    description: -      - 'Use the DYN Zone's Default TTL' -      - 'This option is mutually exclusive with record_ttl' -    required: false -    default: false -    mutually exclusive with: record_ttl - -notes: -  - The module makes a broad assumption that there will be only one record per "node" (FQDN). -  - This module returns record(s) in the "result" element when 'state' is set to 'present'. This value can be be registered and used in your playbooks. - -requirements: [ dyn ] -author: "Russell Harrison" -''' - -EXAMPLES = ''' -# Attempting to cname www.example.com to web1.example.com -- name: Update CNAME record -  dyn_record: -    state: present -    record_fqdn: www.example.com -    zone: example.com -    record_type: CNAME -    record_value: web1.example.com -    record_ttl: 7200 - -# Use the zones default TTL -- name: Update CNAME record -  dyn_record: -    state: present -    record_fqdn: www.example.com -    zone: example.com -    record_type: CNAME -    record_value: web1.example.com -    use_zone_ttl: true - -- name: Update A record -  dyn_record: -    state: present -    record_fqdn: web1.example.com -    zone: example.com -    record_value: 10.0.0.10 -    record_type: A -''' - -try: -    IMPORT_ERROR = False -    from dyn.tm.session import DynectSession -    from dyn.tm.zones import Zone -    import dyn.tm.errors -    import os - -except ImportError as error: -    IMPORT_ERROR = str(error) - -# Each of the record types use a different method for the value. -RECORD_PARAMS = { -    'A'     : {'value_param': 'address'}, -    'AAAA'  : {'value_param': 'address'}, -    'CNAME' : {'value_param': 'cname'}, -    'PTR'   : {'value_param': 'ptrdname'}, -    'TXT'   : {'value_param': 'txtdata'} -} - -# You'll notice that the value_param doesn't match the key (records_key) -# in the dict returned from Dyn when doing a dyn_node.get_all_records() -# This is a frustrating lookup dict to allow mapping to the RECORD_PARAMS -# dict so we can lookup other values in it efficiently - -def get_record_type(record_key): -    '''Get the record type represented by the keys returned from get_any_records.''' -    return record_key.replace('_records', '').upper() - -def get_record_key(record_type): -    '''Get the key to look up records in the dictionary returned from get_any_records. -       example: -       'cname_records' -    ''' -    return record_type.lower() + '_records' - -def get_any_records(module, node): -    '''Get any records for a given node''' -    # Lets get a list of the A records for the node -    try: -        records = node.get_any_records() -    except dyn.tm.errors.DynectGetError as error: -        if 'Not in zone' in str(error): -            # The node isn't in the zone so we'll return an empty dictionary -            return {} -        else: -            # An unknown error happened so we'll need to return it. -            module.fail_json(msg='Unable to get records', -                             error=str(error)) - -    # Return a dictionary of the record objects -    return records - -def get_record_values(records): -    '''Get the record values for each record returned by get_any_records.''' -    # This simply returns the values from a record -    ret_dict = {} -    for key in records.keys(): -        record_type = get_record_type(key) -        params = [RECORD_PARAMS[record_type]['value_param'], 'ttl', 'zone', 'fqdn'] -        ret_dict[key] = [] -        properties = {} -        for elem in records[key]: -            for param in params: -                properties[param] = getattr(elem, param) -            ret_dict[key].append(properties) - -    return ret_dict - -def compare_record_values(record_type_key, user_record_value, dyn_values): -    ''' Verify the user record_value exists in dyn''' -    rtype = get_record_type(record_type_key) -    for record in dyn_values[record_type_key]: -        if user_record_value in record[RECORD_PARAMS[rtype]['value_param']]: -            return True - -    return False - -def compare_record_ttl(record_type_key, user_record_value, dyn_values, user_param_ttl): -    ''' Verify the ttls match for the record''' -    rtype = get_record_type(record_type_key) -    for record in dyn_values[record_type_key]: -        # find the right record -        if user_record_value in record[RECORD_PARAMS[rtype]['value_param']]: -            # Compare ttls from the records -            if int(record['ttl']) == user_param_ttl: -                return True - -    return False - -def main(): -    '''Ansible module for managing Dyn DNS records.''' -    module = AnsibleModule( -        argument_spec=dict( -            state=dict(default='present', choices=['present', 'absent', 'list']), -            customer_name=dict(default=os.environ.get('DYNECT_CUSTOMER_NAME', None), type='str'), -            user_name=dict(default=os.environ.get('DYNECT_USER_NAME', None), type='str', no_log=True), -            user_password=dict(default=os.environ.get('DYNECT_PASSWORD', None), type='str', no_log=True), -            zone=dict(required=True, type='str'), -            record_fqdn=dict(required=False, type='str'), -            record_type=dict(required=False, type='str', choices=[ -                'A', 'AAAA', 'CNAME', 'PTR', 'TXT']), -            record_value=dict(required=False, type='str'), -            record_ttl=dict(required=False, default=None, type='int'), -            use_zone_ttl=dict(required=False, default=False), -        ), -        required_together=( -            ['record_fqdn', 'record_value', 'record_ttl', 'record_type'] -        ), -        mutually_exclusive=[('record_ttl', 'use_zone_ttl')] -    ) - -    if IMPORT_ERROR: -        module.fail_json(msg="Unable to import dyn module: https://pypi.python.org/pypi/dyn", error=IMPORT_ERROR) - -    if module.params['record_ttl'] != None and int(module.params['record_ttl']) <= 0: -        module.fail_json(msg="Invalid Value for record TTL") - -    # Start the Dyn session -    try: -        _ = DynectSession(module.params['customer_name'], -                          module.params['user_name'], -                          module.params['user_password']) -    except dyn.tm.errors.DynectAuthError as error: -        module.fail_json(msg='Unable to authenticate with Dyn', error=str(error)) - -    # Retrieve zone object -    try: -        dyn_zone = Zone(module.params['zone']) -    except dyn.tm.errors.DynectGetError as error: -        if 'No such zone' in str(error): -            module.fail_json(msg="Not a valid zone for this account", zone=module.params['zone']) -        else: -            module.fail_json(msg="Unable to retrieve zone", error=str(error)) - -    # To retrieve the node object we need to remove the zone name from the FQDN -    dyn_node_name = module.params['record_fqdn'].replace('.' + module.params['zone'], '') - -    # Retrieve the zone object from dyn -    dyn_zone = Zone(module.params['zone']) - -    # Retrieve the node object from dyn -    dyn_node = dyn_zone.get_node(node=dyn_node_name) - -    # All states will need a list of the exiting records for the zone. -    dyn_node_records = get_any_records(module, dyn_node) - -    dyn_values = get_record_values(dyn_node_records) - -    if module.params['state'] == 'list': -        module.exit_json(changed=False, dyn_records=dyn_values) - -    elif module.params['state'] == 'absent': -        # If there are any records present we'll want to delete the node. -        if dyn_node_records: -            dyn_node.delete() - -            # Publish the zone since we've modified it. -            dyn_zone.publish() - -            module.exit_json(changed=True, msg="Removed node %s from zone %s" % (dyn_node_name, module.params['zone'])) - -        module.exit_json(changed=False) - -    elif module.params['state'] == 'present': - -        # configure the TTL variable: -        # if use_zone_ttl, use the default TTL of the account. -        # if TTL == None, don't check it, set it as 0 (api default) -        # if TTL > 0, ensure this TTL is set -        if module.params['use_zone_ttl']: -            user_param_ttl = dyn_zone.ttl -        elif not module.params['record_ttl']: -            user_param_ttl = 0 -        else: -            user_param_ttl = module.params['record_ttl'] - -        # First get a list of existing records for the node -        record_type_key = get_record_key(module.params['record_type']) -        user_record_value = module.params['record_value'] - -        # Check to see if the record is already in place before doing anything. -        if dyn_node_records and compare_record_values(record_type_key, user_record_value, dyn_values): - -            if user_param_ttl == 0 or \ -               compare_record_ttl(record_type_key, user_record_value, dyn_values, user_param_ttl): -                module.exit_json(changed=False, dyn_record=dyn_values) - -        # Working on the assumption that there is only one record per -        # node we will first delete the node if there are any records before -        # creating the correct record -        if dyn_node_records: -            dyn_node.delete() - -        # Now lets create the correct node entry. -        record = dyn_zone.add_record(dyn_node_name, -                                     module.params['record_type'], -                                     module.params['record_value'], -                                     user_param_ttl -                                    ) - -        # Now publish the zone since we've updated it. -        dyn_zone.publish() - -        rmsg = "Created node [%s] "  % dyn_node_name -        rmsg += "in zone: [%s]"      % module.params['zone'] -        module.exit_json(changed=True, msg=rmsg, dyn_record=get_record_values({record_type_key: [record]})) - -    module.fail_json(msg="Unknown state: [%s]" % module.params['state']) - -# Ansible tends to need a wild card import so we'll use it here -# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled -from ansible.module_utils.basic import * -if __name__ == '__main__': -    main() diff --git a/roles/lib_dyn/meta/main.yml b/roles/lib_dyn/meta/main.yml deleted file mode 100644 index 5475c6971..000000000 --- a/roles/lib_dyn/meta/main.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -galaxy_info: -  author: Russell Harrison -  description:  A role to provide the dyn_record module -  company: Red Hat, Inc. -  # If the issue tracker for your role is not on github, uncomment the -  # next line and provide a value -  # issue_tracker_url: http://example.com/issue/tracker -  license: Apache -  min_ansible_version: 1.9 -  platforms: -    - name: EL -      versions: -       - 7 -  #- name: Fedora -  #  versions: -  #  - 19 -  #  - 20 -  #  - 21 -  #  - 22 -  # Below are all categories currently available. Just as with -  # the platforms above, uncomment those that apply to your role. -  categories: -    - networking -dependencies: [] -  # List your role dependencies here, one per line. -  # Be sure to remove the '[]' above if you add dependencies -  # to this list. -  # -  # No role dependencies at this time. The module contained in this role does -  # require the dyn python module. -  # https://pypi.python.org/pypi/dyn - diff --git a/roles/lib_dyn/tasks/main.yml b/roles/lib_dyn/tasks/main.yml deleted file mode 100644 index 965962928..000000000 --- a/roles/lib_dyn/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# tasks file for lib_dyn - -- name: Make sure python-dyn is installed -  yum: name=python-dyn state=present -  tags: -    - lib_dyn  | 
