PyStorage 0.5.1
Python Storage Disk Toolkit (EMC VNX, EMC VMAX and IBM DS8K)
License: BSD
Keywords: Python Storage Disk EMC VMX VNX IBM DS800 DS8K Toolkit

=======================================
Python Storage Disk Toolkit (PyStorage)
=======================================

.. image:: https://travis-ci.org/kairoaraujo/PyStorage.svg?branch=master
    :target: https://travis-ci.org/kairoaraujo/PyStorage

:PyStorage:   Python Storage Disk Toolkit
:Copyright:   Copyright (c) 2016  Kairo Araujo <kairo@kairo.eti.br>
:License:     BSD
:Development: https://github.com/kairoaraujo/PyStorage

.. contents::
    :local:
    :depth: 2
    :backlinks: none

Overview
========

This is a collection of storage disk partial commands.

Table of support:

+--------+----------+
| Vendor | Models   |
+========+==========+
|        |  - VMAX  |
+ EMC    +  - VNX   |
|        |          |
+--------+----------+
| IBM    | - DS8K   |
+--------+----------+



Requirements
============

* Python >=2.7


Install
=======

* Using PIP:

.. code-block:: bash

    $ pip install PyStorage

* Offline install

Download the package on https://pypi.python.org/pypi/PyStorage/

.. code-block:: bash

    $ tar xvzf PyStorage-X.Y.tar.gz
    $ cd PyStorage-X.Y
    $ python setup.py install

Using
=====

* EMC.VMAX_

* EMC.VNX_

* IBM.DS8K_


.. _EMC.VMAX:

EMC.VMAX
--------

Class EMC.VMAX() works with EMC VMAX Storage 1 and 2.

Is necessary a SYMCLI installed and working well with your environment.
For more information consult the EMC documentation.

* Importing and initializing

>>> import pystorage
>>> symcli_path = '/opt/emc/SYMCLI/bin'
>>> my_vmax = pystorage.EMC.VMAX(symcli_path)



* EMC.VMAX.list()

List all Storages Disk available.

returns array [return code, output]

>>> print my_vmax.list()[1]
                                S Y M M E T R I X
                                       Mcode    Cache      Num Phys  Num Symm
    SymmID       Attachment  Model     Version  Size (MB)  Devices   Devices
    000000000100 Local       VMAX-1    5876      114688         5     12361
    000000000101 Local       VMAX-1    5876      300800        10     16190
    000000000102 Local       VMAX20K   5876      421120        10     13957
    000000000103 Local       VMAX20K   5876      360960         5     24325
    000000000104 Local       VMAX40K   5876      368640        12      9249
    000000000105 Local       VMAX200K  5977     3014656         2      2691
    000000000106 Remote      VMAX20K   5876      360960         0      9588
    000000000107 Remote      VMAX20K   5876      240640         0     11360
    000000000108 Remote      VMAX20K   5876      120320         0      4640



* EMC.VMAX.lspools(SID)

List all Pools from specific storage SID.

returns array [return code, output]

>>> print my_vmax.lspools(108)[1]
Symmetrix ID: 000000000108
                       S Y M M E T R I X   P O O L S
---------------------------------------------------------------------------
Pool         Flags  Dev              Usable       Free       Used Full Comp
Name         PTECSL Config           Tracks     Tracks     Tracks  (%)  (%)
------------ ------ ------------ ---------- ---------- ---------- ---- ----
DEFAULT_POOL S-F-D- Unknown               0          0          0    0    0
DEFAULT_POOL S-9-D- Unknown               0          0          0    0    0
DEFAULT_POOL S-8-D- Unknown               0          0          0    0    0
DEFAULT_POOL S-A-D- Unknown               0          0          0    0    0
MYPOOLSAS01  TEFDEI RAID-5(7+1)    84095232   69400896   14694336   17    0
MYPOOLSAS02  TFFDEI RAID-5(7+1)  1215449040  791717292  423731748   34    0
MYPOOLSATA01 TSFDEI RAID-6(6+2)  1081337856  974749776  106588080    9    0
Total                            ---------- ---------- ---------- ---- ----
Tracks                           2380882128 1835867964  545014164   22    0



* EMC.VMAX.ign(SID, WWN)

Get Initial Group Name full output by the WWN.

returns array [return code, output]

>>> print my_vmax.ign('108', '10:23:45:67:89:0A:BC:DE')[1]
Symmetrix ID          : 000000000108
Initiator Group Name
--------------------
IG_LNXDBSRV001



* EMC.VMAX.get_ign(SID, WWN)

Get Initial Group Name, only the Initial Group Name.

returns array [return code, output]

>>> print my_vmax.get_ign('108', '10:23:45:67:89:0A:BC:DE')[1]
IG_LNXDBSRV001



* EMC.VMAX.mvn(SID, 'INITIAL GROUP NAME')

Get the Mask View Names with full informations using the Initiator Group Name.

returns array [return code, output]

>>> print my_vmax.get_mvn('108', 'IG_DBSERVER_LINUX')[1]
Symmetrix ID          : 000000000108
Initiator Group Name    : IG_LNXDBSRV001
Last update time        : 12:46:36 PM on Tue Dec 09,2014
Group last update time  : 12:46:36 PM on Tue Dec 09,2014
   Host Initiators
     {
       WWN  : 10234567890abcde
              [alias: 10234567890abcde/10234567890abcde]
     }
   Masking View Names
     {
       MV_LNXDBSRV001
     }
   Parent Initiator Groups
     {
       None
     }



* EMC.VMAX.get_mvn(SID, 'INITIAL GROUP NAME')

Get Mask View Name by the Initial Group Name.

returns array [return code, output]

>>> print my_vmax.get_mvn('108', 'IG_DBSERVER_LINUX')[1:]
MV_LNXDBSRV001



* EMC.VMAX.sgn(SID, 'MASK VIEW NAME')

Get the full Storage Group Name information by the Mask View Name.

returns array [return code, output]

>>> print my_vmax.sgn('168', 'MV_LNXDBSRV001')[1]
Symmetrix ID                : 000000000108
Masking View Name           : MV_LNXDBSRV001
Last update time            : 05:32:53 PM on Thu Nov 12,2015
View last update time       : 05:32:53 PM on Thu Nov 12,2015
Initiator Group Name        : IG_LNXDBSRV001
   Host Initiators
     {
       WWN  : 10234567890abcde
              [alias: 10234567890abcde/10234567890abcde]
     }
Port Group Name             : PG_LNXDBSRV001_012A
   Director Identification
     {
        Director
      Ident  Port   WWN Port Name / iSCSI Target Name
      ------ ---- -------------------------------------------------------
      01-2A   000 500001234567890a
     }
Storage Group Name          : SG_LNXDBSRV001
   Number of Storage Groups : 0
   Storage Group Names      : None
Sym                                        Host
Dev     Dir:Port  Physical Device Name     Lun   Attr  Cap(MB)
------  --------  -----------------------  ----  ----  -------
00055   09F:000   Not Visible                 1              3
00056   09F:000   Not Visible                 2              3
00057   09F:000   Not Visible                 3              3
00058   09F:000   Not Visible                 4              3
                                                       -------
Total Capacity                                              12



* EMC.VMAX.get_sgn(SID, 'MASK VIEW NAME')

Get the Storage Group Name by the Mask View Name

returns array [return code, output]

>>> print my_vmax.get_sgn('108', 'MV_LNXDBSRV001')[1]
SG_LNXDBSRV001



* EMC.VMAX.create_dev(SID, COUNT, 'LUN SIZE', 'MEMBER SIZE', 'REGULAR or META','POOL', 'STORAGE GROUP NAME' 'PREPARE or COMMIT')

Create and add LUN to Storage Group Name.

return array [return code, output]

>>> my_vmax.create_dev('168', 2, '50', '0', 'regular','MYPOOLSAS02',
'SG_LNXDBSRV001' 'prepare')
    Establishing a configuration change session...............Established.
    Processing symmetrix 000000000108
    {
      create dev count=2, size=54600 cyl, emulation=FBA, config=TDEV,
        mvs_ssid=0, binding to pool MYPOOLSAS02, sg=SG_LNXDBSRV001;
    }
    Performing Access checks..................................Allowed.
    Checking Device Reservations..............................Allowed.
    Initiating COMMIT of configuration changes................Started.
    Committing configuration changes..........................Queued.
    COMMIT requesting required resources......................Obtained.
    Step 002 of 018 steps.....................................Executing.
    Step 011 of 018 steps.....................................Executing.
    Step 016 of 019 steps.....................................Executing.
    Step 016 of 019 steps.....................................Executing.
    Local:  COMMIT............................................Done.
    Adding devices to Storage Group...........................
      New symdevs: 00D28:00D29 [TDEVs]
    Terminating the configuration change session..............Done.


.. _EMC.VNX:

EMC.VNX
-------

Class EMC.VNX() works with EMC VNX.

Is necessary a NAVISECCLI installed and working well with your environment.
For more information consult the EMC documentation.

All returns are:

If return code is 0: [return code, data]

If return code is different of 0: [return code, 'data error', 'data'

* Importing and initializing

>>> import pystorage
>>> vnx = pystorage.VNX('naviseccli', '10.0.0.1')

* EMC.VNX.pools()

List all pools informations.


>>> print vnx.pools()[1]
Pool Name:  P1SAS600K15
Pool ID:  0
Raid Type:  r_5
Percent Full Threshold:  70
Description:
Disk Type:  SAS
State:  Ready
Status:  OK(0x0)
Current Operation:  None
Current Operation State:  N/A
Current Operation Status:  N/A
Current Operation Percent Completed:  0
Raw Capacity (Blocks):  236411400960
Raw Capacity (GBs):  112729.741
User Capacity (Blocks):  188771917824
User Capacity (GBs):  90013.465
Consumed Capacity (Blocks):  187616231424
Consumed Capacity (GBs):  89462.391
Available Capacity (Blocks):  1155686400
Available Capacity (GBs):  551.074
Percent Full:  99.388
Total Subscribed Capacity (Blocks):  189324546048
Total Subscribed Capacity (GBs):  90276.979
Percent Subscribed:  100.293
Oversubscribed by (Blocks):  552628224
Oversubscribed by (GBs):  263.514
(...)
Disks:
Bus 2 Enclosure 2 Disk 10
Bus 2 Enclosure 2 Disk 12
Bus 2 Enclosure 2 Disk 14
Bus 3 Enclosure 3 Disk
LUNs:  806, 677, 198, 896, 479, 768, 620, 708, (...)
(... End of Example ...)

* EMC.VNX.pool_list()

Return array with pool names

>>> vnx.pool_list()[1]
['P1SAS600K15']


* EMC.VNX.port_list_all()

Return all data about port list from storage


>>> print vnx.port_list_all()[1]
Information about each HBA:
HBA UID:                 C0:50:76:05:17:AA:00:2C:C0:50:76:05:17:AA:00:2C
Server Name:             MYSERVER01
Server IP Address:       10.10.10.10
HBA Model Description:
HBA Vendor Description:
HBA Device Driver Name:   N/A
Information about each port of this HBA:
    SP Name:               SP A
    SP Port ID:            4
    HBA Devicename:        N/A
    Trusted:               NO
    Logged In:             YES
    Source ID:             3943170
    Defined:               YES
    Initiator Type:           3
    StorageGroup Name:     SG_MYSERVER01
.
    SP Name:               SP B
    SP Port ID:            4
    HBA Devicename:        N/A
    Trusted:               NO
    Logged In:             YES
    Source ID:             3943170
    Defined:               YES
    Initiator Type:           3
    StorageGroup Name:     SG_MYSERVER01
.
Information about each HBA:
HBA UID:                 C0:50:76:05:17:AA:00:2E:C0:50:76:05:17:AA:00:2E
Server Name:             MYSERVER02
Server IP Address:       10.10.10.11
HBA Model Description:
HBA Vendor Description:
HBA Device Driver Name:   N/A
Information about each port of this HBA:
(...end of example...)


* EMC.VNX.get_luns('POOL')

Get all LUNs IDs used in the pool sorted.

>>> print vnx.get_luns('P1SAS600K15')[1]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11' ...]


* EMC.VNX.show_lun('ID')

Get information about specific LUN ID.


>>> print vnx.show_lun('3')[1]
LOGICAL UNIT NUMBER 3
Name:  DB_LUN_3
UID:  60:06:01:60:20:A0:2D:00:36:1B:B4:88:A3:A9:E1:11
Current Owner:  SP B
Default Owner:  SP B
Allocation Owner:  SP B
User Capacity (Blocks):  943718400
User Capacity (GBs):  450.000
Consumed Capacity (Blocks):  972877824
Consumed Capacity (GBs):  463.904
Pool Name:  P1SAS600K15
Raid Type:  r_5
Offset:  0
Auto-Assign Enabled:  DISABLED
Auto-Trespass Enabled:  DISABLED
Current State:  Ready
Status:  OK(0x0)
Is Faulted:  false
Is Transitioning:  false
Current Operation:  None
Current Operation State:  N/A
Current Operation Status:  N/A
Current Operation Percent Completed:  0
Is Pool LUN:  Yes
Is Thin LUN:  No
Is Private:  No
Is Compressed:  No
Tiering Policy:  No Movement
Initial Tier:  Optimize Pool
Tier Distribution:
Performance:  100.00


* EMC.VNX.get_hostname('WWN')

Get the Hostname on storage by host WWN address.

>>> print vnx.get_hostname('C0:50:76:05:14:5F:00:30')[1]
SERVER_DB02


* EMC.VNX.get_stggroup('WWN')

Get the Storage Group Name on storage used by host WWN address.

>>> print vnx.get_stggroup('C0:50:76:05:14:5F:00:30')[1]
SG_SERVER_DB2


* EMC.VNX.show_stggroup('STORAGE GROUP NAME')

Get all informations about the specific storage group name.

>>> print vnx.show_stggroup('SG_SERVER_DB2')[1]
Storage Group Name:    SG_SERVER_DB2
Storage Group UID:     D2:F2:E2:05:89:2F:E3:11:B6:12:00:60:16:38:6D:4F
HBA/SP Pairs:
.
  HBA UID                                          SP Name     SPPort
  -------                                          -------     ------
  20:00:00:24:FF:40:1B:3F:21:00:00:24:FF:40:1B:3F   SP A         7
  20:00:00:24:FF:40:35:C1:21:00:00:24:FF:40:35:C1   SP A         7
  20:00:00:24:FF:40:1B:3F:21:00:00:24:FF:40:1B:3F   SP B         7
  20:00:00:24:FF:40:35:C1:21:00:00:24:FF:40:35:C1   SP B         7
  20:00:00:24:FF:40:1B:4F:21:00:00:24:FF:40:1B:4F   SP A         7
  20:00:00:24:FF:40:1B:4F:21:00:00:24:FF:40:1B:4F   SP B         7
  20:00:00:24:FF:40:1A:3E:21:00:00:24:FF:40:1A:3E   SP A         3
  20:00:00:24:FF:40:1A:3E:21:00:00:24:FF:40:1A:3E   SP B         3
  20:00:00:24:FF:40:35:C0:21:00:00:24:FF:40:35:C0   SP A         3
  20:00:00:24:FF:40:1B:4E:21:00:00:24:FF:40:1B:4E   SP A         3
  20:00:00:24:FF:40:35:C0:21:00:00:24:FF:40:35:C0   SP B         3
  20:00:00:24:FF:40:1B:4E:21:00:00:24:FF:40:1B:4E   SP B         3
  20:00:00:24:FF:40:1A:3F:21:00:00:24:FF:40:1A:3F   SP A         7
  20:00:00:24:FF:40:1A:3F:21:00:00:24:FF:40:1A:3F   SP B         7
.
HLU/ALU Pairs:
.
  HLU Number     ALU Number
  ----------     ----------
    0               923
    1               920
    2               925
    3               922
    4               1040
    5               1041
    6               1042
Shareable:             YES


* EMC.VNX.get_hlu_stggroup('STORAGE GROUP NAME')

Get all the HLU IDs in use on the Storage Group Name

>>> print vnx.get_hlu_stggroup('SG_SERVER_DB2')[1]
['0', '1', '2', '3', '4', '5', '6']


* EMC.VNX.create_dev('address', 'lun_size', 'pool_name', 'LUN ID', 'LUN', lun_type="NonThin")

Create LUN on specific pool

>>> vnx.create_dev('10.0.0.1', 50, 'P1SAS600K15', '103' 'DB2_LUN_103', lun_type="NonThin"):


* EMC.VNX.mapping_dev('STORAGE GROUP NAME', 'HLU ID', 'LUN ID'):

Add (Mapping) of LUN to Storage Group Name

>>> vnx.mapping_dev('SG_SERVER_DB2', '7', '103')


.. _IBM.DS8K:

IBM.DSK8K
---------

Class IBM.DS8K() works with IBM DS8000 System Storage family.

Is necessary a DSCLI installed and configured using profile files by
storage.

The profile files is usual stored on /opt/ibm/dscli/profile/

The usual name is dscli.profile_[storage name]

For more informations check:
http://www-01.ibm.com/support/knowledgecenter/#!/STUVMB/com.ibm.storage.ssic.help.doc/f2c_cliprofile_1yecd2.html

* Importing and initializing

>>> import pystorage
>>> dscli_path = '/opt/ibm/dscli'
>>> dscli_profile_path = '/opt/ibm/dscli/profile/'
>>> my_ds8k = pystorage.IBM.DS8K(dscli_path, dscli_profile_path+'dscli.profile_wxyz')

* IBM.lsextpool()

List all available pools, full output.

return [return code, output]

>>> print my_ds8k.lsextpool()[1]
Date/Time: January 21, 2016 10:34:07 AM BRST IBM DSCLI Version: 7.7.5.61 DS: IBM.2107-82BWXYZ
Name ID stgtype rankgrp status availstor (2^30B) %allocated available reserved numvols
======================================================================================
P0   P0 fb            0  below             14285         96     14285        0    2948
P1   P1 fb            1  below             11737         96     11737        0    2878
P2   P2 fb            0  below             11995         66     11995        0     341
P3   P3 fb            1  below             12123         65     12123        0     422


* IBM.lshostconnect('WWPN')

Get the list of hosts. If used with WWPN (optional) returns informations from
specified WWPN host.

>>> print my_ds8k.lshostconnect('10234567890abcde')[1]
Date/Time: January 21, 2016 10:36:55 AM BRST IBM DSCLI Version: 7.7.5.61 DS: IBM.2107-82BWXYZ
Name                 ID   WWPN             HostType  Profile            portgrp volgrpID ESSIOport
==================================================================================================
LNXDBSRV001_TESTS    03DB 10234567890ABCDE LinuxRHEL Intel - Linux RHEL       0 V334     all




* IBM.get_hostname('WWPN')

Get the hostname from host by the WWPN.

>>> print my_ds8k.get_hostname('10234567890abcde')[1]
LNXDBSRV001_TESTS



* IBM.get_id('WWPN')

Get the id from host by the WWPN.

>>> print my_ds8k.get_hostname('10234567890abcde')[1]
03DB



* IBM.get_volgrpid('WWPN')

Get the Volume Group ID from host by the WWPN.

>>> print my_ds8k.get_volgrpid('10234567890abcde')[1]
V334


* IBM.lsfbvol()

List all fixed block volumes in a storage.
Arguments can be used IBM.DS8K.lsfbvol('args')

Suggestions:

To get all volumes for a specific Volume Group use:

IBM.DS8K.lsfbvol('-volgrp VOL_GROUP_ID')

To get all  volumes with IDs that contain the specified logical subsystem
ID use:

IBM.DS8K.lsfbvol('-lss LSS_ID')

>>> print my_ds8k.lsfbvol('-lss 01')
Date/Time: January 21, 2016 11:55:35 AM BRST IBM DSCLI Version: 7.7.5.61 DS: IBM.2107-82BWXYZ
Name        ID   accstate datastate configstate deviceMTM datatype extpool cap (2^30B) cap (10^9B) cap (blocks)
===================================================================================================================
LUN_0100    0000 Online   Normal    Normal      2107-900  FB 512   P1             50.0           -    104857600
LUN_0101    0001 Online   Normal    Normal      2107-900  FB 512   P1             50.0           -    104857600
LUN_0102    0002 Online   Normal    Normal      2107-900  FB 512   P1             50.0           -    104857600
(...)



* IBM.DS8K.mkfbvol(pool, size, prefix, vol_group, address)

Create the fbvol(s) and allocate to the Volume Group.

>>> print my_ds8k.mkfbvol('P1', 50, 'LUN_', 'V334', '0100 0101 0102 0103')
FB volume 0100 successfully created.
FB volume 0101 successfully created.
FB volume 0102 successfully created.
FB volume 0103 successfully created.


* IBM.DSK8K.chvolgrp(vol_address, vol_group):

Add a volume in another volume group.

>>> my_ds8k.chvolgrp('0101-0103', 'V335')
Volume group V335 successfully modified.



Contributing
============

* Coding

1. Create your account on GitHub
2. Make a fork from GitHub (https://github.com/kairoaraujo/PyStorage)
3. Sign in on GerritHub.io (http://review.gerrithub.io) using your account from GitHub
4. Submit you review =)

* Reporting Issue or suggestions

1. Create a new issue https://github.com/kairoaraujo/PyStorage/issues

Important
=========

EMC, SYMCLI and VMAX are trademarks of EMC in the United States, other
countries, or both.

IBM and DS are trademarks of EMC in the United States, other countries, or both.