From 6578403288be2ae80177ebc44c3707ec25fa1733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Moser?= <mail@renemoser.net>
Date: Mon, 5 Mar 2018 11:42:38 +0100
Subject: [PATCH] cs_zone_facts: implement return facts as ansible returns
 (#36993)

---
 lib/ansible/module_utils/cloudstack.py        | 13 +++
 .../modules/cloud/cloudstack/cs_zone_facts.py | 92 ++++++++-----------
 .../targets/cs_zone_facts/tasks/main.yml      | 24 ++++-
 3 files changed, 75 insertions(+), 54 deletions(-)

diff --git a/lib/ansible/module_utils/cloudstack.py b/lib/ansible/module_utils/cloudstack.py
index 9c92cf82e1..3706b877f2 100644
--- a/lib/ansible/module_utils/cloudstack.py
+++ b/lib/ansible/module_utils/cloudstack.py
@@ -631,3 +631,16 @@ class AnsibleCloudStack:
             if 'tags' in resource:
                 self.result['tags'] = resource['tags']
         return self.result
+
+    def get_result_and_facts(self, facts_name, resource):
+        result = self.get_result(resource)
+
+        ansible_facts = {
+            facts_name: result.copy()
+        }
+        for k in ['diff', 'changed']:
+            if k in ansible_facts[facts_name]:
+                del ansible_facts[facts_name][k]
+
+        result.update(ansible_facts=ansible_facts)
+        return result
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_zone_facts.py b/lib/ansible/modules/cloud/cloudstack/cs_zone_facts.py
index 02af818006..6ad5f6cd28 100644
--- a/lib/ansible/modules/cloud/cloudstack/cs_zone_facts.py
+++ b/lib/ansible/modules/cloud/cloudstack/cs_zone_facts.py
@@ -1,22 +1,8 @@
 #!/usr/bin/python
 # -*- coding: utf-8 -*-
 #
-# (c) 2016, René Moser <mail@renemoser.net>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+# Copyright (c) 2016, René Moser <mail@renemoser.net>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
 
 ANSIBLE_METADATA = {'metadata_version': '1.1',
                     'status': ['stableinterface'],
@@ -28,7 +14,8 @@ DOCUMENTATION = '''
 module: cs_zone_facts
 short_description: Gathering facts of zones from Apache CloudStack based clouds.
 description:
-    - Gathering facts from the API of a zone.
+  - Gathering facts from the API of a zone.
+  - Sets Ansible facts accessable by the key C(cloudstack_zone) and since version 2.6 also returns results.
 version_added: "2.1"
 author: "René Moser (@resmo)"
 options:
@@ -41,102 +28,109 @@ extends_documentation_fragment: cloudstack
 '''
 
 EXAMPLES = '''
-- cs_zone_facts:
+- name: Gather facts from a zone
+  local_action:
+    module: cs_zone_facts
     name: ch-gva-1
-  delegate_to: localhost
+  register: zone
 
-- debug:
+- name: Show the returned results of the registered variable
+  debug:
+    var: zone
+
+- name: Show the facts by the ansible_facts key cloudstack_zone
+  debug:
     var: cloudstack_zone
 '''
 
 RETURN = '''
 ---
-cloudstack_zone.id:
+id:
   description: UUID of the zone.
   returned: success
   type: string
   sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-cloudstack_zone.name:
+name:
   description: Name of the zone.
   returned: success
   type: string
   sample: zone01
-cloudstack_zone.dns1:
+dns1:
   description: First DNS for the zone.
   returned: success
   type: string
   sample: 8.8.8.8
-cloudstack_zone.dns2:
+dns2:
   description: Second DNS for the zone.
   returned: success
   type: string
   sample: 8.8.4.4
-cloudstack_zone.internal_dns1:
+internal_dns1:
   description: First internal DNS for the zone.
   returned: success
   type: string
   sample: 8.8.8.8
-cloudstack_zone.internal_dns2:
+internal_dns2:
   description: Second internal DNS for the zone.
   returned: success
   type: string
   sample: 8.8.4.4
-cloudstack_zone.dns1_ipv6:
+dns1_ipv6:
   description: First IPv6 DNS for the zone.
   returned: success
   type: string
   sample: "2001:4860:4860::8888"
-cloudstack_zone.dns2_ipv6:
+dns2_ipv6:
   description: Second IPv6 DNS for the zone.
   returned: success
   type: string
   sample: "2001:4860:4860::8844"
-cloudstack_zone.allocation_state:
+allocation_state:
   description: State of the zone.
   returned: success
   type: string
   sample: Enabled
-cloudstack_zone.domain:
+domain:
   description: Domain the zone is related to.
   returned: success
   type: string
   sample: ROOT
-cloudstack_zone.network_domain:
+network_domain:
   description: Network domain for the zone.
   returned: success
   type: string
   sample: example.com
-cloudstack_zone.network_type:
+network_type:
   description: Network type for the zone.
   returned: success
   type: string
   sample: basic
-cloudstack_zone.local_storage_enabled:
+local_storage_enabled:
   description: Local storage offering enabled.
   returned: success
   type: bool
   sample: false
-cloudstack_zone.securitygroups_enabled:
+securitygroups_enabled:
   description: Security groups support is enabled.
   returned: success
   type: bool
   sample: false
-cloudstack_zone.guest_cidr_address:
+guest_cidr_address:
   description: Guest CIDR address for the zone
   returned: success
   type: string
   sample: 10.1.1.0/24
-cloudstack_zone.dhcp_provider:
+dhcp_provider:
   description: DHCP provider for the zone
   returned: success
   type: string
   sample: VirtualRouter
-cloudstack_zone.zone_token:
+zone_token:
   description: Zone token
   returned: success
   type: string
   sample: ccb0a60c-79c8-3230-ab8b-8bdbe8c45bb7
-cloudstack_zone.tags:
+tags:
   description: List of resource tags associated with the zone.
   returned: success
   type: dict
@@ -170,19 +164,9 @@ class AnsibleCloudStackZoneFacts(AnsibleCloudStack):
             'allocationstate': 'allocation_state',
             'zonetoken': 'zone_token',
         }
-        self.facts = {
-            'cloudstack_zone': None,
-        }
 
     def get_zone(self):
-        if not self.zone:
-            super(AnsibleCloudStackZoneFacts, self).get_zone()
-        return self.zone
-
-    def run(self):
-        zone = self.get_zone()
-        self.facts['cloudstack_zone'] = self.get_result(zone)
-        return self.facts
+        return super(AnsibleCloudStackZoneFacts, self).get_zone()
 
 
 def main():
@@ -196,10 +180,12 @@ def main():
         supports_check_mode=True,
     )
 
-    cs_zone_facts = AnsibleCloudStackZoneFacts(module=module).run()
-    cs_facts_result = dict(changed=False, ansible_facts=cs_zone_facts)
-
-    module.exit_json(**cs_facts_result)
+    acs_zone_facts = AnsibleCloudStackZoneFacts(module=module)
+    result = acs_zone_facts.get_result_and_facts(
+        facts_name='cloudstack_zone',
+        resource=acs_zone_facts.get_zone()
+    )
+    module.exit_json(**result)
 
 
 if __name__ == '__main__':
diff --git a/test/integration/targets/cs_zone_facts/tasks/main.yml b/test/integration/targets/cs_zone_facts/tasks/main.yml
index 7da41fad98..f137ab3197 100644
--- a/test/integration/targets/cs_zone_facts/tasks/main.yml
+++ b/test/integration/targets/cs_zone_facts/tasks/main.yml
@@ -15,12 +15,23 @@
   cs_zone_facts:
     name: "{{ cs_resource_prefix }}-zone"
   register: zone
-  check_mode: true
+  check_mode: yes
 - name: verify  get facts from zone in check mode
   assert:
     that:
       - zone is successful
       - zone is not changed
+      - zone.dns1 == "8.8.8.8"
+      - zone.dns2 == "8.8.4.4"
+      - zone.internal_dns1 == "8.8.8.8"
+      - zone.internal_dns2 == "8.8.4.4"
+      - zone.local_storage_enabled == false
+      - zone.network_type == "Basic"
+      - zone.zone_token != ""
+      - zone.securitygroups_enabled == true
+      - zone.dhcp_provider == "VirtualRouter"
+      - zone.local_storage_enabled == false
+      # Ansible Facts
       - cloudstack_zone.dns1 == "8.8.8.8"
       - cloudstack_zone.dns2 == "8.8.4.4"
       - cloudstack_zone.internal_dns1 == "8.8.8.8"
@@ -41,6 +52,17 @@
     that:
       - zone is successful
       - zone is not changed
+      - zone.dns1 == "8.8.8.8"
+      - zone.dns2 == "8.8.4.4"
+      - zone.internal_dns1 == "8.8.8.8"
+      - zone.internal_dns2 == "8.8.4.4"
+      - zone.local_storage_enabled == false
+      - zone.network_type == "Basic"
+      - zone.zone_token != ""
+      - zone.securitygroups_enabled == true
+      - zone.dhcp_provider == "VirtualRouter"
+      - zone.local_storage_enabled == false
+      # Ansible Facts
       - cloudstack_zone.dns1 == "8.8.8.8"
       - cloudstack_zone.dns2 == "8.8.4.4"
       - cloudstack_zone.internal_dns1 == "8.8.8.8"