From e5b6abadafcf80bef87369681c0937169489ebc8 Mon Sep 17 00:00:00 2001 From: Simon Dodsley Date: Tue, 30 Oct 2018 05:43:23 -0400 Subject: [PATCH] Add Pure Storage FlashBlade module to manage network interfaces (#44421) --- .../storage/purestorage/purefb_network.py | 197 ++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 lib/ansible/modules/storage/purestorage/purefb_network.py diff --git a/lib/ansible/modules/storage/purestorage/purefb_network.py b/lib/ansible/modules/storage/purestorage/purefb_network.py new file mode 100644 index 00000000000..406a6a9a557 --- /dev/null +++ b/lib/ansible/modules/storage/purestorage/purefb_network.py @@ -0,0 +1,197 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2017, Simon Dodsley (simon@purestorage.com) +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: purefb_network +version_added: "2.8" +short_description: Manage network interfaces in a Pure Storage FlashBlade +description: + - This module manages network interfaces on Pure Storage FlashBlade. + - When creating a network interface a subnet must already exist with + a network prefix that covers the IP address of the interface being + created. +author: Simon Dodsley (@sdodsley) +options: + name: + description: + - Interface Name. + required: true + state: + description: + - Create, delete or modifies a network interface. + required: false + default: present + choices: [ "present", "absent" ] + address: + description: + - IP address of interface. + required: false + services: + description: + - Define which services are configured for the interfaces. + required: false + choices: [ "data" ] + default: data + itype: + description: + - Type of interface. + required: false + choices: [ "vip" ] + default: vip +extends_documentation_fragment: + - purestorage.fb +''' + +EXAMPLES = ''' +- name: Create new network interface named foo + purefb_network: + name: foo + address: 10.21.200.23 + state: present + fb_url: 10.10.10.2 + api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 + +- name: Change IP address of network interface named foo + purefb_network: + name: foo + state: present + address: 10.21.200.123 + fb_url: 10.10.10.2 + api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641 + +- name: Delete network interface named foo + purefb_network: + name: foo + state: absent + fb_url: 10.10.10.2 + api_token: T-55a68eb5-c785-4720-a2ca-8b03903bf641''' + +RETURN = ''' +''' + +HAS_PURITY_FB = True +try: + from purity_fb import NetworkInterface +except ImportError: + HAS_PURITY_FB = False + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.pure import get_blade, purefb_argument_spec + + +MINIMUM_API_VERSION = '1.3' + + +def get_iface(module, blade): + """Return Filesystem or None""" + iface = [] + iface.append(module.params['name']) + try: + res = blade.network_interfaces.list_network_interfaces(names=iface) + return res.items[0] + except: + return None + + +def create_iface(module, blade): + """Create Network Interface""" + + iface = [] + services = [] + iface.append(module.params['name']) + services.append(module.params['services']) + try: + blade.network_interfaces.create_network_interfaces(names=iface, + network_interface=NetworkInterface(address=module.params['address'], + services=services, + type=module.params['itype'] + ) + ) + changed = True + except: + module.fail_json(msg='Interface creation failed. Check valid subnet exists for IP address {0}'.format(module.params['address'])) + changed = False + module.exit_json(changed=changed) + + +def modify_iface(module, blade): + """Modify Network Interface IP address""" + changed = False + iface = get_iface(module, blade) + iface_new = [] + iface_new.append(module.params['name']) + if module.params['address'] != iface.address: + try: + blade.network_interfaces.update_network_interfaces(names=iface_new, + network_interface=NetworkInterface(address=module.params['address'])) + changed = True + except: + changed = False + module.exit_json(changed=changed) + + +def delete_iface(module, blade): + """ Delete Network Interface""" + iface = [] + iface.append(module.params['name']) + try: + blade.network_interfaces.delete_network_interfaces(names=iface) + changed = True + except: + changed = False + module.exit_json(changed=changed) + + +def main(): + argument_spec = purefb_argument_spec() + argument_spec.update( + dict( + name=dict(required=True), + state=dict(default='present', choices=['present', 'absent']), + address=dict(), + services=dict(default='data', choices=['data']), + itype=dict(default='vip', choices=['vip']), + ) + ) + + required_if = [["state", "present", ["address"]]] + + module = AnsibleModule(argument_spec, + required_if=required_if, + supports_check_mode=False) + + if not HAS_PURITY_FB: + module.fail_json(msg='purity_fb sdk is required for this module') + + state = module.params['state'] + blade = get_blade(module) + api_version = blade.api_version.list_versions().versions + if MINIMUM_API_VERSION not in api_version: + module.fail_json(msg='Upgrade Purity//FB to enable this module') + iface = get_iface(module, blade) + + if state == 'present' and not iface: + create_iface(module, blade) + elif state == 'present' and iface: + modify_iface(module, blade) + elif state == 'absent' and iface: + delete_iface(module, blade) + elif state == 'absent' and not iface: + module.exit_json(changed=False) + + +if __name__ == '__main__': + main()