#!/usr/bin/python
#
"""
     Copyright (c) 2016 World Wide Technology, Inc.
     All rights reserved.

     Revision history:

     6 December 2016  |  1.0 - initial release

"""
DOCUMENTATION = '''

---

module: bigip_check
author: Joel W. King, World Wide Technology
version_added: "1.0"
short_description: check if BIG_IP device is ready for configuration

description:
    - Check if the BIG_IP device is responds to iControl API calls, optionally save the config and reload the device.
    - The timeout value is the dead interval, the interval value is a time between connection attempts.
    - Using the default values of 10 and 40, the four attempts are made, 10 seconds apart.

requirements:
    -  ansible-f5/icontrol_install_config.py from https://github.com/joelwking

options:
    host:
        description:
            - IP address (or hostname) of BIG_IP device
        required: true

    password:
        description:
            - password for authentication
        required: true

    username:
        description:
            - username for authentication
        required: false
        default: "admin"

    reload:
        description:
            - boolean indicating if the device should be reloaded
        required: false
        default: false

    save_config:
        description:
            - boolean indicating if the device configuration should be saved
            - the config will be saved before the option reload is attempted
        required: false
        default: false

    timeout:
        description:
            - timeout of API calls
        required: false
        default: 40

    interval:
        description:
            - time waited between checks
        required: false
        default: 10
'''

EXAMPLES = '''

  - name: check if the big_ip is ready
    bigip_check:
       host: "{{inventory_hostname}}"
       password: "{{password}}"
       username: admin    # these  arguments are optional, default values shown
       reload: false
       save_config: false
       timeout: 40
       interval: 10

'''

class Check(object):

    def __init__(self):
        self.changed = 0
        self.save_command = '{"command":"save"}'
        self.reload_command =  '{"command":"reboot"}'

    def save_config(self, device):
        device.uri =  device.validate_uri("/mgmt/tm/sys/config/")
        if device.genericPOST(self.save_command):
            return True

        return False

    def reload_device(self, device):
        device.uri =  device.validate_uri("/mgmt/tm/sys/config/")
        if device.genericPOST(self.reload_command):
            return True

        return False

    def test_ready(self, device):
        """ test if the BIG-IP is ready

        Mark's recommendation is to issue GET https://10.255.111.29/mgmt/tm/services
        and in the 'items' look for 'name' 'tmm' and 'mcpd' and 'isActive' of true

        """
        device.uri =  device.validate_uri("/mgmt/tm/sys/management-ip/")
        return device.genericGET()

    def device_changed(self):
        ""
        if self.changed:
            return True
        return False

def main():
    module = AnsibleModule(
        argument_spec=dict(
        host=dict(required=True),
        username=dict(default='admin'),
        password=dict(required=True),
        save_config=dict(default=False, type='bool'),
        reload=dict(default=False, type='bool'),
        timeout=dict(default=40, type='int'),
        interval=dict(default=10, type='int')
        )
    )

    try:
        import icontrol_install_config as iControl
    except ImportError:
        module.fail_json(msg="icontrol_install_config required for this module")
    import time

    f5 = iControl.BIG_IP(host=module.params["host"], username=module.params["username"], password=module.params["password"])
    me = Check()

    if module.params["save_config"]:
        if me.save_config(f5):
            me.changed += 1
        else:
            module.fail_json(msg="Save config failed")

    if module.params["reload"]:
        if me.reload_device(f5):
            me.changed += 1
        else:
            module.fail_json(msg="Reload failed")

    for increment in range(0, module.params["timeout"], module.params["interval"]):
        if me.test_ready(f5):
            module.exit_json(changed=me.device_changed(), msg="Ready", response=f5.response)         
        time.sleep(module.params["interval"])

    module.fail_json(msg="Device not ready")

from ansible.module_utils.basic import *
main()
#
@@ -166,16 +166,73 @@
  release
+%0A     14 December 2016 %7C  1.1 - Output device information
 %0A%0A%22%22%22%0ADO
@@ -337,17 +337,17 @@
 ded: %221.
-0
+1
 %22%0Ashort_
@@ -735,16 +735,70 @@
 s apart.
+%0A    - Output are ansible facts describing the device.
 %0A%0Arequir
@@ -2168,16 +2168,151 @@
 al: 10%0A%0A
+  - name: show facts output%0A    debug: msg=%22version is %7B%7Bbigip.version%7D%7D %7B%7Bbigip.marketingName%7D%7D %7B%7Bbigip.build%7D%7D %7B%7Bbigip.chassisId%7D%7D%22%0A%0A
 '''%0A%0Acla
@@ -3195,25 +3195,17 @@
 /tm/
-sys/management-ip
+cm/device
 /%22)%0A
@@ -3352,16 +3352,235 @@
  False%0A%0A
+    def build_facts(self, response):%0A        %22Format the output of the module as Ansible facts%22%0A        try:%0A            return response%5B%22items%22%5D%5B0%5D%0A        except:%0A            return dict(error=%22Response not valid%22)%0A%0A%0A
 def main
@@ -4722,24 +4722,72 @@
 _ready(f5):%0A
+            facts = me.build_facts(f5.response)%0A
             
@@ -4849,28 +4849,39 @@
 y%22, 
-response=f5.response
+ansible_facts=dict(bigip=facts)
 )   

Version 1.1 return facts from bigip_check