PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/purefa.py |
## # Copyright 2017 Pure Storage Inc # # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Management of Pure Storage FlashArray Installation Prerequisites -------------------------- - You will need the ``purestorage`` python package in your python installation path that is running salt. .. code-block:: bash pip install purestorage - Configure Pure Storage FlashArray authentication. Use one of the following three methods. 1) From the minion config .. code-block:: yaml pure_tags: fa: san_ip: management vip or hostname for the FlashArray api_token: A valid api token for the FlashArray being managed 2) From environment (PUREFA_IP and PUREFA_API) 3) From the pillar (PUREFA_IP and PUREFA_API) :maintainer: Simon Dodsley (simon@purestorage.com) :maturity: new :requires: purestorage :platform: all .. versionadded:: 2018.3.0 """ import os import platform from datetime import datetime from salt.exceptions import CommandExecutionError # Import 3rd party modules try: import purestorage HAS_PURESTORAGE = True except ImportError: HAS_PURESTORAGE = False __docformat__ = "restructuredtext en" VERSION = "1.0.0" USER_AGENT_BASE = "Salt" __virtualname__ = "purefa" # Default symbols to use for passwords. Avoids visually confusing characters. # ~6 bits per symbol DEFAULT_PASSWORD_SYMBOLS = ( "23456789", # Removed: 0,1 "ABCDEFGHJKLMNPQRSTUVWXYZ", # Removed: I, O "abcdefghijkmnopqrstuvwxyz", ) # Removed: l def __virtual__(): """ Determine whether or not to load this module """ if HAS_PURESTORAGE: return __virtualname__ return ( False, "purefa execution module not loaded: purestorage python library not available.", ) def _get_system(): """ Get Pure Storage FlashArray configuration 1) From the minion config pure_tags: fa: san_ip: management vip or hostname for the FlashArray api_token: A valid api token for the FlashArray being managed 2) From environment (PUREFA_IP and PUREFA_API) 3) From the pillar (PUREFA_IP and PUREFA_API) """ agent = { "base": USER_AGENT_BASE, "class": __name__, "version": VERSION, "platform": platform.platform(), } user_agent = "{base} {class}/{version} ({platform})".format(**agent) try: array = __opts__["pure_tags"]["fa"].get("san_ip") api = __opts__["pure_tags"]["fa"].get("api_token") if array and api: system = purestorage.FlashArray(array, api_token=api, user_agent=user_agent) except (KeyError, NameError, TypeError): try: san_ip = os.environ.get("PUREFA_IP") api_token = os.environ.get("PUREFA_API") system = purestorage.FlashArray( san_ip, api_token=api_token, user_agent=user_agent ) except (ValueError, KeyError, NameError): try: system = purestorage.FlashArray( __pillar__["PUREFA_IP"], api_token=__pillar__["PUREFA_API"], user_agent=user_agent, ) except (KeyError, NameError): raise CommandExecutionError( "No Pure Storage FlashArray credentials found." ) try: system.get() except Exception: # pylint: disable=broad-except raise CommandExecutionError("Pure Storage FlashArray authentication failed.") return system def _get_volume(name, array): """Private function to check volume""" try: return array.get_volume(name) except purestorage.PureError: return None def _get_snapshot(name, suffix, array): """Private function to check snapshot""" snapshot = name + "." + suffix try: for snap in array.get_volume(name, snap=True): if snap["name"] == snapshot: return snapshot except purestorage.PureError: return None def _get_deleted_volume(name, array): """Private function to check deleted volume""" try: return array.get_volume(name, pending="true") except purestorage.PureError: return None def _get_pgroup(name, array): """Private function to check protection group""" pgroup = None for temp in array.list_pgroups(): if temp["name"] == name: pgroup = temp break return pgroup def _get_deleted_pgroup(name, array): """Private function to check deleted protection group""" try: return array.get_pgroup(name, pending="true") except purestorage.PureError: return None def _get_hgroup(name, array): """Private function to check hostgroup""" hostgroup = None for temp in array.list_hgroups(): if temp["name"] == name: hostgroup = temp break return hostgroup def _get_host(name, array): """Private function to check host""" host = None for temp in array.list_hosts(): if temp["name"] == name: host = temp break return host def snap_create(name, suffix=None): """ Create a volume snapshot on a Pure Storage FlashArray. Will return False is volume selected to snap does not exist. .. versionadded:: 2018.3.0 name : string name of volume to snapshot suffix : string if specificed forces snapshot name suffix. If not specified defaults to timestamp. CLI Example: .. code-block:: bash salt '*' purefa.snap_create foo salt '*' purefa.snap_create foo suffix=bar """ array = _get_system() if suffix is None: suffix = "snap-" + str( (datetime.utcnow() - datetime(1970, 1, 1, 0, 0, 0, 0)).total_seconds() ) suffix = suffix.replace(".", "") if _get_volume(name, array) is not None: try: array.create_snapshot(name, suffix=suffix) return True except purestorage.PureError: return False else: return False def snap_delete(name, suffix=None, eradicate=False): """ Delete a volume snapshot on a Pure Storage FlashArray. Will return False if selected snapshot does not exist. .. versionadded:: 2018.3.0 name : string name of volume suffix : string name of snapshot eradicate : boolean Eradicate snapshot after deletion if True. Default is False CLI Example: .. code-block:: bash salt '*' purefa.snap_delete foo suffix=snap eradicate=True """ array = _get_system() if _get_snapshot(name, suffix, array) is not None: try: snapname = name + "." + suffix array.destroy_volume(snapname) except purestorage.PureError: return False if eradicate is True: try: array.eradicate_volume(snapname) return True except purestorage.PureError: return False else: return True else: return False def snap_eradicate(name, suffix=None): """ Eradicate a deleted volume snapshot on a Pure Storage FlashArray. Will return False if snapshot is not in a deleted state. .. versionadded:: 2018.3.0 name : string name of volume suffix : string name of snapshot CLI Example: .. code-block:: bash salt '*' purefa.snap_eradicate foo suffix=snap """ array = _get_system() if _get_snapshot(name, suffix, array) is not None: snapname = name + "." + suffix try: array.eradicate_volume(snapname) return True except purestorage.PureError: return False else: return False def volume_create(name, size=None): """ Create a volume on a Pure Storage FlashArray. Will return False if volume already exists. .. versionadded:: 2018.3.0 name : string name of volume (truncated to 63 characters) size : string if specificed capacity of volume. If not specified default to 1G. Refer to Pure Storage documentation for formatting rules. CLI Example: .. code-block:: bash salt '*' purefa.volume_create foo salt '*' purefa.volume_create foo size=10T """ if len(name) > 63: name = name[0:63] array = _get_system() if _get_volume(name, array) is None: if size is None: size = "1G" try: array.create_volume(name, size) return True except purestorage.PureError: return False else: return False def volume_delete(name, eradicate=False): """ Delete a volume on a Pure Storage FlashArray. Will return False if volume doesn't exist is already in a deleted state. .. versionadded:: 2018.3.0 name : string name of volume eradicate : boolean Eradicate volume after deletion if True. Default is False CLI Example: .. code-block:: bash salt '*' purefa.volume_delete foo eradicate=True """ array = _get_system() if _get_volume(name, array) is not None: try: array.destroy_volume(name) except purestorage.PureError: return False if eradicate is True: try: array.eradicate_volume(name) return True except purestorage.PureError: return False else: return True else: return False def volume_eradicate(name): """ Eradicate a deleted volume on a Pure Storage FlashArray. Will return False is volume is not in a deleted state. .. versionadded:: 2018.3.0 name : string name of volume CLI Example: .. code-block:: bash salt '*' purefa.volume_eradicate foo """ array = _get_system() if _get_deleted_volume(name, array) is not None: try: array.eradicate_volume(name) return True except purestorage.PureError: return False else: return False def volume_extend(name, size): """ Extend an existing volume on a Pure Storage FlashArray. Will return False if new size is less than or equal to existing size. .. versionadded:: 2018.3.0 name : string name of volume size : string New capacity of volume. Refer to Pure Storage documentation for formatting rules. CLI Example: .. code-block:: bash salt '*' purefa.volume_extend foo 10T """ array = _get_system() vol = _get_volume(name, array) if vol is not None: if __utils__["stringutils.human_to_bytes"](size) > vol["size"]: try: array.extend_volume(name, size) return True except purestorage.PureError: return False else: return False else: return False def snap_volume_create(name, target, overwrite=False): """ Create R/W volume from snapshot on a Pure Storage FlashArray. Will return False if target volume already exists and overwrite is not specified, or selected snapshot doesn't exist. .. versionadded:: 2018.3.0 name : string name of volume snapshot target : string name of clone volume overwrite : boolean overwrite clone if already exists (default: False) CLI Example: .. code-block:: bash salt '*' purefa.snap_volume_create foo.bar clone overwrite=True """ array = _get_system() source, suffix = name.split(".") if _get_snapshot(source, suffix, array) is not None: if _get_volume(target, array) is None: try: array.copy_volume(name, target) return True except purestorage.PureError: return False else: if overwrite: try: array.copy_volume(name, target, overwrite=overwrite) return True except purestorage.PureError: return False else: return False else: return False def volume_clone(name, target, overwrite=False): """ Clone an existing volume on a Pure Storage FlashArray. Will return False if source volume doesn't exist, or target volume already exists and overwrite not specified. .. versionadded:: 2018.3.0 name : string name of volume target : string name of clone volume overwrite : boolean overwrite clone if already exists (default: False) CLI Example: .. code-block:: bash salt '*' purefa.volume_clone foo bar overwrite=True """ array = _get_system() if _get_volume(name, array) is not None: if _get_volume(target, array) is None: try: array.copy_volume(name, target) return True except purestorage.PureError: return False else: if overwrite: try: array.copy_volume(name, target, overwrite=overwrite) return True except purestorage.PureError: return False else: return False else: return False def volume_attach(name, host): """ Attach a volume to a host on a Pure Storage FlashArray. Host and volume must exist or else will return False. .. versionadded:: 2018.3.0 name : string name of volume host : string name of host CLI Example: .. code-block:: bash salt '*' purefa.volume_attach foo bar """ array = _get_system() if _get_volume(name, array) is not None and _get_host(host, array) is not None: try: array.connect_host(host, name) return True except purestorage.PureError: return False else: return False def volume_detach(name, host): """ Detach a volume from a host on a Pure Storage FlashArray. Will return False if either host or volume do not exist, or if selected volume isn't already connected to the host. .. versionadded:: 2018.3.0 name : string name of volume host : string name of host CLI Example: .. code-block:: bash salt '*' purefa.volume_detach foo bar """ array = _get_system() if _get_volume(name, array) is None or _get_host(host, array) is None: return False elif _get_volume(name, array) is not None and _get_host(host, array) is not None: try: array.disconnect_host(host, name) return True except purestorage.PureError: return False def host_create(name, iqn=None, wwn=None, nqn=None): """ Add a host on a Pure Storage FlashArray. Will return False if host already exists, or the iSCSI or Fibre Channel parameters are not in a valid format. See Pure Storage FlashArray documentation. .. versionadded:: 2018.3.0 name : string name of host (truncated to 63 characters) iqn : string iSCSI IQN of host nqn : string NVMeF NQN of host .. versionadded:: 3006.0 wwn : string Fibre Channel WWN of host CLI Example: .. code-block:: bash salt '*' purefa.host_create foo iqn='<Valid iSCSI IQN>' wwn='<Valid WWN>' nqn='<Valid NQN>' """ array = _get_system() if len(name) > 63: name = name[0:63] if _get_host(name, array) is None: try: array.create_host(name) except purestorage.PureError: return False if nqn: try: array.set_host(name, addnqnlist=[nqn]) except purestorage.PureError: array.delete_host(name) return False if iqn is not None: try: array.set_host(name, addiqnlist=[iqn]) except purestorage.PureError: array.delete_host(name) return False if wwn is not None: try: array.set_host(name, addwwnlist=[wwn]) except purestorage.PureError: array.delete_host(name) return False else: return False return True def host_update(name, iqn=None, wwn=None, nqn=None): """ Update a hosts port definitions on a Pure Storage FlashArray. Will return False if new port definitions are already in use by another host, or are not in a valid format. See Pure Storage FlashArray documentation. .. versionadded:: 2018.3.0 name : string name of host nqn : string Additional NVMeF NQN of host .. versionadded:: 3006.0 iqn : string Additional iSCSI IQN of host wwn : string Additional Fibre Channel WWN of host CLI Example: .. code-block:: bash salt '*' purefa.host_update foo iqn='<Valid iSCSI IQN>' wwn='<Valid WWN>' nqn='<Valid NQN>' """ array = _get_system() if _get_host(name, array) is not None: if nqn: try: array.set_host(name, addnqnlist=[nqn]) except purestorage.PureError: return False if iqn is not None: try: array.set_host(name, addiqnlist=[iqn]) except purestorage.PureError: return False if wwn is not None: try: array.set_host(name, addwwnlist=[wwn]) except purestorage.PureError: return False return True else: return False def host_delete(name): """ Delete a host on a Pure Storage FlashArray (detaches all volumes). Will return False if the host doesn't exist. .. versionadded:: 2018.3.0 name : string name of host CLI Example: .. code-block:: bash salt '*' purefa.host_delete foo """ array = _get_system() if _get_host(name, array) is not None: for vol in array.list_host_connections(name): try: array.disconnect_host(name, vol["vol"]) except purestorage.PureError: return False try: array.delete_host(name) return True except purestorage.PureError: return False else: return False def hg_create(name, host=None, volume=None): """ Create a hostgroup on a Pure Storage FlashArray. Will return False if hostgroup already exists, or if named host or volume do not exist. .. versionadded:: 2018.3.0 name : string name of hostgroup (truncated to 63 characters) host : string name of host to add to hostgroup volume : string name of volume to add to hostgroup CLI Example: .. code-block:: bash salt '*' purefa.hg_create foo host=bar volume=vol """ array = _get_system() if len(name) > 63: name = name[0:63] if _get_hgroup(name, array) is None: try: array.create_hgroup(name) except purestorage.PureError: return False if host is not None: if _get_host(host, array): try: array.set_hgroup(name, addhostlist=[host]) except purestorage.PureError: return False else: hg_delete(name) return False if volume is not None: if _get_volume(volume, array): try: array.connect_hgroup(name, volume) except purestorage.PureError: hg_delete(name) return False else: hg_delete(name) return False return True else: return False def hg_update(name, host=None, volume=None): """ Adds entries to a hostgroup on a Pure Storage FlashArray. Will return False is hostgroup doesn't exist, or host or volume do not exist. .. versionadded:: 2018.3.0 name : string name of hostgroup host : string name of host to add to hostgroup volume : string name of volume to add to hostgroup CLI Example: .. code-block:: bash salt '*' purefa.hg_update foo host=bar volume=vol """ array = _get_system() if _get_hgroup(name, array) is not None: if host is not None: if _get_host(host, array): try: array.set_hgroup(name, addhostlist=[host]) except purestorage.PureError: return False else: return False if volume is not None: if _get_volume(volume, array): try: array.connect_hgroup(name, volume) except purestorage.PureError: return False else: return False return True else: return False def hg_delete(name): """ Delete a hostgroup on a Pure Storage FlashArray (removes all volumes and hosts). Will return False is hostgroup is already in a deleted state. .. versionadded:: 2018.3.0 name : string name of hostgroup CLI Example: .. code-block:: bash salt '*' purefa.hg_delete foo """ array = _get_system() if _get_hgroup(name, array) is not None: for vol in array.list_hgroup_connections(name): try: array.disconnect_hgroup(name, vol["vol"]) except purestorage.PureError: return False host = array.get_hgroup(name) try: array.set_hgroup(name, remhostlist=host["hosts"]) array.delete_hgroup(name) return True except purestorage.PureError: return False else: return False def hg_remove(name, volume=None, host=None): """ Remove a host and/or volume from a hostgroup on a Pure Storage FlashArray. Will return False is hostgroup does not exist, or named host or volume are not in the hostgroup. .. versionadded:: 2018.3.0 name : string name of hostgroup volume : string name of volume to remove from hostgroup host : string name of host to remove from hostgroup CLI Example: .. code-block:: bash salt '*' purefa.hg_remove foo volume=test host=bar """ array = _get_system() if _get_hgroup(name, array) is not None: if volume is not None: if _get_volume(volume, array): for temp in array.list_hgroup_connections(name): if temp["vol"] == volume: try: array.disconnect_hgroup(name, volume) return True except purestorage.PureError: return False return False else: return False if host is not None: if _get_host(host, array): temp = _get_host(host, array) if temp["hgroup"] == name: try: array.set_hgroup(name, remhostlist=[host]) return True except purestorage.PureError: return False else: return False else: return False if host is None and volume is None: return False else: return False def pg_create(name, hostgroup=None, host=None, volume=None, enabled=True): """ Create a protection group on a Pure Storage FlashArray. Will return False is the following cases: * Protection Grop already exists * Protection Group in a deleted state * More than one type is specified - protection groups are for only hostgroups, hosts or volumes * Named type for protection group does not exist .. versionadded:: 2018.3.0 name : string name of protection group hostgroup : string name of hostgroup to add to protection group host : string name of host to add to protection group volume : string name of volume to add to protection group CLI Example: .. code-block:: bash salt '*' purefa.pg_create foo [hostgroup=foo | host=bar | volume=vol] enabled=[true | false] """ array = _get_system() if hostgroup is None and host is None and volume is None: if _get_pgroup(name, array) is None: try: array.create_pgroup(name) except purestorage.PureError: return False try: array.set_pgroup(name, snap_enabled=enabled) return True except purestorage.PureError: pg_delete(name) return False else: return False elif __utils__["value.xor"](hostgroup, host, volume): if _get_pgroup(name, array) is None: try: array.create_pgroup(name) except purestorage.PureError: return False try: array.set_pgroup(name, snap_enabled=enabled) except purestorage.PureError: pg_delete(name) return False if hostgroup is not None: if _get_hgroup(hostgroup, array) is not None: try: array.set_pgroup(name, addhgrouplist=[hostgroup]) return True except purestorage.PureError: pg_delete(name) return False else: pg_delete(name) return False elif host is not None: if _get_host(host, array) is not None: try: array.set_pgroup(name, addhostlist=[host]) return True except purestorage.PureError: pg_delete(name) return False else: pg_delete(name) return False elif volume is not None: if _get_volume(volume, array) is not None: try: array.set_pgroup(name, addvollist=[volume]) return True except purestorage.PureError: pg_delete(name) return False else: pg_delete(name) return False else: return False else: return False def pg_update(name, hostgroup=None, host=None, volume=None): """ Update a protection group on a Pure Storage FlashArray. Will return False in the following cases: * Protection group does not exist * Incorrect type selected for current protection group type * Specified type does not exist .. versionadded:: 2018.3.0 name : string name of protection group hostgroup : string name of hostgroup to add to protection group host : string name of host to add to protection group volume : string name of volume to add to protection group CLI Example: .. code-block:: bash salt '*' purefa.pg_update foo [hostgroup=foo | host=bar | volume=vol] """ array = _get_system() pgroup = _get_pgroup(name, array) if pgroup is not None: if hostgroup is not None and pgroup["hgroups"] is not None: if _get_hgroup(hostgroup, array) is not None: try: array.add_hgroup(hostgroup, name) return True except purestorage.PureError: return False else: return False elif host is not None and pgroup["hosts"] is not None: if _get_host(host, array) is not None: try: array.add_host(host, name) return True except purestorage.PureError: return False else: return False elif volume is not None and pgroup["volumes"] is not None: if _get_volume(volume, array) is not None: try: array.add_volume(volume, name) return True except purestorage.PureError: return False else: return False else: if ( pgroup["hgroups"] is None and pgroup["hosts"] is None and pgroup["volumes"] is None ): if hostgroup is not None: if _get_hgroup(hostgroup, array) is not None: try: array.set_pgroup(name, addhgrouplist=[hostgroup]) return True except purestorage.PureError: return False else: return False elif host is not None: if _get_host(host, array) is not None: try: array.set_pgroup(name, addhostlist=[host]) return True except purestorage.PureError: return False else: return False elif volume is not None: if _get_volume(volume, array) is not None: try: array.set_pgroup(name, addvollist=[volume]) return True except purestorage.PureError: return False else: return False else: return False else: return False def pg_delete(name, eradicate=False): """ Delete a protecton group on a Pure Storage FlashArray. Will return False if protection group is already in a deleted state. .. versionadded:: 2018.3.0 name : string name of protection group CLI Example: .. code-block:: bash salt '*' purefa.pg_delete foo """ array = _get_system() if _get_pgroup(name, array) is not None: try: array.destroy_pgroup(name) except purestorage.PureError: return False if eradicate is True: try: array.eradicate_pgroup(name) return True except purestorage.PureError: return False else: return True else: return False def pg_eradicate(name): """ Eradicate a deleted protecton group on a Pure Storage FlashArray. Will return False if protection group is not in a deleted state. .. versionadded:: 2018.3.0 name : string name of protection group CLI Example: .. code-block:: bash salt '*' purefa.pg_eradicate foo """ array = _get_system() if _get_deleted_pgroup(name, array) is not None: try: array.eradicate_pgroup(name) return True except purestorage.PureError: return False else: return False def pg_remove(name, hostgroup=None, host=None, volume=None): """ Remove a hostgroup, host or volume from a protection group on a Pure Storage FlashArray. Will return False in the following cases: * Protection group does not exist * Specified type is not currently associated with the protection group .. versionadded:: 2018.3.0 name : string name of hostgroup hostgroup : string name of hostgroup to remove from protection group host : string name of host to remove from hostgroup volume : string name of volume to remove from hostgroup CLI Example: .. code-block:: bash salt '*' purefa.pg_remove foo [hostgroup=bar | host=test | volume=bar] """ array = _get_system() pgroup = _get_pgroup(name, array) if pgroup is not None: if hostgroup is not None and pgroup["hgroups"] is not None: if _get_hgroup(hostgroup, array) is not None: try: array.remove_hgroup(hostgroup, name) return True except purestorage.PureError: return False else: return False elif host is not None and pgroup["hosts"] is not None: if _get_host(host, array) is not None: try: array.remove_host(host, name) return True except purestorage.PureError: return False else: return False elif volume is not None and pgroup["volumes"] is not None: if _get_volume(volume, array) is not None: try: array.remove_volume(volume, name) return True except purestorage.PureError: return False else: return False else: return False else: return False