From 0e07b15f920bbc0174e89cdd8e83177b67940553 Mon Sep 17 00:00:00 2001 From: Jakob Meng Date: Thu, 24 Nov 2022 14:13:15 +0100 Subject: [PATCH] Refactored dns_zone{,_info} modules Change-Id: I030cc0566ae94edf340d33e1e00c20403acabb2d --- ci/roles/dns/defaults/main.yml | 4 - ci/roles/dns/tasks/main.yml | 32 -- ci/roles/dns_zone/defaults/main.yml | 17 ++ ci/roles/dns_zone/tasks/main.yml | 67 +++++ ci/roles/dns_zone_info/tasks/main.yml | 49 --- ci/run-collection.yml | 5 +- plugins/modules/dns_zone.py | 410 ++++++++++++++------------ plugins/modules/dns_zone_info.py | 254 ++++++++-------- 8 files changed, 436 insertions(+), 402 deletions(-) delete mode 100644 ci/roles/dns/defaults/main.yml delete mode 100644 ci/roles/dns/tasks/main.yml create mode 100644 ci/roles/dns_zone/defaults/main.yml create mode 100644 ci/roles/dns_zone/tasks/main.yml delete mode 100644 ci/roles/dns_zone_info/tasks/main.yml diff --git a/ci/roles/dns/defaults/main.yml b/ci/roles/dns/defaults/main.yml deleted file mode 100644 index 6dc476bf..00000000 --- a/ci/roles/dns/defaults/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -dns_zone_name: test.dns.zone. -recordset_name: testrecordset.test.dns.zone. -records: ['10.0.0.0'] -updated_records: ['10.1.1.1'] diff --git a/ci/roles/dns/tasks/main.yml b/ci/roles/dns/tasks/main.yml deleted file mode 100644 index 28047b44..00000000 --- a/ci/roles/dns/tasks/main.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- name: Create dns zone - openstack.cloud.dns_zone: - cloud: "{{ cloud }}" - name: "{{ dns_zone_name }}" - zone_type: "primary" - email: test@example.net - register: dns_zone - -- debug: var=dns_zone - -- name: Update dns zone - openstack.cloud.dns_zone: - cloud: "{{ cloud }}" - name: "{{ dns_zone.zone.name }}" - description: "New descirption" - register: updated_dns_zone - -- debug: var=updated_dns_zone - -- name: Delete dns zone - openstack.cloud.dns_zone: - cloud: "{{ cloud }}" - name: "{{ updated_dns_zone.zone.name }}" - state: absent - register: deleted_dns_zone - -- name: Verify dns zone - assert: - that: - - deleted_dns_zone is successful - - deleted_dns_zone is changed diff --git a/ci/roles/dns_zone/defaults/main.yml b/ci/roles/dns_zone/defaults/main.yml new file mode 100644 index 00000000..2a8e8d06 --- /dev/null +++ b/ci/roles/dns_zone/defaults/main.yml @@ -0,0 +1,17 @@ +expected_fields: + - action + - attributes + - created_at + - description + - email + - id + - links + - masters + - name + - pool_id + - project_id + - serial + - status + - ttl + - type + - updated_at diff --git a/ci/roles/dns_zone/tasks/main.yml b/ci/roles/dns_zone/tasks/main.yml new file mode 100644 index 00000000..77efb9d3 --- /dev/null +++ b/ci/roles/dns_zone/tasks/main.yml @@ -0,0 +1,67 @@ +--- +- name: Create dns zone + openstack.cloud.dns_zone: + cloud: "{{ cloud }}" + name: ansible.test.zone. + type: primary + email: test@example.net + register: dns_zone + +- name: Assert return values of dns_zone module + assert: + that: + - dns_zone.zone.name == "ansible.test.zone." + - dns_zone.zone.type|lower == "primary" + - dns_zone.zone.email == "test@example.net" + # allow new fields to be introduced but prevent fields from being removed + - expected_fields|difference(dns_zone.zone.keys())|length == 0 + +- name: Update dns zone + openstack.cloud.dns_zone: + cloud: "{{ cloud }}" + name: ansible.test.zone. + description: "Another description" + register: dns_zone + +- name: Assert return values of dns_zone module + assert: + that: + - dns_zone.zone.description == "Another description" + +- name: Fetch all dns zones + openstack.cloud.dns_zone_info: + cloud: "{{ cloud }}" + register: dns_zones + +- name: Assert return values of dns_zone_info module + assert: + that: + - dns_zones is not changed + - dns_zones | length > 0 + # allow new fields to be introduced but prevent fields from being removed + - expected_fields|difference(dns_zones.zones[0].keys())|length == 0 + +- name: Fetch a dns zone by name + openstack.cloud.dns_zone_info: + cloud: "{{ cloud }}" + name: ansible.test.zone. + register: dns_zones + +- name: Assert return values of dns_zone_info module + assert: + that: + - dns_zones is not changed + - dns_zones.zones | length == 1 + - dns_zones.zones[0].id == dns_zone.zone.id + +- name: Delete dns zone + openstack.cloud.dns_zone: + cloud: "{{ cloud }}" + name: ansible.test.zone. + state: absent + register: dns_zone + +- name: Verify dns zone + assert: + that: + - dns_zone is changed diff --git a/ci/roles/dns_zone_info/tasks/main.yml b/ci/roles/dns_zone_info/tasks/main.yml deleted file mode 100644 index 2263b0fa..00000000 --- a/ci/roles/dns_zone_info/tasks/main.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- name: Set random prefix - set_fact: - prefix: "{{ 99999999 | random | to_uuid | hash('md5') }}" - -- name: Create dns zone - openstack.cloud.dns_zone: - cloud: "{{ cloud }}" - name: "{{ (prefix + '.test.zone.') }}" - email: test@example.net - -- name: Getting info about dns zones - openstack.cloud.dns_zone_info: - cloud: "{{ cloud }}" - register: zones - -- name: assert result - assert: - that: - - zones is success - - zones is not changed - - zones | length > 0 - -- name: Getting info about created zone - openstack.cloud.dns_zone_info: - cloud: "{{ cloud }}" - name: "{{ (prefix + '.test.zone.') }}" - register: zone - -- name: assert result - assert: - that: - - zone is success - - zone is not changed - - zone.zones | length == 1 - -- name: Assert keys exist - assert: - that: - - '["action", "attributes", "created_at", "description", "email", - "links", "masters", "name", "pool_id", "project_id", "serial", - "status", "ttl", "type", "updated_at", "id"] | - difference(zone.zones.0.keys()) | length == 0' - -- name: Drop created dns zone - openstack.cloud.dns_zone: - cloud: "{{ cloud }}" - name: "{{ (prefix + '.test.zone.') }}" - state: absent diff --git a/ci/run-collection.yml b/ci/run-collection.yml index 7f9c456d..85e0d459 100644 --- a/ci/run-collection.yml +++ b/ci/run-collection.yml @@ -10,10 +10,7 @@ - { role: compute_flavor, tags: compute_flavor } - { role: compute_flavor_access, tags: compute_flavor_access } - { role: config, tags: config } - - { role: dns_zone_info, tags: dns_zone_info } - - role: dns - tags: dns - when: sdk_version is version(0.28, '>=') + - { role: dns_zone, tags: dns_zone } - { role: endpoint, tags: endpoint } - { role: federation_mapping, tags: federation_mapping } - { role: floating_ip, tags: floating_ip } diff --git a/plugins/modules/dns_zone.py b/plugins/modules/dns_zone.py index 30c5ba48..1669c1e9 100644 --- a/plugins/modules/dns_zone.py +++ b/plugins/modules/dns_zone.py @@ -4,116 +4,161 @@ # Copyright (c) 2016 Hewlett-Packard Enterprise # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -DOCUMENTATION = ''' +DOCUMENTATION = r''' --- module: dns_zone -short_description: Manage OpenStack DNS zones +short_description: Manage a OpenStack DNS zone. author: OpenStack Ansible SIG description: - - Manage OpenStack DNS zones. Zones can be created, deleted or - updated. Only the I(email), I(description), I(ttl) and I(masters) values - can be updated. + - Create, delete or update a OpenStack DNS zone. options: - name: - description: - - Zone name - required: true - type: str - zone_type: - description: - - Zone type - choices: [primary, secondary] - type: str - email: - description: - - Email of the zone owner (only applies if zone_type is primary) - type: str - description: - description: - - Zone description - type: str - ttl: - description: - - TTL (Time To Live) value in seconds - type: int - masters: - description: - - Master nameservers (only applies if zone_type is secondary) - type: list - elements: str - state: - description: - - Should the resource be present or absent. - choices: [present, absent] - default: present - type: str + description: + description: + - Zone description. + type: str + email: + description: + - Email of the zone owner. + - Only applies if I(type) is C(primary). + type: str + masters: + description: + - Master nameservers + - Only applies if I(type) is C(secondary). + type: list + elements: str + name: + description: + - Name of the DNS zone. + required: true + type: str + state: + description: + - Whether the zone should be C(present) or C(absent). + choices: ['present', 'absent'] + default: present + type: str + ttl: + description: + - TTL (Time To Live) value in seconds. + type: int + type: + description: + - Zone type. + - This attribute cannot be updated. + choices: ['primary', 'secondary'] + type: str + aliases: ['zone_type'] requirements: - - "python >= 3.6" - - "openstacksdk" - + - "python >= 3.6" + - "openstacksdk" extends_documentation_fragment: -- openstack.cloud.openstack + - openstack.cloud.openstack ''' -EXAMPLES = ''' -# Create a zone named "example.net" -- openstack.cloud.dns_zone: +EXAMPLES = r''' +- name: Create DNS zone example.net. + openstack.cloud.dns_zone: cloud: mycloud state: present name: example.net. - zone_type: primary + type: primary email: test@example.net description: Test zone ttl: 3600 -# Update the TTL on existing "example.net." zone -- openstack.cloud.dns_zone: +- name: Set TTL on DNS zone example.net. + openstack.cloud.dns_zone: cloud: mycloud state: present name: example.net. ttl: 7200 -# Delete zone named "example.net." -- openstack.cloud.dns_zone: +- name: Delete zone example.net. + openstack.cloud.dns_zone: cloud: mycloud state: absent name: example.net. ''' -RETURN = ''' +RETURN = r''' zone: - description: Dictionary describing the zone. - returned: On success when I(state) is 'present'. - type: complex - contains: - id: - description: Unique zone ID - type: str - sample: "c1c530a3-3619-46f3-b0f6-236927b2618c" - name: - description: Zone name - type: str - sample: "example.net." - type: - description: Zone type - type: str - sample: "PRIMARY" - email: - description: Zone owner email - type: str - sample: "test@example.net" - description: - description: Zone description - type: str - sample: "Test description" - ttl: - description: Zone TTL value - type: int - sample: 3600 - masters: - description: Zone master nameservers - type: list - sample: [] + description: Dictionary describing the zone. + returned: On success when I(state) is C(present). + type: dict + contains: + action: + description: Current action in progress on the resource. + type: str + sample: "CREATE" + attributes: + description: Key value pairs of information about this zone, and the + pool the user would like to place the zone in. This + information can be used by the scheduler to place zones on + the correct pool. + type: dict + sample: {"tier": "gold", "ha": "true"} + created_at: + description: Date / Time when resource was created. + type: str + sample: "2014-07-07T18:25:31.275934" + description: + description: Description for this zone. + type: str + sample: "This is an example zone." + email: + description: E-mail for the zone. Used in SOA records for the zone. + type: str + sample: "test@example.org" + id: + description: ID for the resource. + type: int + sample: "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" + links: + description: Links to the resource, and other related resources. When a + response has been broken into pages, we will include a next + link that should be followed to retrieve all results. + type: dict + sample: {"self": "https://127.0.0.1:9001/v2/zones/a86dba...d5e86f3ca3"} + masters: + description: The servers to slave from to get DNS information. + Mandatory for secondary zones. + type: list + sample: "[]" + name: + description: DNS Name for the zone. + type: str + sample: "test.test." + pool_id: + description: ID for the pool hosting this zone. + type: str + sample: "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" + project_id: + description: ID for the project that owns the resource. + type: str + sample: "4335d1f0-f793-11e2-b778-0800200c9a66" + serial: + description: Current serial number for the zone. + type: int + sample: 1404757531 + status: + description: Status of the resource. + type: str + sample: "ACTIVE" + ttl: + description: TTL (Time to Live) for the zone. + type: int + sample: 7200 + type: + description: Type of zone. PRIMARY is controlled by Designate, + SECONDARY zones are slaved from another DNS Server. + Defaults to PRIMARY. + type: str + sample: "PRIMARY" + updated_at: + description: Date / Time when resource last updated. + type: str + sample: "2014-07-07T18:25:31.275934" ''' from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule @@ -122,119 +167,116 @@ from ansible_collections.openstack.cloud.plugins.module_utils.openstack import O class DnsZoneModule(OpenStackModule): argument_spec = dict( - name=dict(required=True), - zone_type=dict(choices=['primary', 'secondary']), - email=dict(), description=dict(), - ttl=dict(type='int'), + email=dict(), masters=dict(type='list', elements='str'), + name=dict(required=True), state=dict(default='present', choices=['absent', 'present']), + ttl=dict(type='int'), + type=dict(choices=['primary', 'secondary'], aliases=['zone_type']), ) - def _system_state_change(self, state, email, description, ttl, masters, zone): - if state == 'present': - if not zone: - return True - if email is not None and zone.email != email: - return True - if description is not None and zone.description != description: - return True - if ttl is not None and zone.ttl != ttl: - return True - if masters is not None and zone.masters != masters: - return True - if state == 'absent' and zone: - return True - return False + def run(self): + state = self.params['state'] + name_or_id = self.params['name'] - def _wait(self, timeout, zone, state): - """Wait for a zone to reach the desired state for the given state.""" + zone = self.conn.dns.find_zone(name_or_id=name_or_id) + + if self.ansible.check_mode: + self.exit_json(changed=self._will_change(state, zone)) + + if state == 'present' and not zone: + # Create zone + zone = self._create() + self.exit_json(changed=True, + zone=zone.to_dict(computed=False)) + + elif state == 'present' and zone: + # Update zone + update = self._build_update(zone) + if update: + zone = self._update(zone, update) + + self.exit_json(changed=bool(update), + zone=zone.to_dict(computed=False)) + + elif state == 'absent' and zone: + # Delete zone + self._delete(zone) + self.exit_json(changed=True) + + elif state == 'absent' and not zone: + # Do nothing + self.exit_json(changed=False) + + def _build_update(self, zone): + update = {} + + attributes = dict((k, self.params[k]) + for k in ['description', 'email', 'masters', 'ttl'] + if self.params[k] is not None + and self.params[k] != zone[k]) + + if attributes: + update['attributes'] = attributes + + return update + + def _create(self): + kwargs = dict((k, self.params[k]) + for k in ['description', 'email', 'masters', 'name', + 'ttl', 'type'] + if self.params[k] is not None) + + if 'type' in kwargs: + # designate expects upper case PRIMARY or SECONDARY + kwargs['type'] = kwargs['type'].upper() + + zone = self.conn.dns.create_zone(**kwargs) + + if self.params['wait']: + self.sdk.resource.wait_for_status( + self.conn.dns, zone, + status='active', + failures=['error'], + wait=self.params['timeout']) + + return zone + + def _delete(self, zone): + self.conn.dns.delete_zone(zone.id) for count in self.sdk.utils.iterate_timeout( - timeout, - "Timeout waiting for zone to be %s" % state): + timeout=self.params['timeout'], + message="Timeout waiting for zone to be absent" + ): + if self.conn.dns.find_zone(zone.id) is None: + break - if (state == 'absent' and zone is None) or (state == 'present' and zone and zone.status == 'ACTIVE'): - return + def _update(self, zone, update): + attributes = update.get('attributes') + if attributes: + zone = self.conn.dns.update_zone(zone.id, **attributes) - try: - zone = self.conn.get_zone(zone.id) - except Exception: - continue + if self.params['wait']: + self.sdk.resource.wait_for_status( + self.conn.dns, zone, + status='active', + failures=['error'], + wait=self.params['timeout']) - if zone and zone.status == 'ERROR': - self.fail_json(msg="Zone reached ERROR state while waiting for it to be %s" % state) + return zone - def run(self): - - name = self.params['name'] - state = self.params['state'] - wait = self.params['wait'] - timeout = self.params['timeout'] - - zone = self.conn.get_zone(name) - - if state == 'present': - - zone_type = self.params['zone_type'] - email = self.params['email'] - description = self.params['description'] - ttl = self.params['ttl'] - masters = self.params['masters'] - - kwargs = {} - - if email: - kwargs['email'] = email - if description: - kwargs['description'] = description - if ttl: - kwargs['ttl'] = ttl - if masters: - kwargs['masters'] = masters - - if self.ansible.check_mode: - self.exit_json(changed=self._system_state_change(state, email, - description, ttl, - masters, zone)) - - if zone is None: - zone = self.conn.create_zone( - name=name, zone_type=zone_type, **kwargs) - changed = True - else: - if masters is None: - masters = [] - - pre_update_zone = zone - changed = self._system_state_change(state, email, - description, ttl, - masters, pre_update_zone) - if changed: - zone = self.conn.update_zone( - name, **kwargs) - - if wait: - self._wait(timeout, zone, state) - - self.exit_json(changed=changed, zone=zone) - - elif state == 'absent': - if self.ansible.check_mode: - self.exit_json(changed=self._system_state_change(state, None, - None, None, - None, zone)) - - if zone is None: - changed = False - else: - self.conn.delete_zone(name) - changed = True - - if wait: - self._wait(timeout, zone, state) - - self.exit_json(changed=changed) + def _will_change(self, state, zone): + if state == 'present' and not zone: + return True + elif state == 'present' and zone: + return bool(self._build_update(zone)) + elif state == 'absent' and zone: + return True + else: + # state == 'absent' and not zone: + return False def main(): diff --git a/plugins/modules/dns_zone_info.py b/plugins/modules/dns_zone_info.py index 79dabaea..cb3d7afc 100644 --- a/plugins/modules/dns_zone_info.py +++ b/plugins/modules/dns_zone_info.py @@ -5,7 +5,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -DOCUMENTATION = ''' +DOCUMENTATION = r''' --- module: dns_zone_info short_description: Getting information about dns zones @@ -13,115 +13,125 @@ author: OpenStack Ansible SIG description: - Getting information about dns zones. Output can be filtered. options: - name: - description: - - Zone name. - type: str - type: - description: - - Zone type. - choices: [primary, secondary] - type: str - email: - description: - - Email of the zone owner (only applies if zone_type is primary). - type: str - description: - description: - - Zone description. - type: str - ttl: - description: - - TTL (Time To Live) value in seconds. - type: int - + description: + description: + - Zone description. + type: str + email: + description: + - Email of the zone owner + - Only applies to primary zones. + type: str + name: + description: + - Zone name. + type: str + ttl: + description: + - TTL (Time To Live) value in seconds. + type: int + type: + description: + - Zone type. + choices: ['primary', 'secondary'] + type: str requirements: - - "python >= 3.6" - - "openstacksdk" - + - "python >= 3.6" + - "openstacksdk" extends_documentation_fragment: -- openstack.cloud.openstack + - openstack.cloud.openstack ''' -EXAMPLES = ''' -# Create a zone named "example.net" -- openstack.cloud.dns_zones: +EXAMPLES = r''' +- name: Fetch all DNS zones + openstack.cloud.dns_zones: + cloud: devstack +- name: Fetch DNS zones by name + openstack.cloud.dns_zones: + cloud: devstack + name: ansible.test.zone. ''' -RETURN = ''' -zone: - description: Dictionary describing the zone. - returned: On success when I(state) is 'present'. - type: complex - contains: - action: - description: Current action in progress on the resource. - type: str - sample: "CREATE" - attributes: - description: Key:Value pairs of information about this zone, and the pool the user would like to place \ - the zone in. This information can be used by the scheduler to place zones on the correct pool. - type: dict - sample: {"tier": "gold", "ha": "true"} - created_at: - description: Date / Time when resource was created. - type: str - sample: "2014-07-07T18:25:31.275934" - description: - description: Description for this zone. - type: str - sample: "This is an example zone." - email: - description: E-mail for the zone. Used in SOA records for the zone. - type: str - sample: "test@example.org" - id: - description: ID for the resource. - type: int - sample: "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" - links: - description: Links to the resource, and other related resources. When a response has been broken into\ - pages, we will include a next link that should be followed to retrieve all results. - type: dict - sample: {"self": "https://127.0.0.1:9001/v2/zones/a86dba58-0043-4cc6-a1bb-69d5e86f3ca3"} - masters: - description: Mandatory for secondary zones. The servers to slave from to get DNS information. - type: list - sample: "[]" - name: - description: DNS Name for the zone. - type: str - sample: "test.test." - pool_id: - description: ID for the pool hosting this zone. - type: str - sample: "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" - project_id: - description: ID for the project that owns the resource. - type: str - sample: "4335d1f0-f793-11e2-b778-0800200c9a66" - serial: - description: Current serial number for the zone. - type: int - sample: 1404757531 - status: - description: Status of the resource. - type: str - sample: "ACTIVE" - ttl: - description: TTL (Time to Live) for the zone. - type: int - sample: 7200 - type: - description: Type of zone. PRIMARY is controlled by Designate, SECONDARY zones are slaved from another\ - DNS Server. Defaults to PRIMARY - type: str - sample: "PRIMARY" - updated_at: - description: Date / Time when resource last updated. - type: str - sample: "2014-07-07T18:25:31.275934" +RETURN = r''' +zones: + description: Dictionary describing the DNS zones. + returned: On success when I(state) is C(present). + type: list + elements: dict + contains: + action: + description: Current action in progress on the resource. + type: str + sample: "CREATE" + attributes: + description: Key value pairs of information about this zone, and the + pool the user would like to place the zone in. This + information can be used by the scheduler to place zones on + the correct pool. + type: dict + sample: {"tier": "gold", "ha": "true"} + created_at: + description: Date / Time when resource was created. + type: str + sample: "2014-07-07T18:25:31.275934" + description: + description: Description for this zone. + type: str + sample: "This is an example zone." + email: + description: E-mail for the zone. Used in SOA records for the zone. + type: str + sample: "test@example.org" + id: + description: ID for the resource. + type: int + sample: "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" + links: + description: Links to the resource, and other related resources. When a + response has been broken into pages, we will include a next + link that should be followed to retrieve all results. + type: dict + sample: {"self": "https://127.0.0.1:9001/v2/zones/a86dba...d5e86f3ca3"} + masters: + description: The servers to slave from to get DNS information. + Mandatory for secondary zones. + type: list + sample: "[]" + name: + description: DNS Name for the zone. + type: str + sample: "test.test." + pool_id: + description: ID for the pool hosting this zone. + type: str + sample: "a86dba58-0043-4cc6-a1bb-69d5e86f3ca3" + project_id: + description: ID for the project that owns the resource. + type: str + sample: "4335d1f0-f793-11e2-b778-0800200c9a66" + serial: + description: Current serial number for the zone. + type: int + sample: 1404757531 + status: + description: Status of the resource. + type: str + sample: "ACTIVE" + ttl: + description: TTL (Time to Live) for the zone. + type: int + sample: 7200 + type: + description: Type of zone. PRIMARY is controlled by Designate, + SECONDARY zones are slaved from another DNS Server. + Defaults to PRIMARY. + type: str + sample: "PRIMARY" + updated_at: + description: Date / Time when resource last updated. + type: str + sample: "2014-07-07T18:25:31.275934" ''' from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule @@ -130,41 +140,27 @@ from ansible_collections.openstack.cloud.plugins.module_utils.openstack import O class DnsZoneInfoModule(OpenStackModule): argument_spec = dict( - name=dict(), - type=dict(choices=['primary', 'secondary']), - email=dict(), description=dict(), - ttl=dict(type='int') + email=dict(), + name=dict(), + ttl=dict(type='int'), + type=dict(choices=['primary', 'secondary']), ) module_kwargs = dict( supports_check_mode=True ) def run(self): + kwargs = dict((k, self.params[k]) + for k in ['description', 'email', 'name', + 'ttl', 'type'] + if self.params[k] is not None) - name = self.params['name'] - type = self.params['type'] - email = self.params['email'] - description = self.params['description'] - ttl = self.params['ttl'] + zones = self.conn.dns.zones(**kwargs) - kwargs = {} - - if name: - kwargs['name'] = name - if type: - kwargs['type'] = type - if email: - kwargs['email'] = email - if description: - kwargs['description'] = description - if ttl: - kwargs['ttl'] = ttl - - data = [zone.to_dict(computed=False) for zone in - self.conn.dns.zones(**kwargs)] - - self.exit_json(zones=data, changed=False) + self.exit_json( + changed=False, + zones=[z.to_dict(computed=False) for z in zones]) def main():