diff --git a/library/net_infrastructure/a10_server b/library/net_infrastructure/a10_server new file mode 100644 index 00000000000..993ca7e8ce3 --- /dev/null +++ b/library/net_infrastructure/a10_server @@ -0,0 +1,225 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Ansible module to manage A10 Networks slb server objects +(c) 2014, Mischa Peters + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Ansible is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Ansible. If not, see . +""" + +DOCUMENTATION = ''' +--- +module: a10_server +version_added: 1.0 +short_description: Manage A10 Networks AX/SoftAX/Thunder/vThunder devices +description: + - Manage slb server objects on A10 Networks devices via aXAPI +author: Mischa Peters +notes: + - Requires A10 Networks aXAPI 2.1 +requirements: + - urllib2 + - re +options: + host: + description: + - hostname or ip of your A10 Networks device + required: true + default: null + aliases: [] + choices: [] + username: + description: + - admin account of your A10 Networks device + required: true + default: null + aliases: ['user', 'admin'] + choices: [] + password: + description: + - admin password of your A10 Networks device + required: true + default: null + aliases: ['pass', 'pwd'] + choices: [] + server_name: + description: + - slb server name + required: true + default: null + aliases: ['server'] + choices: [] + server_ip: + description: + - slb server IP address + required: false + default: null + aliases: ['ip', 'address'] + choices: [] + server_port: + description: + - slb server port + required: false + default: null + aliases: ['port'] + choices: [] + server_protocol: + description: + - slb server protocol + required: false + default: null + aliases: ['proto', 'protocol'] + choices: ['tcp', 'udp'] + server_status: + description: + - slb server status + required: false + default: enabled + aliases: ['status'] + choices: ['enable', 'disable'] + state: + description: + - create, update or remove slb server + required: false + default: present + aliases: [] + choices: ['present', 'absent'] +''' + +EXAMPLES = ''' +# Create a new server +ansible host -m a10_server -a "host=a10adc.example.com username=axapiuser password=axapipass server_name=realserver1 server_ip=192.168.1.23" + +# Add a port +ansible host -m a10_server -a "host=a10adc.example.com username=axapiuser password=axapipass server_name=realserver1 server_port=80 server_protocol=tcp" + +# Disable a server +ansible host -m a10_server -a "host=a10adc.example.com username=axapiuser password=axapipass server_name=realserver1 server_status=disable" +''' + +import urllib2 + + +def axapi_call(url, post=None): + result = urllib2.urlopen(url, post).read() + return result + + +def axapi_authenticate(base_url, user, pwd): + url = base_url + '&method=authenticate&username=' + user + \ + '&password=' + pwd + result = json.loads(axapi_call(url)) + if 'response' in result: + return module.fail_json(msg=result['response']['err']['msg']) + sessid = result['session_id'] + return base_url + '&session_id=' + sessid + + +def main(): + global module + module = AnsibleModule( + argument_spec=dict( + host=dict(type='str', required=True), + username=dict(type='str', aliases=['user', 'admin'], + required=True), + password=dict(type='str', aliases=['pass', 'pwd'], required=True), + server_name=dict(type='str', aliases=['server'], required=True), + server_ip=dict(type='str', aliases=['ip', 'address']), + server_port=dict(type='int', aliases=['port']), + server_protocol=dict(type='str', aliases=['proto', 'protocol'], + choices=['tcp', 'udp']), + server_status=dict(type='str', default='enable', + aliases=['status'], + choices=['enable', 'disable']), + state=dict(type='str', default='present', + choices=['present', 'absent']), + ), + supports_check_mode=False + ) + + host = module.params['host'] + user = module.params['username'] + pwd = module.params['password'] + slb_server = module.params['server_name'] + slb_server_ip = module.params['server_ip'] + slb_server_port = module.params['server_port'] + slb_server_proto = module.params['server_protocol'] + slb_server_status = module.params['server_status'] + state = module.params['state'] + + axapi_base_url = 'https://' + host + '/services/rest/V2.1/?format=json' + + if slb_server_proto == 'tcp' or slb_server_proto == 'TCP' or \ + slb_server_proto is None: + protocol = '2' + else: + protocol = '3' + + if slb_server_status == 'enable': + status = '1' + else: + status = '0' + + if slb_server is None: + module.fail_json(msg='server_name is required') + + if slb_server_port is None: + json_post = {'server': {'name': slb_server, + 'host': slb_server_ip, 'status': status}} + else: + json_post = {'server': {'name': slb_server, 'host': slb_server_ip, + 'status': status, 'port_list': + [{'port_num': slb_server_port, + 'protocol': protocol}]}} + + try: + session_url = axapi_authenticate(axapi_base_url, user, pwd) + + if state == 'present': + response = axapi_call(session_url + '&method=slb.server.search', + json.dumps({'name': slb_server})) + slb_server_exist = re.search(slb_server, response, re.I) + + if slb_server_exist is None: + if slb_server_ip is None: + module.fail_json(msg='IP address is required') + response = axapi_call(session_url + + '&method=slb.server.create', + json.dumps(json_post)) + else: + response = axapi_call(session_url + + '&method=slb.server.update', + json.dumps(json_post)) + + if state == 'absent': + response = axapi_call(session_url + + '&method=slb.server.delete', + json.dumps({'name': slb_server})) + + result = json.loads(response) + axapi_call(session_url + '&method=session.close') + + except Exception, e: + return module.fail_json(msg='received exception: %s' % e) + + if 'respone' in result and 'err' in result['response']: + return module.fail_json(msg=result['response']['err']['msg']) + + module.exit_json(changed=True, content=result) + +from ansible.module_utils.basic import * +main() diff --git a/library/net_infrastructure/a10_service_group b/library/net_infrastructure/a10_service_group new file mode 100644 index 00000000000..0a9f02f76a1 --- /dev/null +++ b/library/net_infrastructure/a10_service_group @@ -0,0 +1,267 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Ansible module to manage A10 Networks slb service-group objects +(c) 2014, Mischa Peters + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Ansible is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Ansible. If not, see . +""" + +DOCUMENTATION = ''' +--- +module: a10_service_group +version_added: 1.0 +short_description: Manage A10 Networks AX/SoftAX/Thunder/vThunder devices +description: + - Manage slb service-group objects on A10 Networks devices via aXAPI +author: Mischa Peters +notes: + - Requires A10 Networks aXAPI 2.1 + - When a server doesn't exist and is added to the service-group the server will be created +requirements: + - urllib2 + - re +options: + host: + description: + - hostname or ip of your A10 Networks device + required: true + default: null + aliases: [] + choices: [] + username: + description: + - admin account of your A10 Networks device + required: true + default: null + aliases: ['user', 'admin'] + choices: [] + password: + description: + - admin password of your A10 Networks device + required: true + default: null + aliases: ['pass', 'pwd'] + choices: [] + service_group: + description: + - slb service-group name + required: true + default: null + aliases: ['service', 'pool', 'group'] + choices: [] + service_group_protocol: + description: + - slb service-group protocol + required: false + default: tcp + aliases: ['proto', 'protocol'] + choices: ['tcp', 'udp'] + service_group_method: + description: + - slb service-group loadbalancing method + required: false + 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'] + server_name: + description: + - slb server name + required: false + default: null + aliases: ['server', 'member'] + choices: [] + server_port: + description: + - slb server port + required: false + default: null + aliases: ['port'] + choices: [] + server_status: + description: + - slb server status + required: false + default: enabled + aliases: ['status'] + choices: ['enable', 'disable'] + state: + description: + - create, remove or update slb service-group + required: false + default: present + aliases: [] + choices: ['present', 'absent'] +''' + +EXAMPLES = ''' +# Create a new service-group +ansible host -m a10_service_group -a "host=a10adc.example.com username=axapiuser password=axapipass service_group=sg-80-tcp" + +# Add a server +ansible host -m a10_service_group -a "host=a10adc.example.com username=axapiuser password=axapipass service_group=sg-80-tcp server_name=realserver1 server_port=80" + +# Disable a server +ansible host -m a10_service_group -a "host=a10adc.example.com username=axapiuser password=axapipass service_group=sg-80-tcp server_name=realserver1 server_port=80 status=disable" +''' + +import urllib2 + + +def axapi_call(url, post=None): + result = urllib2.urlopen(url, post).read() + return result + + +def axapi_authenticate(base_url, user, pwd): + url = base_url + '&method=authenticate&username=' + user + \ + '&password=' + pwd + result = json.loads(axapi_call(url)) + if 'response' in result: + return module.fail_json(msg=result['response']['err']['msg']) + sessid = result['session_id'] + return base_url + '&session_id=' + sessid + + +def main(): + global module + module = AnsibleModule( + argument_spec=dict( + host=dict(type='str', required=True), + username=dict(type='str', aliases=['user', 'admin'], + required=True), + password=dict(type='str', aliases=['pass', 'pwd'], required=True), + 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']), + server_name=dict(type='str', aliases=['server', 'member']), + server_port=dict(type='int', aliases=['port']), + server_status=dict(type='str', default='enable', + aliases=['status'], + choices=['enable', 'disable']), + state=dict(type='str', default='present', + choices=['present', 'absent']), + ), + supports_check_mode=False + ) + + host = module.params['host'] + user = module.params['username'] + pwd = module.params['password'] + 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_server = module.params['server_name'] + slb_server_port = module.params['server_port'] + slb_server_status = module.params['server_status'] + state = module.params['state'] + + 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 slb_service_group_proto == 'tcp' or slb_service_group_proto == 'TCP': + protocol = '2' + else: + protocol = '3' + + if slb_server_status == 'enable': + status = '1' + else: + status = '0' + + if slb_service_group is None: + module.fail_json(msg='service_group is required') + + if slb_server is None and slb_server_port is None: + json_post = {'service_group': {'name': slb_service_group, + 'protocol': protocol, + 'lb_method': load_balancing_methods[slb_service_group_method]}} + elif slb_server is not None and slb_server_port is not None: + json_post = {'service_group': {'name': slb_service_group, + 'protocol': protocol, + 'lb_method': load_balancing_methods[slb_service_group_method], + 'member_list': + [{'server': slb_server, + 'port': slb_server_port, + 'status': status}]}} + else: + module.fail_json(msg='server_name and server_name_port are \ + required to add to the service-group') + + try: + session_url = axapi_authenticate(axapi_base_url, user, pwd) + + if state == 'present': + response = axapi_call(session_url + + '&method=slb.service_group.search', + json.dumps({'name': slb_service_group})) + slb_service_group_exist = re.search(slb_service_group, + response, re.I) + + if slb_service_group_exist is None: + response = axapi_call(session_url + + '&method=slb.service_group.create', + json.dumps(json_post)) + else: + response = axapi_call(session_url + + '&method=slb.service_group.update', + json.dumps(json_post)) + + if state == 'absent': + response = axapi_call(session_url + + '&method=slb.service_group.delete', + json.dumps({'name': slb_service_group})) + + result = json.loads(response) + axapi_call(session_url + '&method=session.close') + + except Exception, e: + return module.fail_json(msg='received exception: %s' % e) + + if 'respone' in result and 'err' in result['response']: + return module.fail_json(msg=result['response']['err']['msg']) + + module.exit_json(changed=True, content=result) + +from ansible.module_utils.basic import * +main() diff --git a/library/net_infrastructure/a10_virtual b/library/net_infrastructure/a10_virtual new file mode 100644 index 00000000000..aed49ce3ea5 --- /dev/null +++ b/library/net_infrastructure/a10_virtual @@ -0,0 +1,352 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +Ansible module to manage A10 Networks slb virtual server objects +(c) 2014, Mischa Peters + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Ansible is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Ansible. If not, see . +""" + +DOCUMENTATION = ''' +--- +module: a10_virtual_server +version_added: 1.0 +short_description: Manage A10 Networks AX/SoftAX/Thunder/vThunder devices +description: + - Manage slb virtual server objects on A10 Networks devices via aXAPI +author: Mischa Peters +notes: + - Requires A10 Networks aXAPI 2.1 +requirements: + - urllib2 + - re +options: + host: + description: + - hostname or ip of your A10 Networks device + required: true + default: null + aliases: [] + choices: [] + username: + description: + - admin account of your A10 Networks device + required: true + default: null + aliases: ['user', 'admin'] + choices: [] + password: + description: + - admin password of your A10 Networks device + required: true + default: null + aliases: ['pass', 'pwd'] + choices: [] + virtual_server: + description: + - slb virtual server name + required: true + default: null + aliases: ['vip', 'virtual'] + choices: [] + virtual_server_ip: + description: + - slb virtual server ip address + required: false + default: null + aliases: ['ip', 'address'] + choices: [] + virtual_server_status: + description: + - slb virtual server status + required: false + default: enable + aliases: ['status'] + choices: ['enabled', 'disabled'] + virtual_server_port: + description: + - slb virtual server port + required: false + default: round-robin + aliases: ['port', 'vport'] + choices: [] + virtual_server_type: + description: + - slb virtual server port type + required: false + default: null + aliases: ['proto', 'protocol'] + choices: ['tcp', 'udp', 'fast-http', 'http', 'https'] + virtual_server_port_status: + description: + - slb virtual server port status + required: false + default: enable + aliases: ['status'] + choices: ['enabled', 'disabled'] + service_group: + description: + - slb virtual server service-group + required: false + default: enabled + aliases: ['pool', 'group'] + choices: [] + state: + description: + - create, update or remove slb virtual server + required: false + default: present + aliases: [] + choices: ['present', 'absent'] +''' + +EXAMPLES = ''' +# Create a new virtual server +ansible host -m a10_virtual -a "host=a10adc.example.com username=axapiuser password=axapipass virtual_server=vip1 virtual_server_ip=192.168.1.20" + +# Add a virtual port +ansible host -m a10_virtual -a "host=a10adc.example.com username=axapiuser password=axapipass virtual_server=vip1 virtual_server_ip=192.168.1.20 virtual_server_port=80 virtual_server_port_type=http service_group=sg-80-tcp" + +# Disable a virtual server +ansible host -m a10_virtual -a "host=a10adc.example.com username=axapiuser password=axapipass virtual_server=vip1 status=disable" + +# Disable a virtual server port +ansible host -m a10_virtual -a "host=a10adc.example.com username=axapiuser password=axapipass virtual_server=vip1 virtual_server_port=80 virtual_server_port_type=http virtual_server_port_status=disable" +''' + +import urllib2 + + +def axapi_call(url, post=None): + result = urllib2.urlopen(url, post).read() + return result + + +def axapi_authenticate(base_url, user, pwd): + url = base_url + '&method=authenticate&username=' + user + \ + '&password=' + pwd + result = json.loads(axapi_call(url)) + if 'response' in result: + return module.fail_json(msg=result['response']['err']['msg']) + sessid = result['session_id'] + return base_url + '&session_id=' + sessid + + +def main(): + global module + module = AnsibleModule( + argument_spec=dict( + host=dict(type='str', required=True), + username=dict(type='str', aliases=['user', 'admin'], + required=True), + password=dict(type='str', aliases=['pass', 'pwd'], + required=True), + virtual_server=dict(type='str', aliases=['vip', 'virtual'], + required=True), + virtual_server_ip=dict(type='str', + aliases=['ip', 'address']), + virtual_server_status=dict(type='str', default='enabled', + aliases=['status'], + choices=['enabled', 'disabled']), + virtual_server_port=dict(type='int', + aliases=['port', 'vport']), + virtual_server_port_type=dict(type='str', + aliases=['proto', 'protocol'], + choices=['tcp', 'udp', 'fast-http', + 'http', 'https']), + virtual_server_port_status=dict(type='str', default='enabled', + aliases=['portstatus', + 'port_status'], + choices=['enabled', 'disabled']), + service_group=dict(type='str', aliases=['pool', 'group']), + state=dict(type='str', default='present', + choices=['present', 'absent']), + ), + supports_check_mode=False + ) + + host = module.params['host'] + user = module.params['username'] + pwd = module.params['password'] + slb_virtual = module.params['virtual_server'] + slb_virtual_ip = module.params['virtual_server_ip'] + slb_virtual_status = module.params['virtual_server_status'] + slb_virtual_port = module.params['virtual_server_port'] + slb_virtual_port_type = module.params['virtual_server_port_type'] + slb_virtual_port_status = module.params['virtual_server_port_status'] + slb_service_group = module.params['service_group'] + state = module.params['state'] + + axapi_base_url = 'https://' + host + '/services/rest/V2.1/?format=json' + vport_types = {'tcp': 2, + 'udp': 3, + 'fast-http': 9, + 'http': 11, + 'https': 12} + + if slb_virtual_status == 'enabled': + status = '1' + else: + status = '0' + + if slb_virtual_port_status == 'enabled': + port_status = '1' + else: + port_status = '0' + + if slb_virtual is None: + module.fail_json(msg='virtual_server is required') + + try: + session_url = axapi_authenticate(axapi_base_url, user, pwd) + + if state == 'present': + find_slb_virtual = axapi_call(session_url + + '&method=slb.virtual_server.search', + json.dumps({'name': slb_virtual})) + slb_virtual_fail = re.search('status": "fail', + find_slb_virtual, re.I) + + if slb_virtual_fail: + if slb_virtual_port is None and slb_virtual_port_type is None \ + and slb_service_group is None: + json_post = {'virtual_server': {'name': slb_virtual, + 'address': slb_virtual_ip, + 'status': status}} + elif slb_virtual_port is not None and \ + slb_virtual_port_type is not None and \ + slb_service_group is None: + json_post = {'virtual_server': + {'name': slb_virtual, + 'address': slb_virtual_ip, + 'status': status, + 'vport_list': + [{'protocol': + vport_types[slb_virtual_port_type], + 'port': slb_virtual_port}]}} + elif slb_virtual_port is not None and \ + slb_virtual_port_type is not None and \ + slb_service_group is not None: + json_post = {'virtual_server': + {'name': slb_virtual, + 'address': slb_virtual_ip, + 'status': status, 'vport_list': + [{'protocol': + vport_types[slb_virtual_port_type], + 'port': slb_virtual_port, + 'service_group': slb_service_group}]}} + else: + module.fail_json(msg='virtual_server_port and + virtual_server_type are required to + create the virtual port') + + response = axapi_call(session_url + + '&method=slb.virtual_server.create', + json.dumps(json_post)) + else: + response = axapi_call(session_url + + '&method=slb.virtual_server.search', + json.dumps({'name': slb_virtual})) + slb_virtual_port_exist = re.search('"port":' + + str(slb_virtual_port) + response, re.I) + current_status = json.loads(response)['virtual_server']['status'] + current_port_status = 1 + + if slb_virtual_port_exist: + vport_list = json.loads(response)['virtual_server']['vport_list'] + if vport_list: + for port in range(len(vport_list)): + if slb_virtual_port == str(vport_list[port]['port']): + current_port_status = vport_list[port]['port'] + + json_post = {'address': slb_virtual_ip, + 'vport': + {'protocol': + vport_types[slb_virtual_port_type], + 'port': slb_virtual_port, + 'service_group': slb_service_group}, + 'status': port_status} + response = axapi_call(session_url + + '&method=slb.virtual_server.\ + vport.update', json.dumps(json_post)) + else: + if slb_service_group is None: + module.fail_json(msg='service_group is required') + json_post = {'name': slb_virtual, + 'vport': + {'protocol': + vport_types[slb_virtual_port_type], + 'port': slb_virtual_port, + 'service_group': slb_service_group}, + 'status': port_status} + response = axapi_call(session_url + + '&method=slb.virtual_server.\ + vport.create', json.dumps(json_post)) + + if current_status != status: + json_post = {'virtual_server': + {'name': slb_virtual, + 'address': slb_virtual_ip, + 'status': status}} + response = axapi_call(session_url + + '&method=slb.virtual_server.update', + json.dumps(json_post)) + + if current_port_status != port_status: + json_post = {'address': slb_virtual_ip, 'vport': + {'protocol': + vport_types[slb_virtual_port_type], + 'port': slb_virtual_port}, + 'status': port_status} + response = axapi_call(session_url + + '&method=slb.virtual_server.\ + vport.update', json.dumps(json_post)) + + if state == 'absent': + if slb_virtual_port is not None and \ + slb_virtual_port_type is not None: + response = axapi_call(session_url + + '&method=slb.virtual_server.\ + vport.delete', + json.dumps({'name': slb_virtual, + 'vport': + {'protocol': + vport_types[slb_virtual_port_type], + 'port': slb_virtual_port}})) + elif slb_virtual_port is None and slb_virtual_port_type is None: + response = axapi_call(session_url + + '&method=slb.virtual_server.delete', + json.dumps({'name': slb_virtual})) + else: + module.fail_json(msg='virtual_server_port and \ + virtual_server_type are required to remove \ + the virtual port') + + result = json.loads(response) + axapi_call(session_url + '&method=session.close') + + except Exception, e: + return module.fail_json(msg='received exception: %s' % e) + + if 'respone' in result and 'err' in result['response']: + return module.fail_json(msg=result['response']['err']['msg']) + + module.exit_json(changed=True, content=result) + +from ansible.module_utils.basic import * +main()