text: #!/usr/bin/python
  
  # Copyright (c) 2018 Catalyst Cloud Ltd.
  # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
  
  DOCUMENTATION = '''
  ---
  module: lb_member
  short_description: Add/Delete a member for a pool in load balancer from OpenStack Cloud
  author: OpenStack Ansible SIG
  description:
     - Add or Remove a member for a pool from the OpenStack load-balancer service.
  options:
     name:
       description:
          - Name that has to be given to the member
       required: true
       type: str
     state:
       description:
         - Should the resource be present or absent.
       choices: [present, absent]
       default: present
       type: str
     pool:
       description:
          - The name or id of the pool that this member belongs to.
       required: true
       type: str
     protocol_port:
       description:
          - The protocol port number for the member.
       default: 80
       type: int
     address:
       description:
          - The IP address of the member.
       type: str
     subnet_id:
       description:
          - The subnet ID the member service is accessible from.
       type: str
     wait:
       description:
          - If the module should wait for the load balancer to be ACTIVE.
       type: bool
       default: 'yes'
     timeout:
       description:
          - The amount of time the module should wait for the load balancer to get
            into ACTIVE state.
       default: 180
       type: int
  requirements:
      - "python >= 3.6"
      - "openstacksdk"
  
  extends_documentation_fragment:
  - openstack.cloud.openstack
  '''
  
  RETURN = '''
  id:
      description: The member UUID.
      returned: On success when I(state) is 'present'
      type: str
      sample: "39007a7e-ee4f-4d13-8283-b4da2e037c69"
  member:
      description: Dictionary describing the member.
      returned: On success when I(state) is 'present'
      type: complex
      contains:
          id:
              description: Unique UUID.
              type: str
              sample: "39007a7e-ee4f-4d13-8283-b4da2e037c69"
          name:
              description: Name given to the member.
              type: str
              sample: "test"
          description:
              description: The member description.
              type: str
              sample: "description"
          provisioning_status:
              description: The provisioning status of the member.
              type: str
              sample: "ACTIVE"
          operating_status:
              description: The operating status of the member.
              type: str
              sample: "ONLINE"
          is_admin_state_up:
              description: The administrative state of the member.
              type: bool
              sample: true
          protocol_port:
              description: The protocol port number for the member.
              type: int
              sample: 80
          subnet_id:
              description: The subnet ID the member service is accessible from.
              type: str
              sample: "489247fa-9c25-11e8-9679-00224d6b7bc1"
          address:
              description: The IP address of the backend member server.
              type: str
              sample: "192.168.2.10"
  '''
  
  EXAMPLES = '''
  # Create a member, wait for the member to be created.
  - openstack.cloud.lb_member:
      cloud: mycloud
      endpoint_type: admin
      state: present
      name: test-member
      pool: test-pool
      address: 192.168.10.3
      protocol_port: 8080
  
  # Delete a listener
  - openstack.cloud.lb_member:
      cloud: mycloud
      endpoint_type: admin
      state: absent
      name: test-member
      pool: test-pool
  '''
  
  import time
  
  from ansible.module_utils.basic import AnsibleModule
  from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec,
                                                                                  openstack_module_kwargs,
                                                                                  openstack_cloud_from_module)
  
  
  def _wait_for_member_status(module, cloud, pool_id, member_id, status,
                              failures, interval=5):
      timeout = module.params['timeout']
  
      total_sleep = 0
      if failures is None:
          failures = []
  
      while total_sleep < timeout:
          member = cloud.load_balancer.get_member(member_id, pool_id)
          provisioning_status = member.provisioning_status
          if provisioning_status == status:
              return member
          if provisioning_status in failures:
              module.fail_json(
                  msg="Member %s transitioned to failure state %s" %
                      (member_id, provisioning_status)
              )
  
          time.sleep(interval)
          total_sleep += interval
  
      module.fail_json(
          msg="Timeout waiting for member %s to transition to %s" %
              (member_id, status)
      )
  
  
  def main():
      argument_spec = openstack_full_argument_spec(
          name=dict(required=True),
          state=dict(default='present', choices=['absent', 'present']),
          pool=dict(required=True),
          address=dict(default=None),
          protocol_port=dict(default=80, type='int'),
          subnet_id=dict(default=None),
      )
      module_kwargs = openstack_module_kwargs()
      module = AnsibleModule(argument_spec, **module_kwargs)
      sdk, cloud = openstack_cloud_from_module(module)
      name = module.params['name']
      pool = module.params['pool']
  
      try:
          changed = False
  
          pool_ret = cloud.load_balancer.find_pool(name_or_id=pool)
          if not pool_ret:
              module.fail_json(msg='pool %s is not found' % pool)
  
          pool_id = pool_ret.id
          member = cloud.load_balancer.find_member(name, pool_id)
  
          if module.params['state'] == 'present':
              if not member:
                  member = cloud.load_balancer.create_member(
                      pool_ret,
                      address=module.params['address'],
                      name=name,
                      protocol_port=module.params['protocol_port'],
                      subnet_id=module.params['subnet_id']
                  )
                  changed = True
  
                  if not module.params['wait']:
                      module.exit_json(changed=changed,
                                       member=member.to_dict(),
                                       id=member.id)
  
              if module.params['wait']:
                  member = _wait_for_member_status(module, cloud, pool_id,
                                                   member.id, "ACTIVE",
                                                   ["ERROR"])
  
              module.exit_json(changed=changed, member=member.to_dict(),
                               id=member.id)
  
          elif module.params['state'] == 'absent':
              if member:
                  cloud.load_balancer.delete_member(member, pool_ret)
                  changed = True
  
              module.exit_json(changed=changed)
      except sdk.exceptions.OpenStackCloudException as e:
          module.fail_json(msg=str(e), extra_data=e.extra_data)
  
  
  if __name__ == "__main__":
      main()
  