Example #1
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            virtual_server=dict(type='str',
                                aliases=['vip', 'virtual'],
                                required=True),
            virtual_server_ip=dict(type='str',
                                   aliases=['ip', 'address'],
                                   required=True),
            virtual_server_status=dict(type='str',
                                       default='enabled',
                                       aliases=['status'],
                                       choices=['enabled', 'disabled']),
            virtual_server_ports=dict(type='list', required=True),
            partition=dict(type='str', default=[]),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_virtual = module.params['virtual_server']
    slb_virtual_ip = module.params['virtual_server_ip']
    slb_virtual_status = module.params['virtual_server_status']
    slb_virtual_ports = module.params['virtual_server_ports']

    if slb_virtual is None:
        module.fail_json(msg='virtual_server is required')

    validate_ports(module, slb_virtual_ports)

    axapi_base_url = 'https://%s/services/rest/V2.1/?format=json' % host
    session_url = axapi_authenticate(module, axapi_base_url, username,
                                     password)

    slb_server_partition = axapi_call(
        module, session_url + '&method=system.partition.active',
        json.dumps({'name': partition}))
    slb_virtual_data = axapi_call(
        module, session_url + '&method=slb.virtual_server.search',
        json.dumps({'name': slb_virtual}))
    slb_virtual_exists = not axapi_failure(slb_virtual_data)

    changed = False
    if state == 'present':
        json_post = {
            'virtual_server': {
                'name': slb_virtual,
                'address': slb_virtual_ip,
                'status': axapi_enabled_disabled(slb_virtual_status),
                'vport_list': slb_virtual_ports,
            }
        }

        # before creating/updating we need to validate that any
        # service groups defined in the ports list exist since
        # since the API will still create port definitions for
        # them while indicating a failure occurred
        checked_service_groups = []
        for port in slb_virtual_ports:
            if 'service_group' in port and port[
                    'service_group'] not in checked_service_groups:
                # skip blank service group entries
                if port['service_group'] == '':
                    continue
                result = axapi_call(
                    module, session_url + '&method=slb.service_group.search',
                    json.dumps({'name': port['service_group']}))
                if axapi_failure(result):
                    module.fail_json(
                        msg=
                        "the service group %s specified in the ports list does not exist"
                        % port['service_group'])
                checked_service_groups.append(port['service_group'])

        if not slb_virtual_exists:
            result = axapi_call(
                module, session_url + '&method=slb.virtual_server.create',
                json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(
                    msg="failed to create the virtual server: %s" %
                    result['response']['err']['msg'])
            changed = True
        else:

            def needs_update(src_ports, dst_ports):
                '''
                Checks to determine if the port definitions of the src_ports
                array are in or different from those in dst_ports. If there is
                a difference, this function returns true, otherwise false.
                '''
                for src_port in src_ports:
                    found = False
                    different = False
                    for dst_port in dst_ports:
                        if src_port['port'] == dst_port['port']:
                            found = True
                            for valid_field in VALID_PORT_FIELDS:
                                if src_port[valid_field] != dst_port[
                                        valid_field]:
                                    different = True
                                    break
                            if found or different:
                                break
                    if not found or different:
                        return True
                # every port from the src exists in the dst, and none of them were different
                return False

            defined_ports = slb_virtual_data.get('virtual_server',
                                                 {}).get('vport_list', [])

            # we check for a needed update both ways, in case ports
            # are missing from either the ones specified by the user
            # or from those on the device
            if needs_update(defined_ports, slb_virtual_ports) or needs_update(
                    slb_virtual_ports, defined_ports):
                result = axapi_call(
                    module, session_url + '&method=slb.virtual_server.update',
                    json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(
                        msg="failed to create the virtual server: %s" %
                        result['response']['err']['msg'])
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(
                module, session_url + '&method=slb.virtual_server.search',
                json.dumps({'name': slb_virtual}))
        else:
            result = slb_virtual_data
    elif state == 'absent':
        if slb_virtual_exists:
            result = axapi_call(
                module, session_url + '&method=slb.virtual_server.delete',
                json.dumps({'name': slb_virtual}))
            changed = True
        else:
            result = dict(msg="the virtual server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(
            module, session_url + '&method=system.action.write_memory')
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out of the session nicely and exit
    axapi_call(module, session_url + '&method=session.close')
    module.exit_json(changed=changed, content=result)
Example #2
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            operation=dict(type='str', default='create', choices=['create', 'update', 'delete']),
            server_name=dict(type='str', aliases=['server'], required=True),
            server_ip=dict(type='str', aliases=['ip', 'address'], required=True),
            server_status=dict(type='str', default='enable', aliases=['action'], choices=['enable', 'disable']),
            server_ports=dict(type='list', aliases=['port'], default=[]),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False
    )

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    operation = module.params['operation']
    write_config = module.params['write_config']
    slb_server = module.params['server_name']
    slb_server_ip = module.params['server_ip']
    slb_server_status = module.params['server_status']
    slb_server_ports = module.params['server_ports']

    axapi_base_url = 'https://{}/axapi/v3/'.format(host)
    axapi_auth_url = axapi_base_url + 'auth/'
    signature = axapi_authenticate_v3(module, axapi_auth_url, username, password)

    # validate the ports data structure
    validate_ports(module, slb_server_ports)


    json_post = {
        "server-list": [
            {
                "name": slb_server,
                "host": slb_server_ip
            }
        ]
    }

    # add optional module parameters
    if slb_server_ports:
        json_post['server-list'][0]['port-list'] = slb_server_ports

    if slb_server_status:
        json_post['server-list'][0]['action'] = slb_server_status

    slb_server_data = axapi_call_v3(module, axapi_base_url+'slb/server/', method='GET', body='', signature=signature)

    # for empty slb server list
    if axapi_failure(slb_server_data):
        slb_server_exists = False
    else:
        slb_server_list = [server['name'] for server in slb_server_data['server-list']]
        if slb_server in slb_server_list:
            slb_server_exists = True
        else:
            slb_server_exists = False

    changed = False
    if operation == 'create':
        if slb_server_exists is False:
            result = axapi_call_v3(module, axapi_base_url+'slb/server/', method='POST', body=json.dumps(json_post), signature=signature)
            if axapi_failure(result):
                module.fail_json(msg="failed to create the server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            module.fail_json(msg="server already exists, use state='update' instead")
            changed = False
        # if we changed things, get the full info regarding result
        if changed:
            result = axapi_call_v3(module, axapi_base_url + 'slb/server/' + slb_server, method='GET', body='', signature=signature)
        else:
            result = slb_server_data
    elif operation == 'delete':
        if slb_server_exists:
            result = axapi_call_v3(module, axapi_base_url + 'slb/server/' + slb_server, method='DELETE', body='', signature=signature)
            if axapi_failure(result):
                module.fail_json(msg="failed to delete server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the server was not present")
    elif operation == 'update':
        if slb_server_exists:
            result = axapi_call_v3(module, axapi_base_url + 'slb/server/', method='PUT', body=json.dumps(json_post), signature=signature)
            if axapi_failure(result):
                module.fail_json(msg="failed to update server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call_v3(module, axapi_base_url+'write/memory/', method='POST', body='', signature=signature)
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" % write_result['response']['err']['msg'])

    # log out gracefully and exit
    axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
    module.exit_json(changed=changed, content=result)
Example #3
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str', default='present', choices=['present', 'absent']),
            virtual_server=dict(type='str', aliases=['vip', 'virtual'], required=True),
            virtual_server_ip=dict(type='str', aliases=['ip', 'address'], required=True),
            virtual_server_status=dict(type='str', default='enabled', aliases=['status'], choices=['enabled', 'disabled']),
            virtual_server_ports=dict(type='list', required=True),
            partition=dict(type='str', default=[]),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False
    )

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_virtual = module.params['virtual_server']
    slb_virtual_ip = module.params['virtual_server_ip']
    slb_virtual_status = module.params['virtual_server_status']
    slb_virtual_ports = module.params['virtual_server_ports']

    if slb_virtual is None:
        module.fail_json(msg='virtual_server is required')

    validate_ports(module, slb_virtual_ports)

    axapi_base_url = 'https://%s/services/rest/V2.1/?format=json' % host
    session_url = axapi_authenticate(module, axapi_base_url, username, password)

    axapi_call(module, session_url + '&method=system.partition.active', json.dumps({'name': partition}))
    slb_virtual_data = axapi_call(module, session_url + '&method=slb.virtual_server.search', json.dumps({'name': slb_virtual}))
    slb_virtual_exists = not axapi_failure(slb_virtual_data)

    changed = False
    if state == 'present':
        json_post = {
            'virtual_server': {
                'name': slb_virtual,
                'address': slb_virtual_ip,
                'status': axapi_enabled_disabled(slb_virtual_status),
                'vport_list': slb_virtual_ports,
            }
        }

        # before creating/updating we need to validate that any
        # service groups defined in the ports list exist since
        # since the API will still create port definitions for
        # them while indicating a failure occurred
        checked_service_groups = []
        for port in slb_virtual_ports:
            if 'service_group' in port and port['service_group'] not in checked_service_groups:
                # skip blank service group entries
                if port['service_group'] == '':
                    continue
                result = axapi_call(module, session_url + '&method=slb.service_group.search', json.dumps({'name': port['service_group']}))
                if axapi_failure(result):
                    module.fail_json(msg="the service group %s specified in the ports list does not exist" % port['service_group'])
                checked_service_groups.append(port['service_group'])

        if not slb_virtual_exists:
            result = axapi_call(module, session_url + '&method=slb.virtual_server.create', json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(msg="failed to create the virtual server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            def needs_update(src_ports, dst_ports):
                '''
                Checks to determine if the port definitions of the src_ports
                array are in or different from those in dst_ports. If there is
                a difference, this function returns true, otherwise false.
                '''
                for src_port in src_ports:
                    found = False
                    different = False
                    for dst_port in dst_ports:
                        if src_port['port'] == dst_port['port']:
                            found = True
                            for valid_field in VALID_PORT_FIELDS:
                                if src_port[valid_field] != dst_port[valid_field]:
                                    different = True
                                    break
                            if found or different:
                                break
                    if not found or different:
                        return True
                # every port from the src exists in the dst, and none of them were different
                return False

            defined_ports = slb_virtual_data.get('virtual_server', {}).get('vport_list', [])

            # we check for a needed update both ways, in case ports
            # are missing from either the ones specified by the user
            # or from those on the device
            if needs_update(defined_ports, slb_virtual_ports) or needs_update(slb_virtual_ports, defined_ports):
                result = axapi_call(module, session_url + '&method=slb.virtual_server.update', json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(msg="failed to create the virtual server: %s" % result['response']['err']['msg'])
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(module, session_url + '&method=slb.virtual_server.search', json.dumps({'name': slb_virtual}))
        else:
            result = slb_virtual_data
    elif state == 'absent':
        if slb_virtual_exists:
            result = axapi_call(module, session_url + '&method=slb.virtual_server.delete', json.dumps({'name': slb_virtual}))
            changed = True
        else:
            result = dict(msg="the virtual server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(module, session_url + '&method=system.action.write_memory')
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" % write_result['response']['err']['msg'])

    # log out of the session nicely and exit
    axapi_call(module, session_url + '&method=session.close')
    module.exit_json(changed=changed, content=result)
Example #4
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            partition=dict(type='str',
                           aliases=['partition', 'part'],
                           required=False),
            file_name=dict(type='str', aliases=['filename'], required=False),
            method=dict(type='str',
                        choices=['upload', 'download'],
                        required=False),
            overwrite=dict(type='bool', default=False, required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    part = module.params['partition']
    state = module.params['state']
    file_name = module.params['file_name']
    method = module.params['method']
    overwrite = module.params['overwrite']

    if method and method != 'upload' and method != 'download':
        module.fail_json(msg="method must be one of 'upload' or 'download'")

    # authenticate
    axapi_base_url = 'https://%s/axapi/v3/' % host
    signature = axapi_authenticate_v3(module, axapi_base_url + 'auth',
                                      username, password)

    # change partitions if we need to
    if part:
        part_change_result = axapi_call_v3(module,
                                           axapi_base_url +
                                           'active-partition/' + part,
                                           method="POST",
                                           signature=signature,
                                           body="")
        if (part_change_result['response']['status'] == 'fail'):
            # log out of the session nicely and exit with an error
            result = axapi_call_v3(module,
                                   axapi_base_url + 'logoff',
                                   method="POST",
                                   signature=signature,
                                   body="")
            module.fail_json(msg=part_change_result['response']['err']['msg'])

    # look for the aflex script on the device
    aflex_data = axapi_call_v3(module,
                               axapi_base_url + 'file/aflex/' + file_name,
                               method="GET",
                               signature=signature)
    aflex_content = ""

    if ('response' in aflex_data
            and aflex_data['response']['status'] == 'fail'):
        if (aflex_data['response']['code'] == 404):
            aflex_exists = False
        else:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=aflex_data['response']['err']['msg'])
    else:
        aflex_content = aflex_data['response']['data']
        aflex_exists = True

    changed = False
    if state == 'present':

        if (method == "upload" and aflex_exists
                and overwrite) or (method == "upload" and not aflex_exists):

            if os.path.isfile(file_name) is False:
                # log out of the session nicely and exit with an error
                result = axapi_call_v3(module,
                                       axapi_base_url + 'logoff',
                                       method="POST",
                                       signature=signature,
                                       body="")
                module.fail_json(msg='File does not exist ' + file_name)
            else:
                try:
                    result = uploadAflex(axapi_base_url + 'file/aflex',
                                         file_name,
                                         file_name,
                                         signature=signature)
                except Exception, e:
                    # log out of the session nicely and exit with an error
                    #err_result = e['changed']
                    result = axapi_call_v3(module,
                                           axapi_base_url + 'logoff',
                                           method="POST",
                                           signature=signature,
                                           body="")
                    module.fail_json(msg=e)

            if axapi_failure(result):
                # log out of the session nicely and exit with an error
                result = axapi_call_v3(module,
                                       axapi_base_url + 'logoff',
                                       method="POST",
                                       signature=signature,
                                       body="")
                module.fail_json(msg="failed to upload the aflex: %s" %
                                 result['response']['err']['msg'])

            changed = True

        elif method == "download" and aflex_exists:
            saveFile(file_name, aflex_content)

        elif method == "download" and not aflex_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'logoff',
                                   method="POST",
                                   signature=signature,
                                   body="")
            module.fail_json(msg="aflex cannot be found the device")
Example #5
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            server_name=dict(type='str', aliases=['server'], required=True),
            server_ip=dict(type='str', aliases=['ip', 'address']),
            server_status=dict(type='str',
                               default='enabled',
                               aliases=['status'],
                               choices=['enabled', 'disabled']),
            server_ports=dict(type='list', aliases=['port'], default=[]),
            partition=dict(type='str', default=[]),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    partition = module.params['partition']
    username = module.params['username']
    password = module.params['password']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_server = module.params['server_name']
    slb_server_ip = module.params['server_ip']
    slb_server_status = module.params['server_status']
    slb_server_ports = module.params['server_ports']

    if slb_server is None:
        module.fail_json(msg='server_name is required')

    axapi_base_url = 'https://%s/services/rest/V2.1/?format=json' % host
    session_url = axapi_authenticate(module, axapi_base_url, username,
                                     password)

    # validate the ports data structure
    validate_ports(module, slb_server_ports)

    json_post = {
        'server': {
            'name': slb_server,
        }
    }

    # add optional module parameters
    if slb_server_ip:
        json_post['server']['host'] = slb_server_ip

    if slb_server_ports:
        json_post['server']['port_list'] = slb_server_ports

    if slb_server_status:
        json_post['server']['status'] = axapi_enabled_disabled(
            slb_server_status)

    slb_server_partition = axapi_call(
        module, session_url + '&method=system.partition.active',
        json.dumps({'name': partition}))

    slb_server_data = axapi_call(module,
                                 session_url + '&method=slb.server.search',
                                 json.dumps({'name': slb_server}))
    slb_server_exists = not axapi_failure(slb_server_data)

    changed = False
    if state == 'present':
        if not slb_server_exists:
            if not slb_server_ip:
                module.fail_json(
                    msg='you must specify an IP address when creating a server'
                )

            result = axapi_call(module,
                                session_url + '&method=slb.server.create',
                                json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(msg="failed to create the server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:

            def port_needs_update(src_ports, dst_ports):
                '''
                Checks to determine if the port definitions of the src_ports
                array are in or different from those in dst_ports. If there is
                a difference, this function returns true, otherwise false.
                '''
                for src_port in src_ports:
                    found = False
                    different = False
                    for dst_port in dst_ports:
                        if src_port['port_num'] == dst_port['port_num']:
                            found = True
                            for valid_field in VALID_PORT_FIELDS:
                                if src_port[valid_field] != dst_port[
                                        valid_field]:
                                    different = True
                                    break
                            if found or different:
                                break
                    if not found or different:
                        return True
                # every port from the src exists in the dst, and none of them were different
                return False

            def status_needs_update(current_status, new_status):
                '''
                Check to determine if we want to change the status of a server.
                If there is a difference between the current status of the server and
                the desired status, return true, otherwise false.
                '''
                if current_status != new_status:
                    return True
                return False

            defined_ports = slb_server_data.get('server',
                                                {}).get('port_list', [])
            current_status = slb_server_data.get('server', {}).get('status')

            # we check for a needed update several ways
            # - in case ports are missing from the ones specified by the user
            # - in case ports are missing from those on the device
            # - in case we are change the status of a server
            if port_needs_update(
                    defined_ports, slb_server_ports) or port_needs_update(
                        slb_server_ports,
                        defined_ports) or status_needs_update(
                            current_status,
                            axapi_enabled_disabled(slb_server_status)):
                result = axapi_call(module,
                                    session_url + '&method=slb.server.update',
                                    json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(msg="failed to update the server: %s" %
                                     result['response']['err']['msg'])
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(module,
                                session_url + '&method=slb.server.search',
                                json.dumps({'name': slb_server}))
        else:
            result = slb_server_data
    elif state == 'absent':
        if slb_server_exists:
            result = axapi_call(module,
                                session_url + '&method=slb.server.delete',
                                json.dumps({'name': slb_server}))
            changed = True
        else:
            result = dict(msg="the server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(
            module, session_url + '&method=system.action.write_memory')
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out of the session nicely and exit
    axapi_call(module, session_url + '&method=session.close')
    module.exit_json(changed=changed, content=result)
Example #6
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            operation=dict(type='str',
                           default='create',
                           choices=['create', 'update', 'delete']),
            service_group=dict(type='str',
                               aliases=['service', 'pool', 'group'],
                               required=True),
            service_group_protocol=dict(type='str',
                                        default='tcp',
                                        aliases=['proto', 'protocol'],
                                        choices=['tcp', 'udp']),
            service_group_lb_method=dict(
                type='str',
                required=False,
                aliases=['lb-method'],
                choices=[
                    'dst-ip-hash', 'dst-ip-only-hash', 'fastest-response',
                    'least-request', 'src-ip-hash', 'src-ip-only-hash',
                    'weighted-rr', 'round-robin', 'round-robin-strict'
                ]),
            service_group_lc_method=dict(
                type='str',
                required=False,
                aliases=['lc-method'],
                choices=[
                    'least-connection', 'service-least-connection',
                    'weighted-least-connection',
                    'service-weighted-least-connection'
                ]),
            servers=dict(type='list', aliases=['server', 'member'],
                         default=[]),
            partition=dict(type='str', required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    operation = module.params['operation']
    write_config = module.params['write_config']
    slb_service_group = module.params['service_group']
    slb_service_group_proto = module.params['service_group_protocol']
    slb_service_group_lb_method = module.params['service_group_lb_method']
    slb_service_group_lc_method = module.params['service_group_lc_method']
    slb_servers = module.params['servers']

    # validate if service group name exists
    if slb_service_group is None:
        module.fail_json(msg='service_group is required')

    # validate the server list with using validate_servers
    validate_servers(module, slb_servers)

    # validate if there is both lb-method and lc-method
    if slb_service_group_lb_method and slb_service_group_lc_method:
        module.fail_json(
            msg=
            'service_group_lb_method and service_group_lc_method are mutually exclusive'
        )

    # Initialize JSON to be POST
    json_post = {
        "service-group": {
            "name": slb_service_group,
            "protocol": slb_service_group_proto,
        }
    }

    json_post_create = {"service-group-list": [{}]}

    # add optional module parameters to JSON
    if slb_servers:
        json_post['service-group']['member-list'] = slb_servers

    if slb_service_group_lb_method:
        json_post['service-group']['lb-method'] = slb_service_group_lb_method

    if slb_service_group_lc_method:
        json_post['service-group']['lc-method'] = slb_service_group_lc_method

    json_post_create['service-group-list'][0] = json_post['service-group']

    # login A10 device and own signature
    axapi_base_url = 'https://{}/axapi/v3/'.format(host)
    axapi_auth_url = axapi_base_url + 'auth/'
    signature = axapi_authenticate_v3(module, axapi_auth_url, username,
                                      password)

    # GET existing partition list and check if the partition indicated in the playbook exists
    if partition:
        partition_list = axapi_call_v3(module,
                                       axapi_base_url + 'partition/',
                                       method='GET',
                                       body='',
                                       signature=signature)
        if axapi_failure(partition_list):
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(msg="There is no partition on the device: %s" %
                             (host))
        else:
            partition_list = [
                partition_attr['partition-name']
                for partition_attr in partition_list['partition-list']
            ]
            if partition in partition_list:
                result = axapi_call_v3(module,
                                       axapi_base_url + 'active-partition/' +
                                       partition,
                                       method='POST',
                                       body='',
                                       signature=signature)
                if axapi_failure(result):
                    axapi_call_v3(module,
                                  axapi_base_url + 'logoff/',
                                  method='POST',
                                  body='',
                                  signature=signature)
                    module.fail_json(
                        msg="failed to create the service group: %s" %
                        result['response']['err']['msg'])
            else:
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="The partition does not exist: %s" %
                                 (partition))

    # GET existing service groups and check if the service group already exists
    slb_service_group_data = axapi_call_v3(module,
                                           axapi_base_url +
                                           'slb/service-group/',
                                           method='GET',
                                           body='',
                                           signature=signature)
    if axapi_failure(slb_service_group_data):
        slb_service_group_exists = False
    else:
        slb_service_group_list = [
            service_group['name']
            for service_group in slb_service_group_data['service-group-list']
        ]
        if slb_service_group in slb_service_group_list:
            slb_service_group_exists = True
        else:
            slb_service_group_exists = False

    # POST configuration
    changed = False
    if operation == 'create':
        if slb_service_group_exists is False:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/',
                                   method='POST',
                                   body=json.dumps(json_post_create),
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to create the service group: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            changed = False
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(
                msg="service group already exists, use state='update' instead")
        # if we changed things, get the full info regarding result
        if changed:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/' +
                                   slb_service_group,
                                   method='GET',
                                   body='',
                                   signature=signature)
        else:
            result = slb_service_group_data
    elif operation == 'delete':
        if slb_service_group_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/' +
                                   slb_service_group,
                                   method='DELETE',
                                   body='',
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to delete service group: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the service group was not present")
    elif operation == 'update':
        if slb_service_group_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/' +
                                   slb_service_group,
                                   method='PUT',
                                   body=json.dumps(json_post),
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to update service group: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the service group was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call_v3(module,
                                     axapi_base_url + 'write/memory/',
                                     method='POST',
                                     body='',
                                     signature=signature)
        if axapi_failure(write_result):
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out gracefully and exit
    axapi_call_v3(module,
                  axapi_base_url + 'logoff/',
                  method='POST',
                  body='',
                  signature=signature)
    module.exit_json(changed=changed, content=result)
Example #7
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type="str", default="present", choices=["present", "absent"]),
            server_name=dict(type="str", aliases=["server"], required=True),
            server_ip=dict(type="str", aliases=["ip", "address"]),
            server_status=dict(type="str", default="enabled", aliases=["status"], choices=["enabled", "disabled"]),
            server_ports=dict(type="list", aliases=["port"], default=[]),
            partition=dict(type="str", default=[]),
        )
    )

    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False)

    host = module.params["host"]
    partition = module.params["partition"]
    username = module.params["username"]
    password = module.params["password"]
    state = module.params["state"]
    write_config = module.params["write_config"]
    slb_server = module.params["server_name"]
    slb_server_ip = module.params["server_ip"]
    slb_server_status = module.params["server_status"]
    slb_server_ports = module.params["server_ports"]

    if slb_server is None:
        module.fail_json(msg="server_name is required")

    axapi_base_url = "https://%s/services/rest/V2.1/?format=json" % host
    session_url = axapi_authenticate(module, axapi_base_url, username, password)

    # validate the ports data structure
    validate_ports(module, slb_server_ports)

    json_post = {"server": {"name": slb_server}}

    # add optional module parameters
    if slb_server_ip:
        json_post["server"]["host"] = slb_server_ip

    if slb_server_ports:
        json_post["server"]["port_list"] = slb_server_ports

    if slb_server_status:
        json_post["server"]["status"] = axapi_enabled_disabled(slb_server_status)

    slb_server_partition = axapi_call(
        module, session_url + "&method=system.partition.active", json.dumps({"name": partition})
    )

    slb_server_data = axapi_call(module, session_url + "&method=slb.server.search", json.dumps({"name": slb_server}))
    slb_server_exists = not axapi_failure(slb_server_data)

    changed = False
    if state == "present":
        if not slb_server_exists:
            if not slb_server_ip:
                module.fail_json(msg="you must specify an IP address when creating a server")

            result = axapi_call(module, session_url + "&method=slb.server.create", json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(msg="failed to create the server: %s" % result["response"]["err"]["msg"])
            changed = True
        else:

            def port_needs_update(src_ports, dst_ports):
                """
                Checks to determine if the port definitions of the src_ports
                array are in or different from those in dst_ports. If there is
                a difference, this function returns true, otherwise false.
                """
                for src_port in src_ports:
                    found = False
                    different = False
                    for dst_port in dst_ports:
                        if src_port["port_num"] == dst_port["port_num"]:
                            found = True
                            for valid_field in VALID_PORT_FIELDS:
                                if src_port[valid_field] != dst_port[valid_field]:
                                    different = True
                                    break
                            if found or different:
                                break
                    if not found or different:
                        return True
                # every port from the src exists in the dst, and none of them were different
                return False

            def status_needs_update(current_status, new_status):
                """
                Check to determine if we want to change the status of a server.
                If there is a difference between the current status of the server and
                the desired status, return true, otherwise false.
                """
                if current_status != new_status:
                    return True
                return False

            defined_ports = slb_server_data.get("server", {}).get("port_list", [])
            current_status = slb_server_data.get("server", {}).get("status")

            # we check for a needed update several ways
            # - in case ports are missing from the ones specified by the user
            # - in case ports are missing from those on the device
            # - in case we are change the status of a server
            if (
                port_needs_update(defined_ports, slb_server_ports)
                or port_needs_update(slb_server_ports, defined_ports)
                or status_needs_update(current_status, axapi_enabled_disabled(slb_server_status))
            ):
                result = axapi_call(module, session_url + "&method=slb.server.update", json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(msg="failed to update the server: %s" % result["response"]["err"]["msg"])
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(module, session_url + "&method=slb.server.search", json.dumps({"name": slb_server}))
        else:
            result = slb_server_data
    elif state == "absent":
        if slb_server_exists:
            result = axapi_call(module, session_url + "&method=slb.server.delete", json.dumps({"name": slb_server}))
            changed = True
        else:
            result = dict(msg="the server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(module, session_url + "&method=system.action.write_memory")
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" % write_result["response"]["err"]["msg"])

    # log out of the session nicely and exit
    axapi_call(module, session_url + "&method=session.close")
    module.exit_json(changed=changed, content=result)
Example #8
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str', default='present', choices=['present', 'absent']),
            service_group=dict(type='str', aliases=['service', 'pool', 'group'], required=True),
            service_group_protocol=dict(type='str', default='tcp', aliases=['proto', 'protocol'], choices=['tcp', 'udp']),
            service_group_method=dict(type='str', default='round-robin',
                                      aliases=['method'],
                                      choices=['round-robin',
                                               'weighted-rr',
                                               'least-connection',
                                               'weighted-least-connection',
                                               'service-least-connection',
                                               'service-weighted-least-connection',
                                               'fastest-response',
                                               'least-request',
                                               'round-robin-strict',
                                               'src-ip-only-hash',
                                               'src-ip-hash']),
            servers=dict(type='list', aliases=['server', 'member'], default=[]),
            partition=dict(type='str', default=[]),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False
    )

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_service_group = module.params['service_group']
    slb_service_group_proto = module.params['service_group_protocol']
    slb_service_group_method = module.params['service_group_method']
    slb_servers = module.params['servers']

    if slb_service_group is None:
        module.fail_json(msg='service_group is required')

    axapi_base_url = 'https://' + host + '/services/rest/V2.1/?format=json'
    load_balancing_methods = {'round-robin': 0,
                              'weighted-rr': 1,
                              'least-connection': 2,
                              'weighted-least-connection': 3,
                              'service-least-connection': 4,
                              'service-weighted-least-connection': 5,
                              'fastest-response': 6,
                              'least-request': 7,
                              'round-robin-strict': 8,
                              'src-ip-only-hash': 14,
                              'src-ip-hash': 15}

    if not slb_service_group_proto or slb_service_group_proto.lower() == 'tcp':
        protocol = 2
    else:
        protocol = 3

    # validate the server data list structure
    validate_servers(module, slb_servers)

    json_post = {
        'service_group': {
            'name': slb_service_group,
            'protocol': protocol,
            'lb_method': load_balancing_methods[slb_service_group_method],
        }
    }

    # first we authenticate to get a session id
    session_url = axapi_authenticate(module, axapi_base_url, username, password)
    # then we select the active-partition
    slb_server_partition = axapi_call(module, session_url + '&method=system.partition.active', json.dumps({'name': partition}))
    # then we check to see if the specified group exists
    slb_result = axapi_call(module, session_url + '&method=slb.service_group.search', json.dumps({'name': slb_service_group}))
    slb_service_group_exist = not axapi_failure(slb_result)

    changed = False
    if state == 'present':
        # before creating/updating we need to validate that servers
        # defined in the servers list exist to prevent errors
        checked_servers = []
        for server in slb_servers:
            result = axapi_call(module, session_url + '&method=slb.server.search', json.dumps({'name': server['server']}))
            if axapi_failure(result):
                module.fail_json(msg="the server %s specified in the servers list does not exist" % server['server'])
            checked_servers.append(server['server'])

        if not slb_service_group_exist:
            result = axapi_call(module, session_url + '&method=slb.service_group.create', json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(msg=result['response']['err']['msg'])
            changed = True
        else:
            # check to see if the service group definition without the
            # server members is different, and update that individually
            # if it needs it
            do_update = False
            for field in VALID_SERVICE_GROUP_FIELDS:
                if json_post['service_group'][field] != slb_result['service_group'][field]:
                    do_update = True
                    break

            if do_update:
                result = axapi_call(module, session_url + '&method=slb.service_group.update', json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(msg=result['response']['err']['msg'])
                changed = True

        # next we pull the defined list of servers out of the returned
        # results to make it a bit easier to iterate over
        defined_servers = slb_result.get('service_group', {}).get('member_list', [])

        # next we add/update new member servers from the user-specified
        # list if they're different or not on the target device
        for server in slb_servers:
            found = False
            different = False
            for def_server in defined_servers:
                if server['server'] == def_server['server']:
                    found = True
                    for valid_field in VALID_SERVER_FIELDS:
                        if server[valid_field] != def_server[valid_field]:
                            different = True
                            break
                    if found or different:
                        break
            # add or update as required
            server_data = {
                "name": slb_service_group,
                "member": server,
            }
            if not found:
                result = axapi_call(module, session_url + '&method=slb.service_group.member.create', json.dumps(server_data))
                changed = True
            elif different:
                result = axapi_call(module, session_url + '&method=slb.service_group.member.update', json.dumps(server_data))
                changed = True

        # finally, remove any servers that are on the target
        # device but were not specified in the list given
        for server in defined_servers:
            found = False
            for slb_server in slb_servers:
                if server['server'] == slb_server['server']:
                    found = True
                    break
            # remove if not found
            server_data = {
                "name": slb_service_group,
                "member": server,
            }
            if not found:
                result = axapi_call(module, session_url + '&method=slb.service_group.member.delete', json.dumps(server_data))
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(module, session_url + '&method=slb.service_group.search', json.dumps({'name': slb_service_group}))
        else:
            result = slb_result
    elif state == 'absent':
        if slb_service_group_exist:
            result = axapi_call(module, session_url + '&method=slb.service_group.delete', json.dumps({'name': slb_service_group}))
            changed = True
        else:
            result = dict(msg="the service group was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(module, session_url + '&method=system.action.write_memory')
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" % write_result['response']['err']['msg'])

    # log out of the session nicely and exit
    axapi_call(module, session_url + '&method=session.close')
    module.exit_json(changed=changed, content=result)
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(partition=dict(type='str', required=False),
             operation=dict(type='str',
                            default='create',
                            choices=['create', 'update', 'delete']),
             server_name=dict(type='str', aliases=['server'], required=True),
             server_ip=dict(type='str',
                            aliases=['ip', 'address'],
                            required=True),
             server_status=dict(type='str',
                                default='enable',
                                aliases=['action'],
                                choices=['enable', 'disable']),
             template_server=dict(type='str', required=False),
             server_health_check_disable=dict(type='str',
                                              required=False,
                                              choises=['yes', 'no']),
             server_conn_limit=dict(type='str', required=False),
             server_weight=dict(type='str', required=False),
             server_slow_start=dict(type='str',
                                    required=False,
                                    choises=['yes', 'no']),
             server_ipv6_addr=dict(type='str', required=False),
             server_ports=dict(type='list', aliases=['port'], default=[])))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    operation = module.params['operation']
    write_config = module.params['write_config']
    slb_server = module.params['server_name']
    slb_server_ip = module.params['server_ip']
    slb_server_status = module.params['server_status']
    slb_server_template_server = module.params['template_server']
    slb_server_health_check_disable = module.params[
        'server_health_check_disable']
    slb_server_conn_limit = module.params['server_conn_limit']
    slb_server_weight = module.params['server_weight']
    slb_server_slow_start = module.params['server_slow_start']
    slb_server_ipv6_addr = module.params['server_ipv6_addr']
    slb_server_ports = module.params['server_ports']

    # validate the ports data structure
    validate_ports(module, slb_server_ports)

    # Initialize JSON to be POST
    json_post = {"server": {"name": slb_server, "host": slb_server_ip}}

    json_post_create = {"server-list": [{}]}

    # add optional module parameters
    if slb_server_status:
        json_post['server']['action'] = slb_server_status

    if slb_server_template_server:
        json_post['server']['template-server'] = slb_server_template_server

    if slb_server_health_check_disable:
        json_post['server'][
            'health-check-disable'] = slb_server_health_check_disable
        if slb_server_health_check_disable == 'True':
            json_post['server']['health-check-disable'] = 1
        elif slb_server_health_check_disable == 'False':
            json_post['server']['health-check-disable'] = 0
        else:
            module.fail_json(
                msg="Server health_check_disable shold be 'yes' or 'no'")

    if slb_server_conn_limit:
        json_post['server']['conn-limit'] = slb_server_conn_limit

    if slb_server_weight:
        json_post['server']['weight'] = slb_server_weight

    if slb_server_slow_start:
        json_post['server']['slow-start'] = slb_server_slow_start
        if slb_server_slow_start == 'True':
            json_post['server']['slow-start'] = 1
        elif slb_server_slow_start == 'False':
            json_post['server']['slow-start'] = 0
        else:
            module.fail_json(msg="Server slow_start shold be 'yes' or 'no'")

    if slb_server_ipv6_addr:
        json_post['server']['server-ipv6-addr'] = slb_server_ipv6_addr

    if slb_server_ports:
        json_post['server']['port-list'] = slb_server_ports

    json_post_create['server-list'][0] = json_post['server']

    # login A10 device and own signature
    axapi_base_url = 'https://{}/axapi/v3/'.format(host)
    axapi_auth_url = axapi_base_url + 'auth/'
    signature = axapi_authenticate_v3(module, axapi_auth_url, username,
                                      password)

    # GET existing partition list and check if the partition indicated in the playbook exists
    if partition:
        partition_list = axapi_call_v3(module,
                                       axapi_base_url + 'partition/',
                                       method='GET',
                                       body='',
                                       signature=signature)
        if axapi_failure(partition_list):
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(msg="There is no partition on the device: %s" %
                             (host))
        else:
            partition_list = [
                partition_attr['partition-name']
                for partition_attr in partition_list['partition-list']
            ]
            if partition in partition_list:
                result = axapi_call_v3(module,
                                       axapi_base_url + 'active-partition/' +
                                       partition,
                                       method='POST',
                                       body='',
                                       signature=signature)
                if axapi_failure(result):
                    axapi_call_v3(module,
                                  axapi_base_url + 'logoff/',
                                  method='POST',
                                  body='',
                                  signature=signature)
                    module.fail_json(
                        msg="failed to create the service group: %s" %
                        result['response']['err']['msg'])
            else:
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="The partition does not exist: %s" %
                                 (partition))

    # GET existing servers and check if the server already exits
    slb_server_data = axapi_call_v3(module,
                                    axapi_base_url + 'slb/server/',
                                    method='GET',
                                    body='',
                                    signature=signature)
    if axapi_failure(slb_server_data):
        slb_server_exists = False
    else:
        slb_server_list = [
            server['name'] for server in slb_server_data['server-list']
        ]
        if slb_server in slb_server_list:
            slb_server_exists = True
        else:
            slb_server_exists = False

    # POST configuration
    changed = False
    if operation == 'create':
        if slb_server_exists is False:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/',
                                   method='POST',
                                   body=json.dumps(json_post_create),
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to create the server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            changed = False
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(
                msg="server %s already exists, use state='update' instead" %
                (slb_server))
        # if we changed things, get the full info regarding result
        if changed:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method='GET',
                                   body='',
                                   signature=signature)
        else:
            result = slb_server_data
    elif operation == 'delete':
        if slb_server_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method='DELETE',
                                   body='',
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to delete server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the server was not present: %s" % (slb_server))
    elif operation == 'update':
        if slb_server_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method='PUT',
                                   body=json.dumps(json_post),
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to update server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the server was not present: %s" % (slb_server))

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call_v3(module,
                                     axapi_base_url + 'write/memory/',
                                     method='POST',
                                     body='',
                                     signature=signature)
        if axapi_failure(write_result):
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out gracefully and exit
    axapi_call_v3(module,
                  axapi_base_url + 'logoff/',
                  method='POST',
                  body='',
                  signature=signature)
    module.exit_json(changed=changed, content=result)
Example #10
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            partition=dict(type='str',
                           aliases=['partition', 'part'],
                           required=False),
            file_name=dict(type='str', aliases=['filename'], required=False),
            cert_key_name=dict(type='str', required=False),
            file_type=dict(type='str',
                           choices=['key', 'certificate', 'certificate/key'],
                           required=False,
                           default='certificate'),
            pfx_passwd=dict(type='str', required=False),
            method=dict(type='str',
                        choices=['upload', 'download'],
                        required=False),
            overwrite=dict(type='bool', default=False, required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    part = module.params['partition']
    state = module.params['state']
    file_name = module.params['file_name']
    cert_key_name = module.params['cert_key_name']
    file_type = module.params['file_type']
    pfx_passwd = module.params['pfx_passwd']
    method = module.params['method']
    overwrite = module.params['overwrite']

    if method and method != 'upload' and method != 'download':
        module.fail_json(msg="method must be one of 'upload' or 'download'")

    # authenticate
    axapi_base_url = 'http://%s/axapi/v3/' % host
    signature = axapi_authenticate_v3(module, axapi_base_url + 'auth',
                                      username, password)
    json_body = {}

    if file_type == "certificate":
        ext_url = 'ssl-cert'
        json_body = {
            "ssl-cert": {
                "certificate-type": "pem",
                "action": "import",
                "file": file_name,
                "file-handle": file_name
            }
        }
    elif file_type == "key":
        ext_url = 'ssl-key'
        json_body = {
            "ssl-key": {
                "action": "import",
                "file": file_name,
                "file-handle": file_name,
                "dst-file": file_name
            }
        }
    elif file_type == "certificate/key":
        ext_url = 'ssl-cert-key'

        # NOT WORKING YET
        # need to upload a .tar.gz file containing the key and cert
        json_body_search = {
            "ssl-cert-key": {
                "action": "check",
                "file": cert_key_name,
                "file-handle": cert_key_name
            }
        }

        if method == "upload":
            json_body = {
                "ssl-cert-key": {
                    "action": "import",
                    "file": file_name,
                    "file-handle": file_name
                }
            }
        elif method == "download":
            json_body = {
                "ssl-cert-key": {
                    "action": "export",
                    "file": file_name,
                    "file-handle": file_name,
                    "dst-file": "blahdoo"
                }
            }

    # change partitions if we need to
    if part:
        part_change_result = axapi_call_v3(module,
                                           axapi_base_url +
                                           'active-partition/' + part,
                                           method="POST",
                                           signature=signature,
                                           body="")
        if (part_change_result['response']['status'] == 'fail'):
            # log out of the session nicely and exit with an error
            result = axapi_call_v3(module,
                                   axapi_base_url + 'logoff',
                                   method="POST",
                                   signature=signature,
                                   body="")
            module.fail_json(msg=part_change_result['response']['err']['msg'])

    # clear the 'changed' flag
    changed = False
    msg = ""

    # does the cert exist on the device already
    cert_found_on_device = False

    # check if the SSL cert/key exists on the device
    # for a cert/key we need to issue a POST and not a GET
    if file_type == "certificate/key":

        # result = axapi_call_v3(module, axapi_base_url + 'file/' + ext_url, method="POST", body=json_body_search, signature=signature)

        # there is no way to check for key/cert together so we must make two separate calls to validate
        result_cert_lookup = axapi_call_v3(module,
                                           axapi_base_url + 'file/ssl-cert/' +
                                           cert_key_name,
                                           method="GET",
                                           signature=signature)
        result_key_lookup = axapi_call_v3(module,
                                          axapi_base_url + 'file/ssl-key/' +
                                          cert_key_name,
                                          method="GET",
                                          signature=signature)

        if ('response' in result_cert_lookup and result_cert_lookup['response']['status'] == 'fail' and (result_cert_lookup['response']['code'] == 404 or result_cert_lookup['response']['code'] == 400) or \
            'response' in result_key_lookup and result_key_lookup['response']['status'] == 'fail' and (result_key_lookup['response']['code'] == 404 or result_key_lookup['response']['code'] == 400)):
            cert_found_on_device = False
        elif 'response' in result_cert_lookup and result_cert_lookup[
                'response']['status'] == 'fail' and result_cert_lookup[
                    'response']['code'] != 404 and result_cert_lookup[
                        'response']['code'] != 400:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])
        elif 'response' in result_cert_lookup and result_cert_lookup[
                'response']['status'] == 'fail' and result_key_lookup[
                    'response']['code'] != 404 and result_key_lookup[
                        'response']['code'] != 400:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])
        else:
            cert_found_on_device = True

        # file_name = "bundle.tar.gz"
    else:
        result = axapi_call_v3(module,
                               axapi_base_url + 'file/' + ext_url + '/' +
                               file_name,
                               method="GET",
                               signature=signature)

        if ('response' in result and result['response']['status'] == 'fail'):
            if (result['response']['code'] == 404
                    or result['response']['code'] == 400):
                cert_found_on_device = False
            else:
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])
        else:
            cert_content = result['response']['data']
            cert_found_on_device = True

    if state == 'present':

        # adding the SSL cert
        if (method == "upload" and cert_found_on_device and overwrite) or \
        (method == "upload" and not cert_found_on_device):

            # make sure the file being uploaded exists locally
            if os.path.isfile(file_name) is False:
                # log out of the session nicely and exit with an error
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg='File not found ' + file_name)
            else:
                try:
                    result = uploadSSL(axapi_base_url + 'file/' + ext_url,
                                       'upload',
                                       file_type,
                                       pfx_passwd,
                                       file_name,
                                       json.dumps(json_body),
                                       signature=signature)
                except Exception, e:
                    # log out of the session nicely and exit with an error
                    #err_result = e['changed']
                    logoff_result = axapi_call_v3(module,
                                                  axapi_base_url + 'logoff',
                                                  method="POST",
                                                  signature=signature,
                                                  body="")
                    module.fail_json(msg=e)

            if axapi_failure(result):
                # log out of the session nicely and exit with an error
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg="failed to upload the cert: %s" %
                                 result['response']['err']['msg'])

            changed = True

        elif method == "download" and (cert_found_on_device
                                       or file_type == "certificate/key"):
            saveFile(file_name, cert_content)

        elif method == "download" and not cert_found_on_device:
            module.fail_json(msg="cert not found")

        elif cert_found_on_device and not overwrite:
            msg = "certificate/key found on device and not overwritten"
Example #11
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str', default='present', choices=['present', 'absent']),
            server_name=dict(type='str', aliases=['server'], required=True),
            server_ip=dict(type='str', aliases=['ip', 'address']),
            server_status=dict(type='str', default='enabled', aliases=['status'], choices=['enabled', 'disabled']),
            server_ports=dict(type='list', aliases=['port'], default=[]),
            partition=dict(type='str', default=[]),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False
    )

    host = module.params['host']
    partition = module.params['partition']
    username = module.params['username']
    password = module.params['password']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_server = module.params['server_name']
    slb_server_ip = module.params['server_ip']
    slb_server_status = module.params['server_status']
    slb_server_ports = module.params['server_ports']

    if slb_server is None:
        module.fail_json(msg='server_name is required')

    axapi_base_url = 'https://%s/services/rest/V2.1/?format=json' % host
    session_url = axapi_authenticate(module, axapi_base_url, username, password)

    # validate the ports data structure
    validate_ports(module, slb_server_ports)

    json_post = {
        'server': {
            'name': slb_server,
        }
    }

    # add optional module parameters
    if slb_server_ip:
        json_post['server']['host'] = slb_server_ip

    if slb_server_ports:
        json_post['server']['port_list'] = slb_server_ports

    if slb_server_status:
        json_post['server']['status'] = axapi_enabled_disabled(slb_server_status)

    axapi_call(module, session_url + '&method=system.partition.active', json.dumps({'name': partition}))

    slb_server_data = axapi_call(module, session_url + '&method=slb.server.search', json.dumps({'name': slb_server}))
    slb_server_exists = not axapi_failure(slb_server_data)

    changed = False
    if state == 'present':
        if not slb_server_exists:
            if not slb_server_ip:
                module.fail_json(msg='you must specify an IP address when creating a server')

            result = axapi_call(module, session_url + '&method=slb.server.create', json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(msg="failed to create the server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            def port_needs_update(src_ports, dst_ports):
                '''
                Checks to determine if the port definitions of the src_ports
                array are in or different from those in dst_ports. If there is
                a difference, this function returns true, otherwise false.
                '''
                for src_port in src_ports:
                    found = False
                    different = False
                    for dst_port in dst_ports:
                        if src_port['port_num'] == dst_port['port_num']:
                            found = True
                            for valid_field in VALID_PORT_FIELDS:
                                if src_port[valid_field] != dst_port[valid_field]:
                                    different = True
                                    break
                            if found or different:
                                break
                    if not found or different:
                        return True
                # every port from the src exists in the dst, and none of them were different
                return False

            def status_needs_update(current_status, new_status):
                '''
                Check to determine if we want to change the status of a server.
                If there is a difference between the current status of the server and
                the desired status, return true, otherwise false.
                '''
                if current_status != new_status:
                    return True
                return False

            defined_ports = slb_server_data.get('server', {}).get('port_list', [])
            current_status = slb_server_data.get('server', {}).get('status')

            # we check for a needed update several ways
            # - in case ports are missing from the ones specified by the user
            # - in case ports are missing from those on the device
            # - in case we are change the status of a server
            if (port_needs_update(defined_ports, slb_server_ports) or
                    port_needs_update(slb_server_ports, defined_ports) or
                    status_needs_update(current_status, axapi_enabled_disabled(slb_server_status))):
                result = axapi_call(module, session_url + '&method=slb.server.update', json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(msg="failed to update the server: %s" % result['response']['err']['msg'])
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(module, session_url + '&method=slb.server.search', json.dumps({'name': slb_server}))
        else:
            result = slb_server_data
    elif state == 'absent':
        if slb_server_exists:
            result = axapi_call(module, session_url + '&method=slb.server.delete', json.dumps({'name': slb_server}))
            changed = True
        else:
            result = dict(msg="the server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(module, session_url + '&method=system.action.write_memory')
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" % write_result['response']['err']['msg'])

    # log out of the session nicely and exit
    axapi_call(module, session_url + '&method=session.close')
    module.exit_json(changed=changed, content=result)
Example #12
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            partition=dict(type='str', aliases=['partition', 'part']),
            service_group=dict(type='str',
                               aliases=['service', 'pool', 'group'],
                               required=True),
            service_group_protocol=dict(type='str',
                                        default='tcp',
                                        aliases=['proto', 'protocol'],
                                        choices=['tcp', 'udp']),
            service_group_method=dict(
                type='str',
                default='round-robin',
                aliases=['method'],
                choices=[
                    'round-robin', 'weighted-rr', 'least-connection',
                    'weighted-least-connection', 'service-least-connection',
                    'service-weighted-least-connection', 'fastest-response',
                    'least-request', 'round-robin-strict', 'src-ip-only-hash',
                    'src-ip-hash'
                ]),
            servers=dict(type='list', aliases=['server', 'member'],
                         default=[]),
            health_monitor=dict(type='str', aliases=['hm']),
            reset_on_server_selection_fail=dict(type='bool', default=False),
            overwrite=dict(type='bool', default=False, required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    part = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_service_group = module.params['service_group']
    slb_service_group_proto = module.params['service_group_protocol']
    slb_service_group_method = module.params['service_group_method']
    slb_servers = module.params['servers']
    slb_health_monitor = module.params['health_monitor']
    slb_reset_on_server_selection_fail = module.params[
        'reset_on_server_selection_fail']
    overwrite = module.params['overwrite']

    if slb_service_group is None:
        module.fail_json(msg='service_group is required')

    axapi_base_url = 'http://%s/axapi/v3/' % host

    # build the JSON message structure
    json_post = {
        'service-group': {
            'name': slb_service_group,
            'protocol': slb_service_group_proto,
            'lb-method': slb_service_group_method,
            'reset-on-server-selection-fail':
            slb_reset_on_server_selection_fail,
            'member-list': []
        }
    }

    if slb_health_monitor:
        json_post['service_group']['health_monitor'] = slb_health_monitor

    # first we authenticate to get a session id
    signature = axapi_authenticate_v3(module, axapi_base_url + 'auth',
                                      username, password)

    # change partitions if we need to
    if part:
        result = axapi_call_v3(module,
                               axapi_base_url + 'active-partition/' + part,
                               method="POST",
                               signature=signature,
                               body="")
        if (result['response']['status'] == 'fail'):
            # log out of the session nicely and exit with an error
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])

    # validate that if the health monitor has been passed in, it exists on the system already
    if slb_health_monitor:
        result_hm = axapi_call_v3(
            module, axapi_base_url + 'health/monitor/' + slb_health_monitor)
        if ('response' in result_hm
                and result_hm['response']['status'] == 'fail'):
            # log out of the session nicely and exit with an error
            result = axapi_call_v3(module,
                                   axapi_base_url + 'logoff',
                                   method="POST",
                                   signature=signature,
                                   body="")
            module.fail_json(msg=result_hm['response']['err']['msg'])

    # then we check to see if the specified service group exists
    result = axapi_call_v3(module,
                           axapi_base_url + 'slb/service-group/' +
                           slb_service_group,
                           method="GET",
                           signature=signature)
    if ('response' in result and result['response']['status'] == 'fail'):
        if (result['response']['code'] == 404):
            slb_service_group_exist = False
        else:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])
    else:
        #        sg_content = result['response']['data']
        slb_service_group_exist = True

    # clear the 'changed' flag
    changed = False
    msg = ""

    if state == 'present':
        # before creating/updating we need to validate that servers
        # defined in the servers list exist to prevent errors
        server_exist = True
        for server in slb_servers:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' +
                                   server['name'],
                                   method="GET",
                                   signature=signature)

            # did the lookup of the server return some error
            if ('response' in result
                    and result['response']['status'] == 'fail'):
                if (result['response']['code'] == 404):
                    server_exist = False
                    break
                else:
                    logoff_result = axapi_call_v3(module,
                                                  axapi_base_url + 'logoff',
                                                  method="POST",
                                                  signature=signature,
                                                  body="")
                    module.fail_json(msg=result['response']['err']['msg'])

            # add server to the member-list
            json_post['service-group']['member-list'].append(server)

        if not server_exist:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg="server %s does not exist" % server['name'])

        if slb_service_group_exist and not overwrite:
            # just exit gracefully with a message
            msg = 'service-group exists but not modified'

        elif slb_service_group_exist and overwrite:
            # overwrite the properties of the service group
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/' +
                                   slb_service_group,
                                   method="PUT",
                                   signature=signature,
                                   body=json_post)
            if ('response' in result and 'err' in result['response']):
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])

            changed = True
            msg = "service group %s updated" % slb_service_group

        elif not slb_service_group_exist:
            # create a new server
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/',
                                   method="POST",
                                   signature=signature,
                                   body=json_post)
            if ('response' in result and 'err' in result['response']):
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])

            changed = True
            msg = "service-group %s created" % slb_service_group

    elif state == 'absent':
        if slb_service_group_exist:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/service-group/' +
                                   slb_service_group,
                                   method="DELETE",
                                   signature=signature)
            changed = True
        else:
            msg = "the service group was not present"
            changed = False

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        result = axapi_call_v3(module,
                               axapi_base_url + 'write/memory',
                               method="POST",
                               signature=signature)

        if ('response' in result and 'err' in result['response']):
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])

    # log out of the session nicely and exit
    result = axapi_call_v3(module,
                           axapi_base_url + 'logoff',
                           method="POST",
                           signature=signature,
                           body="")
    module.exit_json(changed=changed, content=result, msg=msg)
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            partition=dict(type='str', aliases=['partition', 'part']),
            virtual_server=dict(type='str',
                                aliases=['vip', 'virtual'],
                                required=True),
            virtual_server_ip=dict(type='str',
                                   aliases=['ip', 'address'],
                                   required=True),
            virtual_server_status=dict(type='str',
                                       default='enabled',
                                       aliases=['status'],
                                       choices=['enabled', 'disabled']),
            disable_vserver_on_condition=dict(
                type='str',
                choices=[
                    'enable', 'disable', 'disable-when-all-ports-down',
                    'disable-when-any-port-down'
                ],
                required=False,
                default='enable'),
            redistribution_flagged=dict(type='int',
                                        choices=[0, 1, 2],
                                        required=False,
                                        default=0),
            acl_id=dict(type='str', required=False, default=None),
            acl_name=dict(type='str', required=False, default=None),
            virtual_server_ports=dict(type='list', required=True),
            overwrite=dict(type='bool', default=False, required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    part = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_virtual = module.params['virtual_server']
    slb_virtual_ip = module.params['virtual_server_ip']
    slb_virtual_status = module.params['virtual_server_status']
    slb_virtual_ports = module.params['virtual_server_ports']
    redistribution_flagged = module.params['redistribution_flagged']
    acl_id = module.params['acl_id']
    acl_name = module.params['acl_name']
    disable_vserver_on_condition = module.params[
        'disable_vserver_on_condition']
    overwrite = module.params['overwrite']

    # check mandatory fields
    if slb_virtual is None:
        module.fail_json(msg='virtual_server is required')

    axapi_base_url = 'http://%s/axapi/v3/' % host

    # first we authenticate to get a session id
    signature = axapi_authenticate_v3(module, axapi_base_url + 'auth',
                                      username, password)

    # change partitions if we need to
    if part:
        result = axapi_call_v3(module,
                               axapi_base_url + 'active-partition/' + part,
                               method="POST",
                               signature=signature,
                               body="")
        if (result['response']['status'] == 'fail'):
            # log out of the session nicely and exit with an error
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])

    json_post = {
        'virtual-server': {
            'name': slb_virtual,
            'enable-disable-action':
            axapi_enabled_disabled(slb_virtual_status),
            'port-list': slb_virtual_ports,
            'enable-disable-action': disable_vserver_on_condition,
            'redistribution-flagged': redistribution_flagged,
        }
    }

    # is this an IPv4 or IPv6 VIP?
    if "::" in slb_virtual_ip or len(slb_virtual_ip) > 16:
        ip_address_field = "ipv6-address"
        acl_name_field = "ipv6-acl"
    else:
        ip_address_field = "ip-address"
        acl_name_field = "acl-name"

    # if acl id or acl name was passed in bind it to the vip, otherwise assign the ip address passed in
    if acl_id or acl_name:
        if acl_id:
            json_post['virtual-server']['acl-id'] = acl_id
        else:
            json_post['virtual-server'][acl_name_field] = acl_name
#    else:
    json_post['virtual-server'][ip_address_field] = slb_virtual_ip

    result = axapi_call_v3(module,
                           axapi_base_url + 'slb/virtual-server/' +
                           slb_virtual,
                           method="GET",
                           signature=signature)

    if ('response' in result and result['response']['status'] == 'fail'):
        if (result['response']['code'] == 404):
            slb_virtual_exists = False
        else:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])
    else:
        slb_virtual_exists = True

    # clear the 'changed' flag
    changed = False
    msg = ""

    if state == 'present':

        if slb_virtual_exists and not overwrite:
            msg = 'virtual server exists but not modified'

        elif slb_virtual_exists and overwrite:
            # overwrite the properties of the virtual server
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/virtual-server/' +
                                   slb_virtual,
                                   method="PUT",
                                   signature=signature,
                                   body=json_post)
            if ('response' in result and 'err' in result['response']):
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])

            changed = True
            msg = "virtual server %s updated" % slb_virtual

        elif not slb_virtual_exists:
            # create a new server
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/virtual-server/',
                                   method="POST",
                                   signature=signature,
                                   body=json_post)
            if ('response' in result and 'err' in result['response']):
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])

            changed = True
            msg = "virtual server %s created" % slb_virtual

    elif state == 'absent':
        if slb_virtual_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/virtual-server/' +
                                   slb_virtual,
                                   method="DELETE",
                                   signature=signature)
            changed = True
        else:
            changed = False
            msg = "the virtual server was not present"

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        result = axapi_call_v3(module,
                               axapi_base_url + 'write/memory',
                               method="POST",
                               signature=signature)

        if ('response' in result and 'err' in result['response']):
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])

    # log out of the session nicely and exit
    result = axapi_call_v3(module,
                           axapi_base_url + 'logoff',
                           method="POST",
                           signature=signature,
                           body="")
    module.exit_json(changed=changed, content=result, msg=msg)
Example #14
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            partition=dict(type='str',
                           aliases=['partition', 'part'],
                           required=False),
            server_name=dict(type='str', aliases=['server'], required=True),
            server_ip=dict(type='str', aliases=['ip', 'address']),
            server_action=dict(type='str',
                               default='enable',
                               aliases=['status'],
                               choices=['enable', 'disable']),
            server_ports=dict(type='list', aliases=['port'], default=[]),
            server_hm=dict(type='str', aliases=['health_monitor']),
            overwrite=dict(type='bool', default=False, required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    part = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_server = module.params['server_name']
    slb_server_ip = module.params['server_ip']
    slb_server_action = module.params['server_action']
    slb_server_ports = module.params['server_ports']
    slb_server_hm = module.params['server_hm']
    overwrite = module.params['overwrite']

    if slb_server is None:
        module.fail_json(msg='server_name is required')

    axapi_base_url = 'http://%s/axapi/v3/' % host
    signature = axapi_authenticate_v3(module, axapi_base_url + 'auth',
                                      username, password)

    # change partitions if we need to
    if part:
        part_change_result = axapi_call_v3(module,
                                           axapi_base_url +
                                           'active-partition/' + part,
                                           method="POST",
                                           signature=signature,
                                           body="")
        if (part_change_result['response']['status'] == 'fail'):
            # log out of the session nicely and exit with an error
            result = axapi_call_v3(module,
                                   axapi_base_url + 'logoff',
                                   method="POST",
                                   signature=signature,
                                   body="")
            module.fail_json(msg=part_change_result['response']['err']['msg'])

    # is this server an ipv4 or ipv6 server
    if "::" in slb_server_ip or len(slb_server_ip) > 16:
        ip_address_field = "server-ipv6-addr"
    else:
        ip_address_field = "host"

    # create the JSON object containing the parameters
    json_post = {
        'server': {
            'name': slb_server,
        }
    }

    # add optional module parameters
    if slb_server_ip:
        json_post['server'][ip_address_field] = slb_server_ip

    if slb_server_ports:
        json_post['server']['port-list'] = slb_server_ports

    if slb_server_hm:
        json_post['server']['health-check'] = slb_server_hm

    if slb_server_action:
        json_post['server']['action'] = slb_server_action

#    rsp, info = fetch_url(module, axapi_base_url + 'slb/server/' + slb_server, method='GET', data=json.dumps(None), headers={'content-type': 'application/json', 'Authorization': 'A10 %s' % signature})

    slb_server_data = axapi_call_v3(module,
                                    axapi_base_url + 'slb/server/' +
                                    slb_server,
                                    method="GET",
                                    signature=signature)

    if ('response' in slb_server_data
            and slb_server_data['response']['status'] == 'fail'):
        if (slb_server_data['response']['code'] == 404):
            server_exists = False
        else:
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=slb_server_data['response']['err']['msg'])
    else:
        #server_content = slb_server_data['response']['data']
        server_content = slb_server_data
        server_exists = True

    changed = False
    msg = ""

    # server is being added/modified
    if state == 'present':

        if server_exists and not overwrite:
            # just exit gracefully with a message
            msg = 'server exists but not modified'

        elif server_exists and overwrite:
            # overwrite the properties of the server
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method="PUT",
                                   signature=signature,
                                   body=json_post)
            if ('response' in result and 'err' in result['response']):
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])

            changed = True
            msg = "server %s updated" % slb_server

        elif not server_exists:
            # create a new server
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/',
                                   method="POST",
                                   signature=signature,
                                   body=json_post)
            if ('response' in result and 'err' in result['response']):
                logoff_result = axapi_call_v3(module,
                                              axapi_base_url + 'logoff',
                                              method="POST",
                                              signature=signature,
                                              body="")
                module.fail_json(msg=result['response']['err']['msg'])

            changed = True
            msg = "server %s created" % slb_server

    elif state == 'absent':
        if server_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method="DELETE",
                                   signature=signature)
            changed = True
        else:
            changed = False
            msg = "the server was not present"

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        result = axapi_call_v3(module,
                               axapi_base_url + 'write/memory',
                               method="POST",
                               signature=signature)

        if ('response' in result and 'err' in result['response']):
            logoff_result = axapi_call_v3(module,
                                          axapi_base_url + 'logoff',
                                          method="POST",
                                          signature=signature,
                                          body="")
            module.fail_json(msg=result['response']['err']['msg'])

    # log out of the session nicely and exit
    result = axapi_call_v3(module,
                           axapi_base_url + 'logoff',
                           method="POST",
                           signature=signature,
                           body="")
    module.exit_json(changed=changed, content=result, msg=msg)
Example #15
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            state=dict(type='str',
                       default='present',
                       choices=['present', 'absent']),
            service_group=dict(type='str',
                               aliases=['service', 'pool', 'group'],
                               required=True),
            service_group_protocol=dict(type='str',
                                        default='tcp',
                                        aliases=['proto', 'protocol'],
                                        choices=['tcp', 'udp']),
            service_group_method=dict(
                type='str',
                default='round-robin',
                aliases=['method'],
                choices=[
                    'round-robin', 'weighted-rr', 'least-connection',
                    'weighted-least-connection', 'service-least-connection',
                    'service-weighted-least-connection', 'fastest-response',
                    'least-request', 'round-robin-strict', 'src-ip-only-hash',
                    'src-ip-hash'
                ]),
            servers=dict(type='list', aliases=['server', 'member'],
                         default=[]),
            partition=dict(type='str', default=[]),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    state = module.params['state']
    write_config = module.params['write_config']
    slb_service_group = module.params['service_group']
    slb_service_group_proto = module.params['service_group_protocol']
    slb_service_group_method = module.params['service_group_method']
    slb_servers = module.params['servers']

    if slb_service_group is None:
        module.fail_json(msg='service_group is required')

    axapi_base_url = 'https://' + host + '/services/rest/V2.1/?format=json'
    load_balancing_methods = {
        'round-robin': 0,
        'weighted-rr': 1,
        'least-connection': 2,
        'weighted-least-connection': 3,
        'service-least-connection': 4,
        'service-weighted-least-connection': 5,
        'fastest-response': 6,
        'least-request': 7,
        'round-robin-strict': 8,
        'src-ip-only-hash': 14,
        'src-ip-hash': 15
    }

    if not slb_service_group_proto or slb_service_group_proto.lower() == 'tcp':
        protocol = 2
    else:
        protocol = 3

    # validate the server data list structure
    validate_servers(module, slb_servers)

    json_post = {
        'service_group': {
            'name': slb_service_group,
            'protocol': protocol,
            'lb_method': load_balancing_methods[slb_service_group_method],
        }
    }

    # first we authenticate to get a session id
    session_url = axapi_authenticate(module, axapi_base_url, username,
                                     password)
    # then we select the active-partition
    slb_server_partition = axapi_call(
        module, session_url + '&method=system.partition.active',
        json.dumps({'name': partition}))
    # then we check to see if the specified group exists
    slb_result = axapi_call(module,
                            session_url + '&method=slb.service_group.search',
                            json.dumps({'name': slb_service_group}))
    slb_service_group_exist = not axapi_failure(slb_result)

    changed = False
    if state == 'present':
        # before creating/updating we need to validate that servers
        # defined in the servers list exist to prevent errors
        checked_servers = []
        for server in slb_servers:
            result = axapi_call(module,
                                session_url + '&method=slb.server.search',
                                json.dumps({'name': server['server']}))
            if axapi_failure(result):
                module.fail_json(
                    msg=
                    "the server %s specified in the servers list does not exist"
                    % server['server'])
            checked_servers.append(server['server'])

        if not slb_service_group_exist:
            result = axapi_call(
                module, session_url + '&method=slb.service_group.create',
                json.dumps(json_post))
            if axapi_failure(result):
                module.fail_json(msg=result['response']['err']['msg'])
            changed = True
        else:
            # check to see if the service group definition without the
            # server members is different, and update that individually
            # if it needs it
            do_update = False
            for field in VALID_SERVICE_GROUP_FIELDS:
                if json_post['service_group'][field] != slb_result[
                        'service_group'][field]:
                    do_update = True
                    break

            if do_update:
                result = axapi_call(
                    module, session_url + '&method=slb.service_group.update',
                    json.dumps(json_post))
                if axapi_failure(result):
                    module.fail_json(msg=result['response']['err']['msg'])
                changed = True

        # next we pull the defined list of servers out of the returned
        # results to make it a bit easier to iterate over
        defined_servers = slb_result.get('service_group',
                                         {}).get('member_list', [])

        # next we add/update new member servers from the user-specified
        # list if they're different or not on the target device
        for server in slb_servers:
            found = False
            different = False
            for def_server in defined_servers:
                if server['server'] == def_server['server']:
                    found = True
                    for valid_field in VALID_SERVER_FIELDS:
                        if server[valid_field] != def_server[valid_field]:
                            different = True
                            break
                    if found or different:
                        break
            # add or update as required
            server_data = {
                "name": slb_service_group,
                "member": server,
            }
            if not found:
                result = axapi_call(
                    module,
                    session_url + '&method=slb.service_group.member.create',
                    json.dumps(server_data))
                changed = True
            elif different:
                result = axapi_call(
                    module,
                    session_url + '&method=slb.service_group.member.update',
                    json.dumps(server_data))
                changed = True

        # finally, remove any servers that are on the target
        # device but were not specified in the list given
        for server in defined_servers:
            found = False
            for slb_server in slb_servers:
                if server['server'] == slb_server['server']:
                    found = True
                    break
            # remove if not found
            server_data = {
                "name": slb_service_group,
                "member": server,
            }
            if not found:
                result = axapi_call(
                    module,
                    session_url + '&method=slb.service_group.member.delete',
                    json.dumps(server_data))
                changed = True

        # if we changed things, get the full info regarding
        # the service group for the return data below
        if changed:
            result = axapi_call(
                module, session_url + '&method=slb.service_group.search',
                json.dumps({'name': slb_service_group}))
        else:
            result = slb_result
    elif state == 'absent':
        if slb_service_group_exist:
            result = axapi_call(
                module, session_url + '&method=slb.service_group.delete',
                json.dumps({'name': slb_service_group}))
            changed = True
        else:
            result = dict(msg="the service group was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call(
            module, session_url + '&method=system.action.write_memory')
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out of the session nicely and exit
    axapi_call(module, session_url + '&method=session.close')
    module.exit_json(changed=changed, content=result)
Example #16
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            operation=dict(type='str', default='create', choices=['create', 'update', 'delete']),
            virtual_server=dict(type='str', required=True),
            ip_address=dict(type='str', required=False),
            ipv6_address=dict(type='str', required=False),
            use_if_ip=dict(type='str', required=False, choises=['yes', 'no']),
            acl_name=dict(type='str', required=False),
            ipv6_acl=dict(type='str',required=False),
            enable_disable_action=dict(type='str', required=False, choices=['enable', 'disable', 'disable-when-all-ports-down', 'disable-when-any-port-down']),
            template_policy=dict(type='str', required=False),
            template_virtual_server=dict(type='str', required=False),
            vrid=dict(type='str', required=False),
            description=dict(type='str', required=False),
            port_list=dict(type='list', default=[]),
            partition=dict(type='str', required=False),
        )
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=False
    )

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    operation = module.params['operation']
    write_config = module.params['write_config']
    slb_virtual_server = module.params['virtual_server']
    slb_virtual_server_ip_address = module.params['ip_address']
    slb_virtual_server_ipv6_address = module.params['ipv6_address']
    slb_virtual_server_use_if_ip = module.params['use_if_ip']
    slb_virtual_server_acl_name = module.params['acl_name']
    slb_virtual_server_ipv6_acl = module.params['ipv6_acl']
    slb_virtual_server_enable_disable_action = module.params['enable_disable_action']
    slb_virtual_server_template_policy = module.params['template_policy']
    slb_virtual_server_template_virtual_server = module.params['template_virtual_server']
    slb_virtual_server_vrid = module.params['vrid']
    slb_virtual_server_description = module.params['description']
    slb_virtual_server_port_list = module.params['port_list']

    # validate if virtual-server name exists
    if slb_virtual_server is None:
        module.fail_json(msg="virtual-server name is required")

    # validate the server list with using validate_servers
    validate_port_list(module, slb_virtual_server_port_list)

    # validate if ip_address and ipv6_address and use_if_ip are exclusive
    if slb_virtual_server_ip_address:
        if slb_virtual_server_ipv6_address or slb_virtual_server_use_if_ip:
            module.fail_json(msg="ip_address and ipv6_address and use_if_ip are exclusive")
    elif slb_virtual_server_ipv6_address:
        if slb_virtual_server_use_if_ip:
            module.fail_json(msg="ip_address and ipv6_address and use_if_ip are exclusive")
    elif not slb_virtual_server_use_if_ip:
        module.fail_json(msg='One of ip_address or ipv6_address or use_if_ip should be defined')

    # Initialize JSON to be POST
    json_post = {
        "virtual-server": 
            {
                "name": slb_virtual_server,
            }
    }

    json_post_create = {
        "virtual-server-list": [
            {
            }
        ]
    }

    # add optional module parameters to JSON
    if slb_virtual_server_port_list:
        json_post['virtual-server']['port-list'] = slb_virtual_server_port_list

    if slb_virtual_server_ip_address:
        json_post['virtual-server']['ip-address'] = slb_virtual_server_ip_address

    if slb_virtual_server_ipv6_address:
        json_post['virtual-server']['ipv6-address'] = slb_virtual_server_ipv6_address

    if slb_virtual_server_use_if_ip:
        json_post['virtual-server']['use-if-ip'] = slb_virtual_server_use_if_ip
		
    if slb_virtual_server_acl_name:
        json_post['virtual-server']['acl-name'] = slb_virtual_server_acl_name
		
    if slb_virtual_server_ipv6_acl:
        json_post['virtual-server']['ipv6-acl'] = slb_virtual_server_ipv6_acl
		
    if slb_virtual_server_enable_disable_action:
        json_post['virtual-server']['enable-disable-action'] = slb_virtual_server_enable_disable_action
		
    if slb_virtual_server_template_policy:
        json_post['virtual-server']['template-policy'] = slb_virtual_server_template_policy
		
    if slb_virtual_server_template_virtual_server:
        json_post['virtual-server']['template-virtual-server'] = slb_virtual_server_template_virtual_server
		
    if slb_virtual_server_vrid:
        json_post['virtual-server']['vrid'] = slb_virtual_server_vrid
		
    if slb_virtual_server_description:
        json_post['virtual-server']['description'] = slb_virtual_server_description

    json_post_create['virtual-server-list'][0] = json_post['virtual-server']
		
    # login A10 device and own signature
    axapi_base_url = 'https://{}/axapi/v3/'.format(host)
    axapi_auth_url = axapi_base_url + 'auth/'
    signature = axapi_authenticate_v3(module, axapi_auth_url, username, password)

    # GET existing partition list and check if the partition indicated in the playbook exists
    if partition:
        partition_list = axapi_call_v3(module, axapi_base_url+'partition/', method='GET', body='', signature=signature)
        if axapi_failure(partition_list):
            axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
            module.fail_json(msg="There is no partition on the device: %s" % (host))
        else:
            partition_list = [partition_attr['partition-name'] for partition_attr in partition_list['partition-list']]
            if partition in partition_list:
                result = axapi_call_v3(module, axapi_base_url+'active-partition/'+partition, method='POST', body='', signature=signature)
                if axapi_failure(result):
                    axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
                    module.fail_json(msg="failed to create the virtual server: %s" % result['response']['err']['msg'])                    
            else:
                axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
                module.fail_json(msg="The partition does not exist: %s" % (partition))
        
    # GET existing service groups and check if the service group already exists
    slb_virtual_server_data = axapi_call_v3(module, axapi_base_url+'slb/virtual-server/', method='GET', body='', signature=signature)
    if axapi_failure(slb_virtual_server_data):
        slb_virtual_server_exists = False
    else:
        slb_virtual_server_list = [virtual_server['name'] for virtual_server in slb_virtual_server_data['virtual-server-list']]
        if slb_virtual_server in slb_virtual_server_list:
            slb_virtual_server_exists = True
        else:
            slb_virtual_server_exists = False

    # POST configuration
    changed = False
    if operation == 'create':
        if slb_virtual_server_exists is False:
            result = axapi_call_v3(module, axapi_base_url+'slb/virtual-server/', method='POST', body=json.dumps(json_post_create), signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
                module.fail_json(msg="failed to create the virtual server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            changed = False
            axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
            module.fail_json(msg="The virtual server already exists, use state='update' instead")
         # if we changed things, get the full info regarding result
        if changed:
            result = axapi_call_v3(module, axapi_base_url + 'slb/virtual-server/' + slb_virtual_server, method='GET', body='', signature=signature)
        else:
            result = slb_virtual_server_data
    elif operation == 'delete':
        if slb_virtual_server_exists:
            result = axapi_call_v3(module, axapi_base_url + 'slb/virtual-server/' + slb_virtual_server, method='DELETE', body='', signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
                module.fail_json(msg="failed to delete the virtual server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="The virtual server was not present")
    elif operation == 'update':
        if slb_virtual_server_exists:
            result = axapi_call_v3(module, axapi_base_url + 'slb/virtual-server/' + slb_virtual_server, method='PUT', body=json.dumps(json_post), signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
                module.fail_json(msg="failed to update the virtual server: %s" % result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="The virtual server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call_v3(module, axapi_base_url+'write/memory/', method='POST', body='', signature=signature)
        if axapi_failure(write_result):
            axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
            module.fail_json(msg="failed to save the configuration: %s" % write_result['response']['err']['msg'])

    # log out gracefully and exit
    axapi_call_v3(module, axapi_base_url + 'logoff/', method='POST', body='', signature=signature)
    module.exit_json(changed=changed, content=result)
Example #17
0
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            operation=dict(type='str',
                           default='create',
                           choices=['create', 'update', 'delete']),
            server_name=dict(type='str', aliases=['server'], required=True),
            server_ip=dict(type='str',
                           aliases=['ip', 'address'],
                           required=True),
            server_status=dict(type='str',
                               default='enable',
                               aliases=['action'],
                               choices=['enable', 'disable']),
            server_ports=dict(type='list', aliases=['port'], default=[]),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    operation = module.params['operation']
    write_config = module.params['write_config']
    slb_server = module.params['server_name']
    slb_server_ip = module.params['server_ip']
    slb_server_status = module.params['server_status']
    slb_server_ports = module.params['server_ports']

    axapi_base_url = 'https://{}/axapi/v3/'.format(host)
    axapi_auth_url = axapi_base_url + 'auth/'
    signature = axapi_authenticate_v3(module, axapi_auth_url, username,
                                      password)

    # validate the ports data structure
    validate_ports(module, slb_server_ports)

    json_post = {"server-list": [{"name": slb_server, "host": slb_server_ip}]}

    # add optional module parameters
    if slb_server_ports:
        json_post['server-list'][0]['port-list'] = slb_server_ports

    if slb_server_status:
        json_post['server-list'][0]['action'] = slb_server_status

    slb_server_data = axapi_call_v3(module,
                                    axapi_base_url + 'slb/server/',
                                    method='GET',
                                    body='',
                                    signature=signature)

    # for empty slb server list
    if axapi_failure(slb_server_data):
        slb_server_exists = False
    else:
        slb_server_list = [
            server['name'] for server in slb_server_data['server-list']
        ]
        if slb_server in slb_server_list:
            slb_server_exists = True
        else:
            slb_server_exists = False

    changed = False
    if operation == 'create':
        if slb_server_exists == False:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/',
                                   method='POST',
                                   body=json.dumps(json_post),
                                   signature=signature)
            if axapi_failure(result):
                module.fail_json(msg="failed to create the server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            module.fail_json(
                msg="server already exists, use state='update' instead")
            changed = False
        # if we changed things, get the full info regarding result
        if changed:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method='GET',
                                   body='',
                                   signature=signature)
        else:
            result = slb_server_data
    elif operation == 'delete':
        if slb_server_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/' + slb_server,
                                   method='DELETE',
                                   body='',
                                   signature=signature)
            if axapi_failure(result):
                module.fail_json(msg="failed to delete server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the server was not present")
    elif operation == 'update':
        if slb_server_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'slb/server/',
                                   method='PUT',
                                   body=json.dumps(json_post),
                                   signature=signature)
            if axapi_failure(result):
                module.fail_json(msg="failed to update server: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the server was not present")

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call_v3(module,
                                     axapi_base_url + 'write/memory/',
                                     method='POST',
                                     body='',
                                     signature=signature)
        if axapi_failure(write_result):
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out gracefully and exit
    axapi_call_v3(module,
                  axapi_base_url + 'logoff/',
                  method='POST',
                  body='',
                  signature=signature)
    module.exit_json(changed=changed, content=result)
def main():
    argument_spec = a10_argument_spec()
    argument_spec.update(url_argument_spec())
    argument_spec.update(
        dict(
            partition=dict(type='str', required=False),
            operation=dict(type='str',
                           default='create',
                           choices=['create', 'update', 'delete']),
            pool_name=dict(type='str', required=True),
            start_address=dict(type='str', required=True),
            end_address=dict(type='str', required=True),
            netmask=dict(type='str', required=True),
            gateway=dict(type='str', required=False),
        ))

    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=False)

    host = module.params['host']
    username = module.params['username']
    password = module.params['password']
    partition = module.params['partition']
    operation = module.params['operation']
    write_config = module.params['write_config']
    ip_nat_pool_name = module.params['pool_name']
    ip_nat_pool_start_address = module.params['start_address']
    ip_nat_pool_end_address = module.params['end_address']
    ip_nat_pool_netmask = module.params['netmask']
    ip_nat_pool_gateway = module.params['gateway']

    # Initialize JSON to be POST
    json_post = {
        "pool": {
            "pool-name": ip_nat_pool_name,
            "start-address": ip_nat_pool_start_address,
            "end-address": ip_nat_pool_end_address,
            "netmask": ip_nat_pool_netmask
        }
    }

    json_post_create = {"pool-list": [{}]}

    if ip_nat_pool_gateway:
        json_post['pool']['gateway'] = ip_nat_pool_gateway

    json_post_create['pool-list'][0] = json_post['pool']
    #    module.fail_json(msg="JSON file is %s" % (json_post))

    # login A10 device and own signature
    axapi_base_url = 'https://{}/axapi/v3/'.format(host)
    axapi_auth_url = axapi_base_url + 'auth/'
    signature = axapi_authenticate_v3(module, axapi_auth_url, username,
                                      password)

    # GET existing partition list and check if the partition indicated in the playbook exists
    if partition:
        partition_list = axapi_call_v3(module,
                                       axapi_base_url + 'partition/',
                                       method='GET',
                                       body='',
                                       signature=signature)
        if axapi_failure(partition_list):
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(msg="There is no partition on the device: %s" %
                             (host))
        else:
            partition_list = [
                partition_attr['partition-name']
                for partition_attr in partition_list['partition-list']
            ]
            if partition in partition_list:
                result = axapi_call_v3(module,
                                       axapi_base_url + 'active-partition/' +
                                       partition,
                                       method='POST',
                                       body='',
                                       signature=signature)
                if axapi_failure(result):
                    axapi_call_v3(module,
                                  axapi_base_url + 'logoff/',
                                  method='POST',
                                  body='',
                                  signature=signature)
                    module.fail_json(
                        msg="failed to create the service group: %s" %
                        result['response']['err']['msg'])
            else:
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="The partition does not exist: %s" %
                                 (partition))

    # GET existing servers and check if the server already exits
    ip_nat_pool_data = axapi_call_v3(module,
                                     axapi_base_url + 'ip/nat/pool',
                                     method='GET',
                                     body='',
                                     signature=signature)
    if axapi_failure(ip_nat_pool_data):
        ip_nat_pool_exists = False
    else:
        ip_nat_pool_list = [
            ip_nat_pool['pool-name']
            for ip_nat_pool in ip_nat_pool_data['pool-list']
        ]
        if ip_nat_pool_name in ip_nat_pool_list:
            ip_nat_pool_exists = True
        else:
            ip_nat_pool_exists = False

    # POST configuration
    changed = False
    if operation == 'create':
        if ip_nat_pool_exists is False:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'ip/nat/pool',
                                   method='POST',
                                   body=json.dumps(json_post),
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to create the NAT Pool: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            changed = False
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(
                msg="NAT pool %s already exists, use 'update' instead" %
                (ip_nat_pool_name))
        # if we changed things, get the full info regarding result
        if changed:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'ip/nat/pool/' +
                                   ip_nat_pool_name,
                                   method='GET',
                                   body='',
                                   signature=signature)
        else:
            result = ip_nat_pool_data
    elif operation == 'delete':
        if ip_nat_pool_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'ip/nat/pool/' +
                                   ip_nat_pool_name,
                                   method='DELETE',
                                   body='',
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to delete NAT Pool: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the NAT Pool was not present: %s" %
                          (ip_nat_pool_name))
    elif operation == 'update':
        if ip_nat_pool_exists:
            result = axapi_call_v3(module,
                                   axapi_base_url + 'ip/nat/pool/' +
                                   ip_nat_pool_name,
                                   method='PUT',
                                   body=json.dumps(json_post),
                                   signature=signature)
            if axapi_failure(result):
                axapi_call_v3(module,
                              axapi_base_url + 'logoff/',
                              method='POST',
                              body='',
                              signature=signature)
                module.fail_json(msg="failed to update NAT Pool: %s" %
                                 result['response']['err']['msg'])
            changed = True
        else:
            result = dict(msg="the NAT Pool was not present: %s" %
                          (ip_nat_pool_name))

    # if the config has changed, save the config unless otherwise requested
    if changed and write_config:
        write_result = axapi_call_v3(module,
                                     axapi_base_url + 'write/memory/',
                                     method='POST',
                                     body='',
                                     signature=signature)
        if axapi_failure(write_result):
            axapi_call_v3(module,
                          axapi_base_url + 'logoff/',
                          method='POST',
                          body='',
                          signature=signature)
            module.fail_json(msg="failed to save the configuration: %s" %
                             write_result['response']['err']['msg'])

    # log out gracefully and exit
    axapi_call_v3(module,
                  axapi_base_url + 'logoff/',
                  method='POST',
                  body='',
                  signature=signature)
    module.exit_json(changed=changed, content=result)