def write_memory(module, signature): host = module.params['a10_host'] axapi_version = module.params['axapi_version'] if axapi_version == '3': axapi_base_url = 'https://{}/axapi/v3/'.format(host) result = axapi_call_v3(module, axapi_base_url + 'write/memory/', method='POST', body='', signature=signature) if axapi_failure(result): axapi_close_session(module, signature) module.fail_json(msg="Failed to write config: %s" % result['response']['err']['msg'])
def change_partition(module, signature): host = module.params['a10_host'] partition = module.params['partition'] axapi_version = module.params['axapi_version'] if axapi_version == '3': axapi_base_url = 'https://{}/axapi/v3/'.format(host) result = axapi_call_v3(module, axapi_base_url + 'active-partition/' + partition, method='POST', body='', signature=signature) if axapi_failure(result): axapi_close_session(module, signature) module.fail_json(msg="Failed to change partition: %s" % result['response']['err']['msg'])
def axapi_close_session(module, signature): host = module.params['a10_host'] axapi_version = module.params['axapi_version'] if axapi_version == '3': axapi_logoff_url = 'https://{}/axapi/v3/logoff/'.format(host) result = axapi_call_v3(module, axapi_logoff_url, method='POST', body='', signature=signature) elif axapi_version == '2.1': axapi_logoff_url = signature + '&method=session.close' result = axapi_call(module, axapi_logoff_url) if axapi_failure(result): module.fail_json(msg="Failed to close aXAPI session: %s" % result['response']['err']['msg'])
def axapi_open_session(module): host = module.params['a10_host'] username = module.params['a10_username'] password = module.params['a10_password'] axapi_version = module.params['axapi_version'] if axapi_version == '3': axapi_auth_url = 'https://{}/axapi/v3/auth/'.format(host) rv = axapi_authenticate_v3(module, axapi_auth_url, username, password) elif axapi_version == '2.1': axapi_auth_url = 'https://{}/services/rest/V2.1/'.format(host) rv = axapi_authenticate(module, axapi_auth_url, username, password) if axapi_failure(rv): module.fail_json(msg="Failed to open aXAPI session: %s" % result['response']['err']['msg']) return rv
def diff_config(module, signature, result, status): host = module.params['a10_host'] axapi_version = module.params['axapi_version'] # Initialize return values differences = 0 config_before = {} if axapi_version == '3': axapi_base_url = 'https://{}/axapi/v3/'.format(host) result_list = axapi_call_v3(module, axapi_base_url + FIRST_LEVEL, method='GET', body='', signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json(msg="Failed to obtain current %s setup %s." % (FIRST_LEVEEL, result_list)) else: component_list = [] if result_list[FIRST_LEVEL].has_key(SECOND_LEVEL_LIST): result_list = axapi_call_v3(module, axapi_base_url + FIRST_LEVEL + '/' + SECOND_LEVEL, method='GET', body='', signature=signature) for config_list in result_list[SECOND_LEVEL_LIST]: mandatory_attributes_in_config = [] for mandatory_attribute_in_config in MANDATORY_ATTRIBUTES.values( ): mandatory_attributes_in_config.append( config_list[mandatory_attribute_in_config]) component_list.append(mandatory_attributes_in_config) else: result_list = {SECOND_LEVEL: {}} config_before = copy.deepcopy(result_list) mandatory_attributes_in_playbook = [] for mandatory_attribute_in_playbook in MANDATORY_ATTRIBUTES.keys(): if not (module.params[mandatory_attribute_in_playbook] is None): mandatory_attributes_in_playbook.append( module.params[mandatory_attribute_in_playbook]) if mandatory_attributes_in_playbook in component_list: component_path = mandatory_attributes_in_playbook[0] mandatory_attributes_in_playbook.pop(0) for mandatory_attribute_in_playbook in mandatory_attributes_in_playbook: component_path = component_path + '+' + mandatory_attribute_in_playbook result_list = axapi_call_v3(module, axapi_base_url + FIRST_LEVEL + '/' + SECOND_LEVEL + '/' + str(component_path), method='GET', body='', signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json( msg="Failed to obtain %s %s %s information." % (FIRST_LEVEL, SECOND_LEVEL, component_path)) else: config_before = copy.deepcopy(result_list) json_post = copy.deepcopy(result_list) diff_sw = False same_sw = False absent_sw = False for playbook_attribute in COMPONENT_ATTRIBUTES.keys(): if not (module.params[playbook_attribute] is None): if result_list[SECOND_LEVEL].has_key( COMPONENT_ATTRIBUTES[playbook_attribute]): if result_list[SECOND_LEVEL][COMPONENT_ATTRIBUTES[ playbook_attribute]] != module.params[ playbook_attribute]: diff_sw = True else: same_sw = True if status == 'absent': json_post[SECOND_LEVEL].pop( COMPONENT_ATTRIBUTES[ playbook_attribute]) else: absent_sw = True if status == 'present': for mutually_exclusive_list in MUTUALLY_EXCLUSIVE_ATTRIBUTES_SET: if playbook_attribute in mutually_exclusive_list: mutually_exclusive_list.remove( playbook_attribute) for current_attribute_removed in mutually_exclusive_list: if json_post[SECOND_LEVEL].has_key( COMPONENT_ATTRIBUTES_ALL[ current_attribute_removed] ): json_post[SECOND_LEVEL].pop( COMPONENT_ATTRIBUTES_ALL[ current_attribute_removed] ) json_post[SECOND_LEVEL][COMPONENT_ATTRIBUTES[ playbook_attribute]] = module.params[ playbook_attribute] for playbook_attribute in COMPONENT_ATTRIBUTES_BOOLEAN.keys( ): if not (module.params[playbook_attribute] is None): if result_list[SECOND_LEVEL].has_key( COMPONENT_ATTRIBUTES_BOOLEAN[ playbook_attribute]): if result_list[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_BOOLEAN[ playbook_attribute]] != module.params[ playbook_attribute]: diff_sw = True else: same_sw = True if status == 'absent': json_post[SECOND_LEVEL].pop( COMPONENT_ATTRIBUTES_BOOLEAN[ playbook_attribute]) else: absent_sw = True if status == 'present': for mutually_exclusive_list in MUTUALLY_EXCLUSIVE_ATTRIBUTES_SET: if playbook_attribute in mutually_exclusive_list: mutually_exclusive_list.remove( playbook_attribute) for current_attribute_removed in mutually_exclusive_list: if json_post[SECOND_LEVEL].has_key( COMPONENT_ATTRIBUTES_ALL[ current_attribute_removed] ): json_post[SECOND_LEVEL].pop( COMPONENT_ATTRIBUTES_ALL[ current_attribute_removed] ) json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_BOOLEAN[ playbook_attribute]] = module.params[ playbook_attribute] for playbook_attribute in COMPONENT_ATTRIBUTES_LIST.keys(): if not (module.params[playbook_attribute] is None): if result_list[SECOND_LEVEL].has_key( COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]): json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]] = [] current_lists = copy.deepcopy( result_list[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]]) playbook_lists = copy.deepcopy( module.params[playbook_attribute]) current_lists_rest = copy.deepcopy( current_lists) playbook_lists_rest = copy.deepcopy( playbook_lists) for playbook_list in playbook_lists: for current_list in current_lists: current_list_mandatory_values = [] current_list_options = copy.deepcopy( current_list) playbook_list_mandatory_values = [] playbook_list_options = copy.deepcopy( playbook_list) json_post_list = copy.deepcopy( current_list) if COMPONENT_ATTRIBUTES_LIST_MANDATORIES.has_key( playbook_attribute): for list_mandatory_key in COMPONENT_ATTRIBUTES_LIST_MANDATORIES[ playbook_attribute]: current_list_mandatory_values.append( current_list[ list_mandatory_key]) current_list_options.pop( list_mandatory_key) playbook_list_mandatory_values.append( playbook_list[ list_mandatory_key]) playbook_list_options.pop( list_mandatory_key) if set( current_list_mandatory_values ) == set(playbook_list_mandatory_values ): if playbook_list_options != {}: playbook_options_included = True if list( set(playbook_list_options ) - set(current_list_options )) != []: playbook_options_included = False for playbook_list_option_key in playbook_list_options.keys( ): if current_list_options.has_key( playbook_list_option_key ): if playbook_list_options[ playbook_list_option_key] != current_list_options[ playbook_list_option_key]: playbook_options_included = False if playbook_options_included: same_sw = True else: diff_sw = True if status == 'present': for playbook_list_key in playbook_list.keys( ): json_post_list[ playbook_list_key] = playbook_list[ playbook_list_key] if status == 'absent': if playbook_list_options != []: for playbook_list_key in playbook_list.keys( ): if (json_post_list[ playbook_list_key] == playbook_list[ playbook_list_key] ) and not ( playbook_list_key in COMPONENT_ATTRIBUTES_LIST_MANDATORIES[ playbook_attribute] ): json_post_list.pop( playbook_list_key ) json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]].append( json_post_list) else: if status == 'absent': diff_sw = True if status == 'present': json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]].append( current_list) current_lists_rest.remove( current_list) playbook_lists_rest.remove( playbook_list) if current_lists_rest != []: for current_list in current_lists_rest: json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]].append( current_list) if playbook_lists_rest != []: absent_sw = True if status == 'present': for playbook_list in playbook_lists_rest: json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]].append( playbook_list) else: absent_sw = True if status == 'present': for mutually_exclusive_list in MUTUALLY_EXCLUSIVE_ATTRIBUTES_SET: if playbook_attribute in mutually_exclusive_list: mutually_exclusive_list.remove( playbook_attribute) for current_attribute_removed in mutually_exclusive_list: if json_post[SECOND_LEVEL].has_key( COMPONENT_ATTRIBUTES_ALL[ current_attribute_removed] ): json_post[SECOND_LEVEL].pop( COMPONENT_ATTRIBUTES_ALL[ current_attribute_removed] ) json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]] = module.params[ playbook_attribute] if absent_sw and not (diff_sw) and not (same_sw): differences = 4 elif not (absent_sw) and not (diff_sw) and not (same_sw): differences = 5 elif not (absent_sw) and not (diff_sw) and same_sw: differences = 2 else: differences = 3 else: #there is no existing SECOND_LEVEL component in the current config differences = 1 if status == 'present': json_post = {SECOND_LEVEL: {}} for playbook_attribute in MANDATORY_ATTRIBUTES.keys(): if not (module.params[playbook_attribute] is None): json_post[SECOND_LEVEL][MANDATORY_ATTRIBUTES[ playbook_attribute]] = module.params[ playbook_attribute] for playbook_attribute in COMPONENT_ATTRIBUTES.keys(): if not (module.params[playbook_attribute] is None): json_post[SECOND_LEVEL][COMPONENT_ATTRIBUTES[ playbook_attribute]] = module.params[ playbook_attribute] for playbook_attribute in COMPONENT_ATTRIBUTES_BOOLEAN.keys( ): if not (module.params[playbook_attribute] is None): json_post[SECOND_LEVEL][ COMPONENT_ATTRIBUTES_BOOLEAN[ playbook_attribute]] = module.params[ playbook_attribute] for playbook_attribute in COMPONENT_ATTRIBUTES_LIST.keys(): if not (module.params[playbook_attribute] is None): json_post[SECOND_LEVEL][COMPONENT_ATTRIBUTES_LIST[ playbook_attribute]] = module.params[ playbook_attribute] elif status == 'absent': json_post = {} return differences, config_before, json_post
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)
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( 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)
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)
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)
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)
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)
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( 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)
def absent(module, signature, result): differences, config_before, json_post = diff_config(module, signature, result, status='absent') result['original_message'] = differences if differences == 1: result['msg'] = "Playbook's root element is not in the current config." elif differences == 2: result[ 'msg'] = "Playbook's config is entirely included in the current config." elif differences == 3: result[ 'msg'] = "Playbook's config is partially different from current config." elif differences == 4: result[ 'msg'] = "All playbook's config attributes are not in the current config." elif differences == 5: result[ 'msg'] = "Playbook indicates only the root element in the current config." result['post_config'] = json_post host = module.params['a10_host'] axapi_version = module.params['axapi_version'] if axapi_version == '3': if differences == 2 or differences == 3: axapi_base_url = 'https://{}/axapi/v3/'.format(host) mandatory_attributes_in_playbook = copy.deepcopy( MANDATORY_ATTRIBUTES.keys()) component_path = module.params[mandatory_attributes_in_playbook[0]] mandatory_attributes_in_playbook.pop(0) for mandatory_attribute_in_playbook in mandatory_attributes_in_playbook: component_path = component_path + '+' + module.params[ mandatory_attribute_in_playbook] result_list = axapi_call_v3(module, axapi_base_url + FIRST_LEVEL + '/' + SECOND_LEVEL + '/' + str(component_path), method='PUT', body=json.dumps(json_post), signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json( msg="Failed to delete elemetns of %s %s: %s." % (FIRST_LEVEL, SECOND_LEVEL, result_list)) else: if config_before != result_list: result["changed"] = True else: result["changed"] = False elif differences == 5: axapi_base_url = 'https://{}/axapi/v3/'.format(host) mandatory_attributes_in_playbook = copy.deepcopy( MANDATORY_ATTRIBUTES.keys()) component_path = module.params[mandatory_attributes_in_playbook[0]] mandatory_attributes_in_playbook.pop(0) for mandatory_attribute_in_playbook in mandatory_attributes_in_playbook: component_path = component_path + '+' + module.params[ mandatory_attribute_in_playbook] result_list = axapi_call_v3(module, axapi_base_url + FIRST_LEVEL + '/' + SECOND_LEVEL + '/' + str(component_path), method='DELETE', body='', signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json(msg="Failed to delete %s %s: %s." % (FIRST_LEVEL, SECOND_LEVEL, result_list)) else: result["changed"] = True else: result_list = copy.deepcopy(config_before) result['diff']['before'] = config_before result['diff']['after'] = result_list return result
def diff_config(module, signature, result, status): host = module.params['a10_host'] axapi_version = module.params['axapi_version'] vlan_num = module.params['vlan_num'] name = module.params['name'] user_tag = module.params['user_tag'] shared_vlan = module.params['shared_vlan'] ve = module.params['ve'] tagged_eth_list = module.params['tagged_eth_list'] tagged_trunk_list = module.params['tagged_trunk_list'] untagged_eth_list = module.params['untagged_eth_list'] untagged_trunk_list = module.params['untagged_trunk_list'] untagged_lif = module.params['untagged_lif'] # Initialize return values differences = 0 config_before = {} if axapi_version == '3': axapi_base_url = 'https://{}/axapi/v3/'.format(host) result_list = axapi_call_v3(module, axapi_base_url + 'network', method='GET', body='', signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json(msg="Failed to obtain current network setup %s." % result_list) else: if result_list['network'].has_key('vlan-list'): result_list = axapi_call_v3(module, axapi_base_url + 'network/vlan', method='GET', body='', signature=signature) vlan = [vlan['vlan-num'] for vlan in result_list['vlan-list']] else: result_list = {"vlan": {}} vlan = [] config_before = copy.deepcopy(result_list) if vlan_num in vlan: result_list = axapi_call_v3(module, axapi_base_url + 'network/vlan/' + str(vlan_num), method='GET', body='', signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json(msg="Failed to obtain vlan information.") else: config_before = copy.deepcopy(result_list) json_post = copy.deepcopy(result_list) # json_post['vlan'].pop('uuid') # json_post['vlan'].pop('a10-url') diff_sw = 0 same_sw = 0 absent_sw = 0 if name: if result_list['vlan'].has_key('name'): if result_list['vlan']['name'] != name: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('name') else: absent_sw = 1 if status == 'present': json_post['vlan']['name'] = name if user_tag: if result_list['vlan'].has_key('user-tag'): if result_list['vlan']['user-tag'] != user_tag: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('user-tag') else: absent_sw = 1 if status == 'present': json_post['vlan']['user-tag'] = user_tag if int(shared_vlan): if result_list['vlan'].has_key('shared-vlan'): if result_list['vlan'][ 'shared-vlan'] != shared_vlan: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('shared-vlan') else: absent_sw = 1 if status == 'present': json_post['vlan']['shared-vlan'] = shared_vlan if ve: if result_list['vlan'].has_key('ve'): if result_list['vlan']['ve'] != ve: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('ve') else: absent_sw = 1 if status == 'present': json_post['vlan']['ve'] = ve if tagged_eth_list: if result_list['vlan'].has_key('tagged-eth-list'): if result_list['vlan'][ 'tagged-eth-list'] != tagged_eth_list: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('tagged-eth-list') else: absent_sw = 1 if status == 'present': json_post['vlan'][ 'tagged-eth-list'] = tagged_eth_list if tagged_trunk_list: if result_list['vlan'].has_key('tagged-trunk-list'): if result_list['vlan'][ 'tagged-trunk-list'] != tagged_trunk_list: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('tagged-trunk-list') else: absent_sw = 1 if status == 'present': json_post['vlan'][ 'tagged-trunk-list'] = tagged_trunk_list if untagged_eth_list: if result_list['vlan'].has_key('untagged-eth-list'): if result_list['vlan'][ 'untagged-eth-list'] != untagged_eth_list: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('untagged-eth-list') else: absent_sw = 1 if status == 'present': json_post['vlan'][ 'untagged-eth-list'] = untagged_eth_list if untagged_trunk_list: if result_list['vlan'].has_key('untagged-trunk-list'): if result_list['vlan'][ 'untagged-trunk-list'] != untagged_trunk_list: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop( 'untagged-trunk-list') else: absent_sw = 1 if status == 'present': json_post['vlan'][ 'untagged-trunk-list'] = untagged_trunk_list if untagged_lif: if result_list['vlan'].has_key('untagged-lif'): if result_list['vlan'][ 'untagged-lif'] != untagged_lif: diff_sw = 1 else: same_sw = 1 if status == 'absent': json_post['vlan'].pop('untagged-lif') else: absent_sw = 1 if status == 'present': json_post['vlan']['untagged-lif'] = untagged_lif if absent_sw and not (diff_sw) and not (same_sw): differences = 4 elif diff_sw: differences = 3 elif same_sw and not (diff_sw): differences = 2 else: differences = 5 else: #there is no existing vlan whose number is vlan-num differences = 1 if status == 'present': json_post = {"vlan": {"vlan-num": vlan_num}} if name: json_post['vlan']['name'] = name if user_tag: json_post['vlan']['user-tag'] = user_tag if int(shared_vlan): json_post['vlan']['shared-vlan'] = shared_vlan if ve: json_post['vlan']['ve'] = ve if tagged_eth_list: json_post['vlan']['tagged-eth-list'] = tagged_eth_list if tagged_trunk_list: json_post['vlan'][ 'tagged-trunk-list'] = tagged_trunk_list if untagged_eth_list: json_post['vlan'][ 'untagged-eth-list'] = untagged_eth_list if untagged_trunk_list: json_post['vlan'][ 'untagged-trunk-list'] = untagged_trunk_list if untagged_lif: json_post['vlan']['untagged-lif'] = untagged_lif elif status == 'absent': json_post = {} return differences, config_before, json_post
def absent(module, signature, result): differences, config_before, json_post = diff_config(module, signature, result, status='absent') result['original_message'] = differences if differences == 1: result['msg'] = "Playbook's root element is not in the current config." elif differences == 2: result[ 'msg'] = "Playbook's config is entirely included in the current config." elif differences == 3: result[ 'msg'] = "Playbook's config is partially different from current config." elif differences == 4: result[ 'msg'] = "All playbook's config attributes are not in the current config." elif differences == 5: result[ 'msg'] = "Playbook indicates only the root element in the current config." result['post_config'] = json_post host = module.params['a10_host'] axapi_version = module.params['axapi_version'] vlan_num = module.params['vlan_num'] if axapi_version == '3': if differences == 2 or differences == 3: axapi_base_url = 'https://{}/axapi/v3/'.format(host) result_list = axapi_call_v3(module, axapi_base_url + 'network/vlan/' + str(vlan_num), method='PUT', body=json.dumps(json_post), signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json(msg="Failed to delete elemetns of VLAN: %s." % result_list) else: result["changed"] = True elif differences == 5: axapi_base_url = 'https://{}/axapi/v3/'.format(host) result_list = axapi_call_v3(module, axapi_base_url + 'network/vlan/' + str(vlan_num), method='DELETE', body='', signature=signature) if axapi_failure(result_list): axapi_close_session(module, signature) module.fail_json(msg="Failed to delete VLAN: %s." % result_list) else: result["changed"] = True else: result_list = copy.deepcopy(config_before) result['diff']['before'] = config_before result['diff']['after'] = result_list return result
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)
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)
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)