#===============================================================#
#                                                               #
# ID                                                            #
#                                                               #
#  policy.py                                                    #
#                                                               #
# Copyright (c) 2011 NetApp, Inc. All rights reserved.          #
# Specifications subject to change without notice.              #
#                                                               #
# Sample code to demonstrate how to:                            #
#        - list/delete protection policies                      #
#        - list/create/delete a new provisionoing policy        #
#                                                               #
# This Sample code is supported from DataFabric Manager 3.8     #
# onwards.                                                      #
# However few of the functionalities of the sample code may     #
# work on older versions of DataFabric Manager.                 #
#===============================================================#

import sys
sys.path.append("../../../../../../../lib/python/NetApp")
from NaServer import *

# Print usage of this script
def print_usage() :
    print ("Usage: \n")
    print ("policy.py <dfmserver> <user> <password> list {-v [<prov-name>] | -t [<prot-name>]}\n")
    print ("policy.py <dfmserver> <user> <password> destroy <prov-name>\n")
    print ("policy.py <dfmserver> <user> <password> create <prov-name> <type> <rtag>\n")
    print ("<dfmserver>        -- Name/IP Address of the DFM server\n")
    print ("<user>             -- DFM server User name\n")
    print ("<password>         -- DFM server User Password\n")
    print ("<prov-name>        -- provisioning policy name\n")
    print ("<prot-name>        -- protection policy name\n")
    print ("<type>             -- provisioning policy type, san or nas\n")
    print ("<rtag>             -- Resource tag for policy\n")
    print ("Creates policy with default options :\n")
    print ("NAS - User-quota=Group-quota=1G,Thin-prov=True, Snapshot-reserve=False\n")
    print ("SAN - Storage-Container=Volume, Thin-prov=True.\n")
    sys.exit(1)
    

# Variables declaration
args      = len(sys.argv) - 1

# check for valid number of parameters
if ( args < 4 ) :
        print_usage()

dfmserver = sys.argv[1]
dfmuser   = sys.argv[2]
dfmpw     = sys.argv[3]
command   = sys.argv[4]

# Setup DFM server connection
s = NaServer( dfmserver, 1, 0 )
s.set_style("LOGIN")
s.set_transport_type("HTTP")
s.set_server_type("DFM")
s.set_port(8088)
s.set_admin_user( dfmuser, dfmpw )

# List provisioning or protection policy
if ( command == "list" ) :
    
    if(args > 5):
        subCommand = sys.argv[5]
        pname = sys.argv[6]
    
    elif(args > 4):
        subCommand = sys.argv[5]
        pname = None
    
    else :
        subCommand = None
        pname = None

    #List provisioning policy
    if ( subCommand == "-v" ) :
        # Begin the iterator APIs
        input = NaElement("provisioning-policy-list-iter-start")
        
        if ( pname ) :
            input.child_add_string( "provisioning-policy-name-or-id", pname )
        
        out = s.invoke_elem(input)
    
        if ( out.results_status() == "failed" ) :
            print( "Error : " + out.results_reason() + "\n" )
            sys.exit(2)
        
        # Use tag and records retrieved in previous API call to initiate records retrieval
        input = NaElement("provisioning-policy-list-iter-next")
        input.child_add_string( "maximum", out.child_get_int("records") )
        input.child_add_string( "tag",     out.child_get_string("tag") )
        out = s.invoke_elem(input)

        if ( out.results_status() == "failed" ) :
            print( "Error : " + out.results_reason() + "\n" )
            sys.exit(2)
        
        print ("\nProvisioning Policies:\n")
        print ("===================================================================\n")
        pps = out.child_get("provisioning-policies")
        
        if ( pps == None ) :
            print ("Error: No Provisioning Policies!\n")
            sys.exit (2)
        
        ppInfos = pps.children_get()

        # Print details from the records retrieved iteratively
        if(ppInfos != None):
            for ppi in ppInfos :
                print ("Policy Name\t: " + ppi.child_get_string("provisioning-policy-name"))
                pType = ppi.child_get_string("provisioning-policy-type")
                print ("Policy Type\t: " + pType)
                print ("Resource Tag\t: " + ppi.child_get_string("resource-tag"))

            # If it is a NAS policy
            if ( pType == "nas" ) :
                print ("NAS container Settings:\n")
                nas = ppi.child_get("nas-container-settings")
                print ("\t\tDefault User Quota  : " + str(nas.child_get_int("default-user-quota")))
                print ("\t\tDefault Group Quota : " + str(nas.child_get_int("default-group-quota")))
                print ("\t\tSnapshot Reserve    : " + nas.child_get_string("snapshot-reserve"))
                print ("\t\tThin Provision      : " + nas.child_get_string("thin-provision"))
            elif ( pType == "san" ) :
                # If it is a SAN policy
                print ("SAN container Settings:\n")
                san = ppi.child_get("san-container-settings")
                print ("\t\tStorage Container Type\t: " + san.child_get_string("storage-container-type"))
                print ("\t\tThin Provision\t\t: " + san.child_get_string("thin-provision"))
                print ("\t\tThin Prov. Config.\t: "+ san.child_get_string("thin-provisioning-configuration"))
            
            srel = ppi.child_get("storage-reliability")
            print ("Availability Features:\n")
            print ("\t\tStorage Sub-system Failure (aggr SyncMirror): " + srel.child_get_string("sub-system-failure"))
            print ("\t\tStorage Controller Failure (active/active)  : " + srel.child_get_string("controller-failure"))
            print ("\t\tDisk Failure Protection (RAID Level)        : " + srel.child_get_string("disk-failure"))
            print ("===================================================================\n")
        
    elif ( subCommand == "-t" ) :
        # List Data Protection policies
        input = NaElement("dp-policy-list-iter-start")
        
        if (pname) :
            input.child_add_string( "dp-policy-name-or-id", pname )
        
        out = s.invoke_elem(input)
        
        if ( out.results_status() == "failed" ) :
            print( "Error : " + out.results_reason() + "\n" )
            sys.exit(2)
        
        input = NaElement("dp-policy-list-iter-next")
        input.child_add_string( "maximum", out.child_get_int("records") )
        input.child_add_string( "tag",     out.child_get_string("tag") )
        out = s.invoke_elem(input)
        
        if ( out.results_status() == "failed" ) :
            print( "Error : " + out.results_reason() + "\n" )
            sys.exit(2)
        
        print ("\nProtection Policies:\n")
        print ("===================================================================\n")
        dps = out.child_get("dp-policy-infos")
        
        if ( dps == None ) :
            print ("Error: No Provisioning Policies!\n")
            sys.exit (2)

        dpInfo = dps.children_get()
        
        if(dpInfo != None):
            for ppi in dpInfo :
                dpContent = ppi.child_get("dp-policy-content")
                print ("Policy Name\t: " + dpContent.child_get_string("name")  )
                dpCons     = dpContent.child_get("dp-policy-connections")
                dpConInfos = dpCons.children_get()
        
            if(dpConInfos != None):    
                for dpi in dpConInfos :
                    print ("-----------------------------------\n")
                    print ("Connection Type\t: " + dpi.child_get_string("type"))
                    print ("Source Node\t: " + dpi.child_get_string("from-node-name"))
                    print ("To Node\t\t: " + dpi.child_get_string("to-node-name"))
                
            print ("\n===================================================================\n")
        
        print ("\n")
        print ("===================================================================\n")
    
    else :
        print_usage()
    
elif ( command == "create" ) :
    # Create a new Provisioning Policy
    if ( args < 7 ) :
        print_usage()
    
    ppname = sys.argv[5]
    pptype = sys.argv[6]
    rtag   = sys.argv[7]
    input  = NaElement("provisioning-policy-create")
    ppi = NaElement("provisioning-policy-info")
    ppi.child_add_string( "provisioning-policy-name", ppname )
    ppi.child_add_string( "provisioning-policy-type", pptype )
    ppi.child_add_string( "resource-tag",             rtag )

    # Set default options for a NAS policy.  You can otherwise collect these 
    # details on commandline or a config file
    if ( pptype == "nas" ) :
        nas = NaElement("nas-container-settings")
        nas.child_add_string( "default-user-quota",  "1000000000" )
        nas.child_add_string( "default-group-quota", "1000000000" )
        nas.child_add_string( "thin-provision",      "true" )
        nas.child_add_string( "snapshot-reserve",    "false" )
        ppi.child_add(nas)
    
    elif ( pptype == "san" ) :
        # Set default options for a SAN policy.  You can otherwise collect 
        # these details on commandline or a config file
        san = NaElement("san-container-settings")
        san.child_add_string( "storage-container-type", "volume" )
        san.child_add_string( "thin-provision",         "true" )
        ppi.child_add(san)
    
    input.child_add(ppi)
    out = s.invoke_elem(input)
    
    if ( out.results_status() == "failed" ) :
        print( "Error : " + out.results_reason() + "\n" )
        sys.exit(2)
    
    print ("New Provisioning Policy " + ppname + " created with ID : " + out.child_get_string("provisioning-policy-id") + "\n")

elif ( command == "destroy" ) :
    if ( args < 5 ) :
        print_usage()
    
    pname = sys.argv[5]
    out = s.invoke( "provisioning-policy-destroy", "provisioning-policy-name-or-id", pname )
    
    if ( out.results_status() == "failed" ) :
        print( "Error : " + out.results_reason() + "\n" )
        sys.exit(2)
    
    print ("Provisioning Policy " + pname + " destroyed!\n")

else :
    print_usage()


