예제 #1
0
def get_volume_info():


    args = len(sys.argv) - 1
    
    if(args < 3):
        print_usage()
 
    filer = sys.argv[1]
    user = sys.argv[2]
    pw = sys.argv[3]
   
    if(args == 4):
        volume = sys.argv[4]

    s = NaServer(filer, 1, 3)
    response = s.set_style('LOGIN')
    if(response and response.results_errno() != 0 ):
        r = response.results_reason()
        print ("Unable to set authentication style " + r + "\n")
        sys.exit (2)

    s.set_admin_user(user, pw)
    response = s.set_transport_type('HTTP')
    
    if(response and response.results_errno() != 0 ):
        r = response.results_reason()
        print ("Unable to set HTTP transport " + r + "\n")
        sys.exit (2)

    if(args == 3):
        out = s.invoke("volume-list-info")

    else:
        out = s.invoke("volume-list-info", "volume", volume)

    if(out.results_status() == "failed"):
        print (out.results_reason() + "\n")
        sys.exit (2)

    volume_info = out.child_get("volumes")
    result = volume_info.children_get()

    for vol in result:
        vol_name = vol.child_get_string("name")
        print ("Volume name :" + vol_name + "\n")
        size_total = vol.child_get_int("size-total")
        print ("Total size: " + str(size_total) + " bytes \n")
        size_used = vol.child_get_int("size-used")
        print ("Used Size : " + str(size_used) + " bytes\n")
        print ("-------------------------------------------\n")
예제 #2
0
def connect_svm(in_args):

    # type and syntax checking on command line args
    obj_regexp = re.compile(
        r'^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$|^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](\.[a-zA-Z0-9\-]{2,}){0,6}$'
    )
    if (not (obj_regexp.match(in_args.svm))):
        sys.exit(
            "error: the svm parameter must be either an IP address or a hostname"
        )

    # connect to svm
    obj_svm = NaServer(in_args.svm, 1, 3)
    obj_svm.set_transport_type('HTTPS')
    if (in_args.cert is None):
        obj_svm.set_style('LOGIN')
        string_username = raw_input("login as: ")
        string_password = getpass.getpass()
        obj_svm.set_admin_user(string_username, string_password)
    else:
        result = obj_svm.set_style('CERTIFICATE')
        obj_svm.set_server_cert_verification(0)
        obj_svm.set_client_cert_and_key(in_args.cert[0], in_args.cert[1])

    # check that the api is reachable
    result = obj_svm.invoke("system-get-version")
    if (result.results_status() == "failed"):
        sys.exit("error: cannot connect to filer; " + result.results_reason())

    return obj_svm
예제 #3
0
def list_lifs_from_locked_node(cluster, problem_node, problem_vserver, username, password):
    s = NaServer(cluster, 1 , 110)
    s.set_server_type("FILER")
    s.set_transport_type("HTTPS")
    s.set_port(443)
    s.set_style("LOGIN")
    s.set_admin_user(username, password)

    # Set tag to null in order to use the iter-api properly
    tag = "";
    interfaces = []
    while tag != None:
        if not tag:
            result = s.invoke('net-interface-get-iter', 'max-records', 1)
        else:
            result = s.invoke('net-interface-get-iter', 'tag', tag, 'max-records', 1)

        if result.results_status() == "failed":
            reason = result.results_reason()
            print(reason + "\n")
            return
            #sys.exit(2)

        if result.child_get_int('num-records') == 0:
            # print("Migrating interfaces")
            # for i in interfaces:
            #     print(i['name'])
            #sys.exit(0)
            return interfaces

        tag = result.child_get_string('next-tag')

        for interface in result.child_get('attributes-list').children_get():
            name = interface.child_get_string('interface-name')
            vserver = interface.child_get_string('vserver')
            home_port = interface.child_get_string('home-port')
            home_node = interface.child_get_string('home-node')
            if vserver == problem_vserver and home_node == problem_node:
                interfaces.append({'name':name, 'vserver': vserver, 'home_port':home_port, 'home_node':home_node})
예제 #4
0
def get_quota_info():
    s = NaServer(filer, 1, 3)
    response = s.set_style('LOGIN')

    if (response and response.results_errno() != 0):
        r = response.results_reason()
        print("Unable to set authentication style " + r + "\n")
        sys.exit(2)

    s.set_admin_user(user, pw)
    response = s.set_transport_type('HTTP')

    if (response and response.results_errno() != 0):
        r = response.results_reason()
        print("Unable to set transport type " + r + "\n")
        sys.exit(2)

    out = s.invoke("quota-list-entries")

    if (out.results_status() == "failed"):
        print(out.results_reason() + "\n")
        sys.exit(2)

    quota_info = out.child_get("quota-entries")
    result = quota_info.children_get()
    print("-----------------------------------------------------\n")

    for quota in result:
        if (quota.child_get_string("quota-target")):
            quota_target = quota.child_get_string("quota-target")
            print("Quota Target: " + quota_target + " \n")

        if (quota.child_get_string("volume")):
            volume = quota.child_get_string("volume")
            print("Volume: " + volume + "\n")

        if (quota.child_get_string("quota-type")):
            quota_type = quota.child_get_string("quota-type")
            print("Quota Type: " + quota_type + "\n")

        print("-----------------------------------------------------\n")
def get_volume_info():
    s = NaServer(filer, 1, 3)
    response = s.set_style('LOGIN')

    if (response and response.results_errno() != 0):
        r = response.results_reason()
        print("Unable to set authentication style " + r + "\n")
        sys.exit(2)

    s.set_admin_user(user, pw)
    response = s.set_transport_type('HTTP')

    if (response and response.results_errno() != 0):
        r = response.results_reason()
        print("Unable to set HTTP transport" + r + "\n")
        sys.exit(2)

    for volume in volumes:
        out = s.invoke("volume-list-info", "volume", volume)

        if (out.results_status() == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

        volume_info = out.child_get("volumes")
        result = volume_info.children_get()

        global total_volume_size
        global used_volume_size
        global percent_space_avail

        for vol in result:
            total_volume_size = vol.child_get_int("size-total")
            used_volume_size = vol.child_get_int("size-used")
            space_avail = (total_volume_size - used_volume_size)
            percent_space_avail = (float(space_avail) /
                                   float(total_volume_size)) * 100

            if (percent_space_avail < threshold):
                send_mail(volume)
예제 #6
0
def create():
    args = len(sys.argv) - 1

    if (args < 3):
        print_usage()

    filer = sys.argv[1]
    user = sys.argv[2]
    password = sys.argv[3]

    aggr_name = "cinder_aggr"
    vol_name = "cinder"

    s = NaServer(filer, 1, 1)
    s.set_server_type("Filer")
    s.set_admin_user(user, password)
    s.set_transport_type("HTTP")

    # Get the sysid of "this" controller
    system = s.invoke("system-get-info")
    sysinfo = system.child_get("system-info")
    sysid = sysinfo.child_get_string("system-id")

    # get the disks that this controller owns
    output = s.invoke("disk-sanown-list-info")

    if (output.results_errno() != 0):
        r = output.results_reason()
        print("Failed: \n" + str(r))

    else:
        disks = output.child_get("disk-sanown-details")
        result = disks.children_get()

        disk_list = []
        for disk in result:
            disk_name = disk.child_get_string("name")
            owner = disk.child_get_string("owner-id")
            if owner == sysid:
                disk_list.append(disk_name)

    aggr_disks = []

    # Make sure the disks aren't already assigned to an aggr
    for i in disk_list:
        print "Checking details for disk %s" % i
        time.sleep(0.4)
        diskinfo = s.invoke("disk-list-info", "disk", i)
        details = diskinfo.child_get("disk-details")
        check_list = details.children_get()

        for j in check_list:
            disk_name = j.child_get_string("name")
            aggr = j.child_get_string("aggregate")
            if aggr is None:
                aggr_disks.append(disk_name)

    #Subtract some spares
    aggr_disk_list = len(aggr_disks) - 2

    # Create an aggr using n - 2 available disks
    output = s.invoke("aggr-create", "aggregate", aggr_name, "disk-count",
                      aggr_disk_list)
    if (output.results_errno() != 0):
        r = output.results_reason()
        print("Failed: \n" + str(r))
    else:
        print "Success"

    # Get maximum space
    vol_size = ""

    output = s.invoke("aggr-space-list-info", "aggregate", aggr_name)
    if (output.results_errno() != 0):
        print("Failed: " + str(output.results_reason()))
    else:
        info = output.child_get("aggr-space-info")
        vol_size = info.child_get_int("size-nominal")
예제 #7
0

args = len(sys.argv) - 1

if (args < 3):
    print_usage()

filer = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]

s = NaServer(filer, 1, 1)
s.set_server_type("Filer")
s.set_admin_user(user, password)
s.set_transport_type("HTTP")
output = s.invoke("aggr-space-list-info")


def sizeof_fmt(num):
    for x in ['bytes', 'KB', 'MB', 'GB']:
        if num < 1024.0 and num > -1024.0:
            return "%3.1f%s" % (num, x)
        num /= 1024.0
    return "%3.1f%s" % (num, 'TB')


if (output.results_errno() != 0):
    r = output.results_reason()
    print("Failed: \n" + str(r))

else:
예제 #8
0
class Netapp(SnapHandler):
    _exceptionbase = "netapp"
    _blocksize = 1024
    _filer = None

    def __init__(self, configname):
        zfscredfilename = os.path.join(scriptpath(), 'netappcredentials.cfg')
        if not os.path.isfile(zfscredfilename):
            raise Exception(
                self._exceptionbase,
                "Configuration file %s not found" % zfscredfilename)
        # Authentication information
        zfscredconfig = SafeConfigParser()
        zfscredconfig.read(zfscredfilename)
        zfsauth = (zfscredconfig.get('netappcredentials', 'user'),
                   zfscredconfig.get('netappcredentials', 'password'))
        #
        self._filer = Configuration.get('filer', 'netapp')
        self._srv = NaServer(self._filer, 1, 1)
        self._srv.set_admin_user(
            zfscredconfig.get('netappcredentials', 'user'),
            zfscredconfig.get('netappcredentials', 'password'))
        self._volprefix = Configuration.get('volumeprefix', 'netapp')
        self._volname = "%s%s" % (self._volprefix, configname)
        super(Netapp, self).__init__(configname)

    def _check_netapp_error(self, output, errmsg):
        if output.results_errno() != 0:
            raise Exception(self._exceptionbase,
                            "%s. %s" % (errmsg, output.results_reason()))

    # Public interfaces
    def filesystem_info(self, filesystemname=None):
        info = {}
        output = self._srv.invoke("volume-clone-get", "volume", filesystemname)
        self._check_netapp_error(output, "Getting clone info failed")
        attrlist = output.child_get("attributes")
        if (attrlist is None or attrlist == ""):
            raise Exception(self._exceptionbase,
                            "No attributes found for clone.")
        for ss in attrlist.children_get():
            info['origin'] = ss.child_get_string('parent-volume')
            info['clonename'] = filesystemname
            info['mountpoint'] = ss.child_get_string('junction-path')
        return info

    def listclones(self):
        elem = NaElement("volume-clone-get-iter")
        elem.child_add_string("max-records", "50")
        query = NaElement("query")
        query.child_add_string("parent-volume", self._volname)
        elem.child_add(query)
        #
        output = self._srv.invoke_elem(elem)
        self._check_netapp_error(output, "List clones failed")
        attrlist = output.child_get("attributes-list")
        if (attrlist is not None and attrlist):
            for ss in attrlist.children_get():
                info = {}
                info['origin'] = ss.child_get_string('parent-volume')
                info['clonename'] = ss.child_get_string('volume')
                info['mountpoint'] = ss.child_get_string('junction-path')
                yield info

    def mountstring(self, filesystemname):
        info = self.filesystem_info(filesystemname)
        return "%s:%s" % (self._filer, info['mountpoint'])

    def snap(self):
        snapname = "%s_%s" % (self._volname,
                              datetime.now().strftime('%Y%m%dT%H%M%S'))
        output = self._srv.invoke("snapshot-create", "volume", self._volname,
                                  "snapshot", snapname)
        self._check_netapp_error(output, "Creating snapshot failed")
        return snapname

    def dropsnap(self, snapid):
        output = self._srv.invoke("snapshot-delete", "volume", self._volname,
                                  "snapshot", snapid)
        self._check_netapp_error(output, "Failed to drop snapshot %s" % snapid)

    def getsnapinfo(self, snapstruct):
        return snapstruct

    def listsnapshots(self, sortbycreation=False, sortreverse=False):
        output = self._srv.invoke("snapshot-list-info", "volume",
                                  self._volname)
        self._check_netapp_error(output, "Failed to list snapshots")
        snapshotlist = output.child_get("snapshots")
        snapshots = []
        if (snapshotlist is not None and snapshotlist):
            for ss in snapshotlist.children_get():
                snapshots.append({
                    'id':
                    ss.child_get_string("name"),
                    'creation':
                    datetime.utcfromtimestamp(
                        float(ss.child_get_int("access-time"))),
                    'numclones':
                    1 if ss.child_get_string("busy") == "true" else 0,
                    'space_total':
                    ss.child_get_int("cumulative-total") * self._blocksize,
                    'space_unique':
                    ss.child_get_int("total") * self._blocksize
                })
        if not sortbycreation:
            return snapshots
        else:
            return sorted(snapshots,
                          key=operator.itemgetter('creation'),
                          reverse=sortreverse)

    def clone(self, snapid, clonename):
        output = self._srv.invoke("volume-clone-create", "parent-volume",
                                  self._volname, "parent-snapshot", snapid,
                                  "volume", clonename)
        self._check_netapp_error(output, "Creating clone failed")
        output = self._srv.invoke("volume-mount", "junction-path",
                                  "/%s" % clonename, "volume-name", clonename)
        self._check_netapp_error(output, "Mounting clone failed")
        output = self._srv.invoke("volume-set-option", "option-name",
                                  "nosnapdir", "option-value", "on", "volume",
                                  clonename)
        self._check_netapp_error(output, "Setting attribute on clone failed")

    def dropclone(self, cloneid):
        info = self.filesystem_info(cloneid)
        if info['origin'] != self._volname:
            raise Exception(
                self._exceptionbase,
                "This clone does not belong to parent %s" % self._volname)
        output = self._srv.invoke("volume-unmount", "volume-name", cloneid)
        self._check_netapp_error(output,
                                 "Unmounting volume %s failed" % cloneid)
        output = self._srv.invoke("volume-offline", "name", cloneid)
        self._check_netapp_error(output,
                                 "Offlining volume %s failed" % cloneid)
        output = self._srv.invoke("volume-destroy", "name", cloneid)
        self._check_netapp_error(output, "Dropping volume %s failed" % cloneid)
def print_usage():
    print("Usage: system_mode.py <storage-system> <user> <password> \n")
    print("<storage-system> -- Storage System name\n")
    print("<user> -- User name\n")
    print("<password> -- Password\n")
    sys.exit(1)


args = len(sys.argv) - 1
if (args < 3):
    print_usage()

storage = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]

s = NaServer(storage, 1, 0)
s.set_admin_user(user, password)
output = s.invoke("system-get-version")

if (output.results_errno() != 0):
    r = output.results_reason()
    print("Failed: \n" + str(r))
else:
    clustered = output.child_get_string("is-clustered")
    if (clustered == "true"):
        print("The Storage System " + storage + " is in \"Cluster Mode\"\n")
    else:
        print("The Storage System " + storage + " is in \"7 Mode\"\n")
예제 #10
0

args = len(sys.argv) - 1

if (args < 3):
    print_usage()

filer = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]

s = NaServer(filer, 1, 1)
s.set_server_type("Filer")
s.set_admin_user(user, password)
s.set_transport_type("HTTP")
output = s.invoke("volume-list-info")


def sizeof_fmt(num):
    for x in ['bytes', 'KB', 'MB', 'GB']:
        if num < 1024.0 and num > -1024.0:
            return "%3.1f%s" % (num, x)
        num /= 1024.0
    return "%3.1f%s" % (num, 'TB')


if (output.results_errno() != 0):
    r = output.results_reason()
    print("Failed: \n" + str(r))

else:
예제 #11
0
def do_nfs():
    s = NaServer(filer, 1, 3)
    out = s.set_transport_type('HTTP')

    if (out and (out.results_errno() != 0)):
        r = out.results_reason()
        print("Connection to filer failed" + r + "\n")
        sys.exit(2)

    out = s.set_style('LOGIN')

    if (out and (out.results_errno() != 0)):

        r = out.results_reason()
        print("Connection to filer failed" + r + "\n")
        sys.exit(2)

    out = s.set_admin_user(user, pw)

    if (cmd == "enable"):
        out = s.invoke("nfs-enable")

        if (out.results_status() == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

        else:
            print("Operation successful\n")

    elif (cmd == "disable"):
        out = s.invoke("nfs=disable")

        if (out.results_status == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

        else:
            print("Operation successful\n")

    elif (cmd == "status"):
        out = s.invoke("nfs-status")

        if (out.results_status == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

        enabled = out.child_get_string("is-enabled")

        if (enabled == "true"):
            print("NFS Server is enabled\n")

        else:
            print("NFS Server is disabled\n")

    elif (cmd == "list"):
        out = s.invoke("nfs-exportfs-list-rules")
        export_info = out.child_get("rules")

        if (export_info):
            result = export_info.children_get()

        else:
            sys.exit(2)

        for export in result:
            path_name = export.child_get_string("pathname")
            rw_list = "rw="
            ro_list = "ro="
            root_list = "root="
            if (export.child_get("read-only")):
                ro_results = export.child_get("read-only")
                ro_hosts = ro_results.children_get()
                for ro in ro_hosts:

                    if (ro.child_get_string("all-hosts")):
                        all_hosts = ro.child_get_string("all-hosts")

                        if (all_hosts == "true"):
                            ro_list = ro_list + "all-hosts"
                            break

                    elif (ro.child_get_string("name")):
                        host_name = ro.child_get_string("name")
                        ro_list = ro_list + host_name + ":"

            if (export.child_get("read-write")):
                rw_results = export.child_get("read-write")
                rw_hosts = rw_results.children_get()
                for rw in rw_hosts:

                    if (rw.child_get_string("all-hosts")):
                        all_hosts = rw.child_get_string("all-hosts")

                        if (all_hosts == "true"):
                            rw_list = rw_list + "all-hosts"
                            break

                    elif (rw.child_get_string("name")):
                        host_name = rw.child_get_string("name")
                        rw_list = rw_list + host_name + ":"

            if (export.child_get("root")):
                root_results = export.child_get("root")
                root_hosts = root_results.children_get()

                for root in root_hosts:

                    if (root.child_get_string("all-hosts")):
                        all_hosts = root.child_get_string("all-hosts")

                        if (all_hosts == "true"):
                            root_list = root_list + "all-hosts"
                            break

                    elif (root.child_get_string("name")):
                        host_name = root.child_get_string("name")
                        root_list = root_list + host_name + ":"

            path_name = path_name + "  "

            if (ro_list != "ro="):
                path_name = path_name + ro_list

            if (rw_list != "rw="):
                path_name = path_name + "," + rw_list

            if (root_list != "root="):
                path_name = path_name + "," + root_list

            print(path_name + "\n")

    else:
        print("Invalid operation\n")
        print_usage()
예제 #12
0
class Netapp(SnapHandler):
    _exceptionbase = "netapp"
    _blocksize = 1024
    _filer = None
    _cacert = None

    def __init__(self, configname):
        zfscredfilename = os.path.join(scriptpath(), 'netappcredentials.cfg')
        if not os.path.isfile(zfscredfilename):
            raise Exception(
                self._exceptionbase,
                "Configuration file %s not found" % zfscredfilename)
        # Authentication information
        zfscredconfig = SafeConfigParser()
        zfscredconfig.read(zfscredfilename)
        zfsauth = (zfscredconfig.get('netappcredentials', 'user'),
                   zfscredconfig.get('netappcredentials', 'password'))
        #
        self._filer = Configuration.get('filer', 'netapp')
        self._srv = NaServer(self._filer, 1, 1)
        # Check if CA certificate validation is needed
        try:
            self._cacert = os.path.join(scriptpath(), 'certs',
                                        Configuration.get('cacert', 'netapp'))
        except NoOptionError:
            self._cacert = None
        if self._cacert:
            self._srv.set_ca_certs(self._cacert)
            self._srv.set_server_cert_verification(True)
            self._srv.set_hostname_verification(False)
        #
        self._srv.set_admin_user(
            zfscredconfig.get('netappcredentials', 'user'),
            zfscredconfig.get('netappcredentials', 'password'))
        self._volprefix = Configuration.get('volumeprefix', 'netapp')
        self._volname = "%s%s" % (self._volprefix, configname)
        super(Netapp, self).__init__(configname)

    def _check_netapp_error(self, output, errmsg):
        if output.results_errno() != 0:
            raise Exception(self._exceptionbase,
                            "%s. %s" % (errmsg, output.results_reason()))

    def _volsize_to_num(self, volsize):
        unit = volsize[-1].lower()
        factor = 1
        if unit == "m":
            factor = 20
        elif unit == "g":
            factor = 30
        elif unit == "t":
            factor = 40
        elif unit == "p":
            factor = 50
        return round(float(volsize[:-1]) * (2**factor))

    # Public interfaces
    def filesystem_info(self, filesystemname=None):
        info = {}
        output = self._srv.invoke("volume-clone-get", "volume", filesystemname)
        self._check_netapp_error(output, "Getting clone info failed")
        attrlist = output.child_get("attributes")
        if (attrlist is None or attrlist == ""):
            raise Exception(self._exceptionbase,
                            "No attributes found for clone.")
        for ss in attrlist.children_get():
            info['origin'] = ss.child_get_string('parent-volume')
            info['clonename'] = filesystemname
            info['mountpoint'] = ss.child_get_string('junction-path')
        return info

    def listclones(self):
        elem = NaElement("volume-clone-get-iter")
        elem.child_add_string("max-records", "50")
        query = NaElement("query")
        query.child_add_string("parent-volume", self._volname)
        elem.child_add(query)
        #
        output = self._srv.invoke_elem(elem)
        self._check_netapp_error(output, "List clones failed")
        attrlist = output.child_get("attributes-list")
        if (attrlist is not None and attrlist):
            for ss in attrlist.children_get():
                info = {}
                info['origin'] = ss.child_get_string('parent-volume')
                info['clonename'] = ss.child_get_string('volume')
                info['mountpoint'] = ss.child_get_string('junction-path')
                yield info

    def mountstring(self, filesystemname):
        info = self.filesystem_info(filesystemname)
        return "%s:%s" % (self._filer, info['mountpoint'])

    def snap(self):
        snapname = "%s_%s" % (self._volname,
                              datetime.now().strftime('%Y%m%dT%H%M%S'))
        output = self._srv.invoke("snapshot-create", "volume", self._volname,
                                  "snapshot", snapname)
        self._check_netapp_error(output, "Creating snapshot failed")
        return snapname

    def dropsnap(self, snapid):
        output = self._srv.invoke("snapshot-delete", "volume", self._volname,
                                  "snapshot", snapid)
        self._check_netapp_error(output, "Failed to drop snapshot %s" % snapid)

    def getsnapinfo(self, snapstruct):
        return snapstruct

    def listsnapshots(self, sortbycreation=False, sortreverse=False):
        output = self._srv.invoke("volume-size", "volume", self._volname)
        self._check_netapp_error(output,
                                 "Failed to get volume size information")
        volsize = self._volsize_to_num(output.child_get_string("volume-size"))
        pct_limit = round(2147483648 * 100 / (volsize / self._blocksize))
        output = self._srv.invoke("snapshot-list-info", "volume",
                                  self._volname)
        self._check_netapp_error(output, "Failed to list snapshots")
        snapshotlist = output.child_get("snapshots")
        snapshots = []
        if (snapshotlist is not None and snapshotlist):
            for ss in snapshotlist.children_get():
                snapshots.append({
                    'id':
                    ss.child_get_string("name"),
                    'creation':
                    datetime.utcfromtimestamp(
                        float(ss.child_get_int("access-time"))),
                    'numclones':
                    1 if ss.child_get_string("busy") == "true" else 0,
                    'space_total':
                    ss.child_get_int("cumulative-total") * self._blocksize if
                    ss.child_get_int("cumulative-percentage-of-total-blocks") <
                    pct_limit else round(volsize * ss.child_get_int(
                        "cumulative-percentage-of-total-blocks") / 100),
                    'space_unique':
                    ss.child_get_int("total") * self._blocksize if
                    ss.child_get_int("percentage-of-total-blocks") < pct_limit
                    else round(volsize *
                               ss.child_get_int("percentage-of-total-blocks") /
                               100)
                })
        if not sortbycreation:
            return snapshots
        else:
            return sorted(snapshots,
                          key=operator.itemgetter('creation'),
                          reverse=sortreverse)

    def clone(self, snapid, clonename):
        output = self._srv.invoke("volume-clone-create", "parent-volume",
                                  self._volname, "parent-snapshot", snapid,
                                  "volume", clonename)
        self._check_netapp_error(output, "Creating clone failed")
        output = self._srv.invoke("volume-mount", "junction-path",
                                  "/%s" % clonename, "volume-name", clonename)
        self._check_netapp_error(output, "Mounting clone failed")
        output = self._srv.invoke("volume-set-option", "option-name",
                                  "nosnapdir", "option-value", "on", "volume",
                                  clonename)
        self._check_netapp_error(output, "Setting attribute on clone failed")

    def dropclone(self, cloneid):
        info = self.filesystem_info(cloneid)
        if info['origin'] != self._volname:
            raise Exception(
                self._exceptionbase,
                "This clone does not belong to parent %s" % self._volname)
        output = self._srv.invoke("volume-unmount", "volume-name", cloneid)
        self._check_netapp_error(output,
                                 "Unmounting volume %s failed" % cloneid)
        output = self._srv.invoke("volume-offline", "name", cloneid)
        self._check_netapp_error(output,
                                 "Offlining volume %s failed" % cloneid)
        output = self._srv.invoke("volume-destroy", "name", cloneid)
        self._check_netapp_error(output, "Dropping volume %s failed" % cloneid)

    def createvolume(self):
        uid = os.getuid()
        gid = os.getgid()
        permissions = "0770"
        #
        ui = UIElement()
        aggregate = ui.ask_string("Aggregate name:", 50)
        volume_size = ui.ask_size("Volume size:")
        path = ui.ask_string("Parent namespace:", 50)
        export_policy = ui.ask_string("Export policy:", 50)
        #
        output = self._srv.invoke(
            "volume-create", "volume", self._volname, "containing-aggr-name",
            aggregate, "efficiency-policy", "default",
            "export-policy", export_policy, "group-id", gid, "user-id",
            os.getuid(), "unix-permissions", permissions, "junction-path",
            os.path.join(path, self.configname), "percentage-snapshot-reserve",
            0, "size", volume_size, "volume-state", "online")
        self._check_netapp_error(output, "Creating volume failed")
        #
        rootelem = NaElement("volume-modify-iter")
        attrelem1 = NaElement("attributes")
        attrelem = NaElement("volume-attributes")
        attrelem1.child_add(attrelem)
        queryelem1 = NaElement("query")
        queryelem = NaElement("volume-attributes")
        queryelem1.child_add(queryelem)
        volid = NaElement("volume-id-attributes")
        volid.child_add_string("name", self._volname)
        queryelem.child_add(volid)
        snapattr = NaElement("volume-snapshot-attributes")
        snapattr.child_add_string("auto-snapshots-enabled", "false")
        snapattr.child_add_string("snapdir-access-enabled", "false")
        autosizeattr = NaElement("volume-autosize-attributes")
        autosizeattr.child_add_string("mode", "grow")
        attrelem.child_add(snapattr)
        attrelem.child_add(autosizeattr)
        rootelem.child_add(attrelem1)
        rootelem.child_add(queryelem1)
        rootelem.child_add_string("max-records", "1")
        output = self._srv.invoke_elem(rootelem)
        self._check_netapp_error(output, "Setting volume options failed.")
        print "Volume created. Please disable automatic snapshot creation through GUI, for some reason it does not work through API."
예제 #13
0
#####
##### netapp api calls
#####

# connect to filer
obj_svm = NaServer(ns_args.svm, 1, 3)
result = obj_svm.set_transport_type('HTTPS')
if (result and (result.results_errno() != 0)):
    sys.exit("error: connection to svm failed; " + result.results_reason())
result = obj_svm.set_style('LOGIN')
if (result and (result.results_errno() != 0)):
    sys.exit("error: connection to svm failed; " + result.results_reason())
result = obj_svm.set_admin_user(ns_args.username, getpass.getpass())

# check that the api is reachable
result = obj_svm.invoke("system-get-version")
if (result.results_status() == "failed"):
    sys.exit("error: cannot execute api; " + result.results_reason())

# check that nfs service is enabled
result = obj_svm.invoke("nfs-status")
if (result.results_status() == "failed"):
    sys.exit("error: cannot execute api; " + result.results_reason())

# enable nfs service
if (result.child_get_string("is-enabled") == "false"):
    obj_nfs_service_create = NaElement("nfs-service-create")
    obj_nfs_service_create.child_add_string("is-nfsv3-enabled", "false")
    obj_nfs_service_create.child_add_string("is-nfsv40-enabled", "true")
    obj_nfs_service_create.child_add_string("is-nfsv40-acl-enabled", "true")
    obj_nfs_service_create.child_add_string("is-nfsv41-enabled", "true")
예제 #14
0
if (args < 5):
    print_usage()

opt = sys.argv[1]
filer = sys.argv[2]
user = sys.argv[3]
pw = sys.argv[4]
vol = sys.argv[5]
s = NaServer(filer, 1, 1)
s.set_admin_user(user, pw)

#
# snapshot-get-schedule
#
if (opt == "-g"):
    output = s.invoke("snapshot-get-schedule", "volume", vol)

    if (output.results_errno() != 0):
        r = output.results_reason()
        print("snapshot-get-schedule failed:" + r + "\n")

    minutes = output.child_get_int("minutes")
    hours = output.child_get_int("hours")
    days = output.child_get_int("days")
    weeks = output.child_get_int("weeks")
    whichhours = output.child_get_string("which-hours")
    whichminutes = output.child_get_string("which-minutes")
    print("\n")
    print("Snapshot schedule for volume " + vol + " on filer " + filer +
          "\n\n")
예제 #15
0
        else:
            user = raw_input("User: "******"":
        password = getpass.getpass("Password: "******"vserver-type")
        if vs_type == "data":
            svm_list.append(vs.child_get_string('vserver-name'))
예제 #16
0
s.set_server_type("Filer")
s.set_admin_user(user, password)
s.set_transport_type("HTTP")
#ss = s.invoke("aggr-list-info","aggregate","aggr1")
''''
#获取aggr信息
aggr = s.invoke("aggr-list-info")
aggregates = aggr.child_get("aggregates")
result = aggregates.children_get() #返回一个列表
for aggregate in result:
  print ("home-name: " + aggregate.child_get_string("home-name") + "\n")
  print ("name: " + aggregate.child_get_string("name") + "\n")
  print ("disk-count: " + aggregate.child_get_string("disk-count") + "\n")
    
'''
vol_cre = s.invoke("volume-create", "volume", "vol2", "containing-aggr-name",
                   "aggr0", "size", "5g")
vol = s.invoke("volume-list-info")
volumes = vol.child_get("volumes")
vol_list = volumes.children_get()
for vol_single in vol_list:
    print("name: " + vol_single.child_get_string("name") + "\n")
    print("size-total: " + vol_single.child_get_string("size-total") + "\n")

#output = s.invoke("system-get-version")  #获取系统版本信息
"""
if(output.results_errno() != 0):
   r = output.results_reason()
   print("Failed: \n" + str(r))

else :
   #r = output
def main():
    s = NaServer(filer, 1, 3)
    resp = s.set_style('LOGIN')

    if (resp and resp.results_errno() != 0):
        r = resp.results_reason()
        print("Failed to set authentication style " + r + "\n")
        sys.exit(2)

    s.set_admin_user(user, pw)
    resp = s.set_transport_type('HTTP')

    if (resp and resp.results_errno() != 0):
        r = resp.results_reason()
        print("Unable to set HTTP transport " + r + "\n")
        sys.exit(2)

    if (command == "create"):
        vfiler_create(s)

    elif (command == "list"):
        vfiler_list(s)

    if (args < 5 and (command == "start" or command == "stop"
                      or command == "status" or command == "destroy")):
        print("This operation requires <vfiler-name> \n\n")
        print_usage()

    if (command == "start"):
        out = s.invoke("vfiler-start", "vfiler", vfiler)

        if (out.results_status() == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

    elif (command == "status"):
        out = s.invoke("vfiler-get-status", "vfiler", vfiler)

        if (out.results_status() == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

        status = out.child_get_string("status")
        print("status:" + status + "\n")

    elif (command == "stop"):
        out = s.invoke("vfiler-stop", "vfiler", vfiler)

        if (out.results_status() == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

    elif (command == "destroy"):
        out = s.invoke("vfiler-destroy", "vfiler", vfiler)

        if (out.results_status() == "failed"):
            print(out.results_reason() + "\n")
            sys.exit(2)

    else:
        print("Invalid operation\n")
        print_usage()
    print("Usage: hello_dfm.py <dfmserver> <dfmuser> <dfmpassword> \n")
    print("<dfmserver> -- Name/IP Address of the DFM server \n")
    print("<dfmuser> -- DFM server User name\n")
    print("<dfmpassword> -- DFM server Password\n")
    sys.exit(1)


args = len(sys.argv) - 1

if (args != 3):
    print_usage()

dfmserver = sys.argv[1]
dfmuser = sys.argv[2]
dfmpw = sys.argv[3]
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)
output = s.invoke("dfm-about")

if (output.results_errno() != 0):
    r = output.results_reason()
    print("Failed " + str(r) + "\n")

else:
    r = output.child_get_string("version")
    print("Hello World ! DFM Server version is: " + r + "\n")
예제 #19
0
    print_usage()

filer = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]

aggr_name = "cinder_aggr"
vol_name = "cinder"

s = NaServer(filer, 1, 1)
s.set_server_type("Filer")
s.set_admin_user(user, password)
s.set_transport_type("HTTP")

# Get the sysid of "this" controller
system = s.invoke("system-get-info")
sysinfo = system.child_get("system-info")
sysid = sysinfo.child_get_string("system-id")

# get the disks that this controller owns
output = s.invoke("disk-sanown-list-info")

if (output.results_errno() != 0):
    r = output.results_reason()
    print("Failed: \n" + str(r))

else:
    disks = output.child_get("disk-sanown-details")
    result = disks.children_get()

    disk_list = []
def ntap_get_svm_list(host, protocol, config):
    addr = ""
    hostname = {}
    host_lookup = ()
    share_list = {}
    host_list = {}

    # Set up NetApp API session
    try:
        _create_unverified_https_context = ssl._create_unverified_context
    except AttributeError:
        pass
    else:
        ssl._create_default_https_context = _create_unverified_https_context
    netapp = NaServer(host, 1, 130)
    out = netapp.set_transport_type('HTTPS')
    ntap_set_err_check(out)
    out = netapp.set_style('LOGIN')
    ntap_set_err_check(out)
    out = netapp.set_admin_user(config['array_user'], config['array_password'])
    ntap_set_err_check(out)

    # Get list of SVMs from NetApp

    if svm_list == {}:
        result = netapp.invoke('vserver-get-iter')
        ntap_invoke_err_check(result)
        vs_info = result.child_get('attributes-list').children_get()
        for vs in vs_info:
            vs_type = vs.child_get_string("vserver-type")
            if vs_type == "data":
                svm_list[vs.child_get_string('vserver-name')] = ""


# Get list of interfaces on the NetApp.  Find the an applicable interface, grab the IP,
# then try to get a hostname from it via DNS

    for svm in svm_list.keys():
        int_list = []
        netapp.set_vserver(svm)
        result = netapp.invoke('net-interface-get-iter')
        ntap_invoke_err_check(result)
        try:
            ints = result.child_get('attributes-list').children_get()
        except AttributeError:
            continue
        for i in ints:
            int_name = i.child_get_string('interface-name')
            protocols = i.child_get('data-protocols').children_get()
            addr = i.child_get_string('address')
            try:
                host_lookup = socket.gethostbyaddr(addr)
                addr = host_lookup[0]
            except socket.herror:
                pass
            # Couldn't figure out how to pull the protocols properly, nasty hack.  Should clean up later
            proto_list = []
            for p in protocols:
                proto = p.sprintf()
                proto = proto.replace('<', '>')
                pf = proto.split('>')
                proto_list.append(pf[2])
            int_list.append({'address': addr, "protocols": proto_list})
            cand_list = []
            for int_cand in int_list:
                if protocol == "nfs,cifs":
                    if int_cand['protocols'] == ['nfs', 'cifs']:
                        cand_list = [int_cand]
                        break
                    elif int_cand['protocols'] == ["nfs"]:
                        cand_list.append(int_cand)
                    elif int_cand['protocols'] == ["cifs"]:
                        cand_list.append(int_cand)
                elif protocol == "nfs":
                    if int_cand['protocols'] == ["nfs"]:
                        cand_list = [int_cand]
                        break
                    elif int_cand['protocols'] == ["nfs,cifs"]:
                        cand_list.append(int_cand)
                elif protocol == "cifs":
                    if int_cand['protocols'] == ["cifs"]:
                        cand_list = [int_cand]
                        break
                    elif int_cand['protocols'] == ["nfs", "cifs"]:
                        cand_list.append(int_cand)
            host_list[svm] = cand_list
    return (host_list)
def ntap_get_share_list(ntap_host, protocol, svm_list, config):
    share_list = {}
    dprint("SVM_LIST2: " + str(svm_list))
    # Set up NetApp API session
    try:
        _create_unverified_https_context = ssl._create_unverified_context
    except AttributeError:
        pass
    else:
        ssl._create_default_https_context = _create_unverified_https_context
    netapp = NaServer(ntap_host, 1, 130)
    out = netapp.set_transport_type('HTTPS')
    ntap_set_err_check(out)
    out = netapp.set_style('LOGIN')
    ntap_set_err_check(out)
    out = netapp.set_admin_user(config['array_user'], config['array_password'])
    ntap_set_err_check(out)

    # For each SVM, grab the NFS exports of SMB shares.  Generate the share_list structure for main()

    for svm in svm_list.keys():
        svm_share_list = []
        junct_point = {}
        out = netapp.set_vserver(svm)
        share_host = get_host_from_svm_list(svm_list[svm], protocol)
        if protocol == "nfs":
            api = NaElement('volume-get-iter')
            l1 = NaElement('desired-attributes')
            api.child_add(l1)
            l2 = NaElement('volume-attributes')
            l1.child_add(l2)
            l2_1 = NaElement('volume-id-attributes')
            l2.child_add(l2_1)
            l2_1.child_add_string('name', '<name>')
            l2_1.child_add_string('junction-path', '<junction-path>')
            l2_2 = NaElement('volume-state-attributes')
            l2.child_add(l2_2)
            l2_2.child_add_string('is-node-root', '<is-node-root>')
            l2_2.child_add_string('is-vserver-root', '<is-vserver-root')
            api.child_add_string('max-records', 5000)
            result = netapp.invoke_elem(api)
            ntap_invoke_err_check(result)
            vol_attrs = result.child_get('attributes-list').children_get()
            for v in vol_attrs:
                vid_attrs = v.child_get('volume-id-attributes')
                vst_attrs = v.child_get('volume-state-attributes')
                node_root = vst_attrs.child_get_string('is-node-root')
                svm_root = vst_attrs.child_get_string('is-vserver-root')
                if node_root == "false" and svm_root == "false":
                    volume = vid_attrs.child_get_string('name')
                    print("FOUND VOL: " + volume)
                    junction = vid_attrs.child_get_string('junction-path')
                    junct_point[volume] = junction
            dprint("JUNCTION_POINTS for " + svm + ": " + str(junct_point))
            api = NaElement('qtree-list-iter')
            l1 = NaElement('desired-attributes')
            api.child_add(l1)
            l2 = NaElement('qtree-info')
            l1.child_add(l2)
            l2.child_add_string('qtree', '<qtree>')
            l2.child_add_string('volume', '<volume>')
            api.child_add_string('max-records', 5000)
            result = netapp.invoke_elem(api)
            ntap_invoke_err_check(result)
            qt_attrs = result.child_get('attributes-list').children_get()
            for qt in qt_attrs:
                volume = qt.child_get_string('volume')
                qtree = qt.child_get_string('qtree')
                if qtree == "":
                    try:
                        vol_j = junct_point[volume]
                    except KeyError:
                        print("KEY_ERROR")
                        continue
                else:
                    vol_j = junct_point[volume] + "/" + qtree
                if vol_j != "/" and type(vol_j) is unicode:
                    svm_share_list.append(vol_j + ":" + vol_j)
        elif protocol == "cifs" or protocol == "smb":
            result = netapp.invoke('cifs-share-get-iter')
            ntap_invoke_err_check(result)
            try:
                attr = result.child_get('attributes-list').children_get()
            except AttributeError:
                continue
            for sh in attr:
                path = sh.child_get_string('path')
                sh_name = sh.child_get_string('share-name')
                if path == "/":  # Exclude root volumes
                    continue
                svm_share_list.append(sh_name + ":" + path)
        share_list[share_host] = svm_share_list
    if config['purge_overlaps'] != "false":
        dprint("SHARE_LIST: " + str(share_list))
        purge_overlapping_shares(share_list, config['purge_overlaps'])
    return (share_list)
예제 #22
0
def ntap_get_share_list(host, user, password, protocol, interface, do_svms):
    svm_list = []
    addr = ""
    hostname = {}
    host_lookup = ()

    # Set up NetApp API session

    try:
        _create_unverified_https_context = ssl._create_unverified_context
    except AttributeError:
        pass
    else:
        ssl._create_default_https_context = _create_unverified_https_context
    netapp = NaServer(host, 1, 130)
    out = netapp.set_transport_type('HTTPS')
    ntap_set_err_check(out)
    out = netapp.set_style('LOGIN')
    ntap_set_err_check(out)
    out = netapp.set_admin_user(user, password)
    ntap_set_err_check(out)

    # Get list of SVMs from NetApp

    result = netapp.invoke('vserver-get-iter')
    ntap_invoke_err_check(result)
    vs_info = result.child_get('attributes-list').children_get()
    for vs in vs_info:
        vs_type = vs.child_get_string("vserver-type")
        if vs_type == "data":
            svm_list.append(vs.child_get_string('vserver-name'))

# Get list of interfaces on the NetApp.  Find the an applicable interface, grab the IP,
# then try to get a hostname from it via DNS

    result = netapp.invoke('net-interface-get-iter')
    ntap_invoke_err_check(result)
    ints = result.child_get('attributes-list').children_get()
    for i in ints:
        if interface:
            if i.child_get_string('interface-name') not in interface:
                continue
        protocols = i.child_get('data-protocols').children_get()

        # Couldn't figure out how to pull the protocols properly, nasty hack.  Should clean up later

        for p in protocols:
            proto = p.sprintf()
            proto = proto.replace('<', '>')
            pf = proto.split('>')
            if pf[2] == protocol or (pf[2] == "cifs" and protocol == "smb"):
                svm = i.child_get_string('vserver')
                addr = i.child_get_string('address')
                try:
                    host_lookup = socket.gethostbyaddr(addr)
                    hostname[svm] = host_lookup[0]
                except socket.herror:
                    hostname[svm] = addr


# For each SVM, grab the NFS exports of SMB shares.  Generate the share_list structure for main()
    dprint("HOSTNAME_ARRAY: " + str(hostname))
    for svm in svm_list:
        svm_share_list = []
        junct_point = {}
        if do_svms and svm not in do_svms:
            continue
        dprint("SVM = " + svm)
        out = netapp.set_vserver(svm)
        if protocol == "nfs":
            result = netapp.invoke('volume-get-iter')
            ntap_invoke_err_check(result)
            vol_attrs = result.child_get('attributes-list').children_get()
            for v in vol_attrs:
                vid_attrs = v.child_get('volume-id-attributes')
                volume = vid_attrs.child_get_string('name')
                junction = vid_attrs.child_get_string('junction-path')
                junct_point[volume] = junction
            dprint("JP = " + str(junct_point))
            result = netapp.invoke('qtree-list-iter')
            ntap_invoke_err_check(result)
            qt_attrs = result.child_get('attributes-list').children_get()
            for qt in qt_attrs:
                volume = qt.child_get_string('volume')
                qtree = qt.child_get_string('qtree')
                dprint("VOL= " + volume)
                dprint("QTREE= " + qtree)
                try:
                    dprint("JUNCT_P= " + junct_point[volume])
                except:
                    dprint("No Junction Point found")
                dprint("JUNCT = " + str(junct_point))
                if qtree == "":
                    try:
                        vol_j = junct_point[volume]
                    except:
                        continue
                else:
                    vol_j = junct_point[volume] + "/" + qtree
                if vol_j != "/":
                    svm_share_list.append(vol_j)
        elif protocol == "cifs" or protocol == "smb":
            api = NaElement("cifs-share-get-iter")
            xi = NaElement("desired-attributes")
            api.child_add(xi)
            xi1 = NaElement("cifs-share")
            xi1.child_add_string("vserver", "")
            xi1.child_add_string("path", "")
            xi.child_add(xi1)
            api.child_add_string('max-records', 5000)
            result = netapp.invoke_elem(api)
            ntap_invoke_err_check(result)
            try:
                attr = result.child_get('attributes-list').children_get()
            except:
                continue
            for sh in attr:
                sh_svm = sh.child_get_string('vserver')
                if sh_svm != svm:
                    continue
                path = sh.child_get_string('path')
                if path == "/":  # Exclude root volumes
                    continue
                svm_share_list.append(sh.child_get_string('share-name'))
        share_list[hostname[svm]] = svm_share_list
    return (share_list)
예제 #23
0
class Filer(object):
    """ NetApp Filer """
    def __init__(self, hostname, user, passwd):
        self.api = NaServer(hostname, 1, 3)
        response = self.api.set_style('LOGIN')

        if (response and response.results_errno() != 0):
            r = response.results_reason()
            print("Unable to set authentication style " + r + "\n")
            sys.exit(2)

        self.api.set_admin_user(user, passwd)
        self.api.set_transport_type('HTTPS')

        self.name = hostname

    def get_name(self):
        return self.name

    # Get list of volumes (OBJECTS)
    def get_volumes(self):
        volume_list_info = self.api.invoke("volume-list-info")

        if (volume_list_info.results_status() == "failed"):
            print(volume_list_info.results_reason() + "\n")
            sys.exit(2)

        volumes = volume_list_info.child_get("volumes")

        # Create a list of volumes based off the 'volumes' XML representation
        # User instance/object.sprintf()
        volume_list = volumes.children_get()
        return volume_list

    def is_vol_online(self, volume):
        if not isinstance(volume, str):
            vol_state = volume.child_get_string("state")

        if vol_state == 'online':
            return True
        else:
            return False

    # Return BOOL for volume protected/SnapMirrored status
    def is_vol_snapmirror_source(self, volume):
        if not isinstance(volume, str):
            volume = volume.child_get_string("name")

        snapmirror_vol_status = self.api.invoke("snapmirror-get-volume-status",
                                                "volume", volume)

        if (snapmirror_vol_status.results_status() == "failed"):
            print(snapmirror_vol_status.results_reason() + "\n")
            sys.exit(2)

        if snapmirror_vol_status.child_get_string("is-source") == 'true':
            return True
        else:
            return False

    # Get snapmirror_status_info object
    def get_vol_snapmirror_status_info(self, volume):
        if not isinstance(volume, str):
            volume = volume.child_get_string("name")

        snapmirror_get_status = self.api.invoke("snapmirror-get-status",
                                                "location", volume)
        if (snapmirror_get_status.results_status() == "failed"):
            print(snapmirror_get_status.results_reason() + "\n")
            sys.exit(2)

        snapmirror_status = snapmirror_get_status.child_get(
            "snapmirror-status")

        if (not (snapmirror_status == None)):
            snapmirror_status_info = snapmirror_status.child_get(
                'snapmirror-status-info')
        else:
            sys.exit(0)

        return snapmirror_status_info

    # Source location string
    def get_vol_snapmirror_source(self, volume):
        snapmirror_status_info = self.get_vol_snapmirror_status_info(volume)
        return snapmirror_status_info.child_get_string('source-location')

    # Destination location string
    def get_vol_snapmirror_destination(self, volume):
        snapmirror_status_info = self.get_vol_snapmirror_status_info(volume)
        return snapmirror_status_info.child_get_string('destination-location')

    # Lag time in seconds
    def get_vol_snapmirror_lag(self, volume):
        snapmirror_status_info = self.get_vol_snapmirror_status_info(volume)
        return snapmirror_status_info.child_get_int('lag-time')

    # Size in KB (int)
    def get_vol_snapmirror_last_transfer_size(self, volume):
        snapmirror_status_info = self.get_vol_snapmirror_status_info(volume)
        return snapmirror_status_info.child_get_int('last-transfer-size')

    # Duration in seconds
    def get_vol_snapmirror_last_transfer_duration(self, volume):
        snapmirror_status_info = self.get_vol_snapmirror_status_info(volume)
        return snapmirror_status_info.child_get_int('last-transfer-duration')

    # Current progress status
    def get_vol_snapmirror_progress(self, volume):
        snapmirror_status_info = self.get_vol_snapmirror_status_info(volume)
        return snapmirror_status_info.child_get_string('transfer-progress')

    # List of Snapmirrored Volumes
    def get_snapmirrored_volumes(self):
        snapmirrored_vols = []
        vols = self.get_volumes()

        for vol in vols:
            if self.is_vol_online(vol) and self.is_vol_snapmirror_source(vol):
                snapmirrored_vols.append(vol)

        return snapmirrored_vols

    # List of non-Snapmirrored Volumes
    def get_non_snapmirrored_volumes(self):
        non_snapmirrored_vols = []
        vols = self.get_volumes()

        for vol in vols:
            if self.is_vol_online(
                    vol) and not self.is_vol_snapmirror_source(vol):
                non_snapmirrored_vols.append(vol)

        return non_snapmirrored_vols

    # Volume protection report
    def vol_snapmirror_report(self, rpo=86400, ignore_volumes=[]):
        # Get list of Volume Objects
        vols = self.get_volumes()

        # Initialize [non]snapmirrored volumes arrays
        snapmirrored_vols = self.get_snapmirrored_volumes()
        non_snapmirrored_vols = self.get_non_snapmirrored_volumes()

        # Apply ignore_volumes exclusion
        snapmirrored_vols = [
            vol for vol in snapmirrored_vols
            if vol.child_get_string("name") not in ignore_volumes
        ]
        non_snapmirrored_vols = [
            vol for vol in non_snapmirrored_vols
            if vol.child_get_string("name") not in ignore_volumes
        ]

        # Generate report for non protected volumes
        # non_snapmirrored_vols_report 'string'
        if non_snapmirrored_vols:
            non_snapmirrored_vols_report = "------------------------------------------------------\n"
            non_snapmirrored_vols_report += "The following volumes are not protected by SnapMirror:\n"
            non_snapmirrored_vols_report += "------------------------------------------------------\n"

            # Output volumes not snapmirrored
            for vol in sorted(non_snapmirrored_vols,
                              key=lambda elm: elm.child_get_string("name")):
                non_snapmirrored_vols_report += vol.child_get_string(
                    "name") + "\n"

        # Generate report for protected volumes that have a lag
        if snapmirrored_vols:
            report_lag = ''
            for vol in sorted(snapmirrored_vols,
                              key=lambda elm: elm.child_get_string("name")):
                if self.get_vol_snapmirror_lag(vol) > int(rpo):
                    report_lag += "%30s | %40s | %18s | %18.2f(GB) | %25s | %8.2f(GB) " % (
                        self.get_vol_snapmirror_source(vol),
                        self.get_vol_snapmirror_destination(vol),
                        str(
                            datetime.timedelta(
                                seconds=self.get_vol_snapmirror_lag(vol))),
                        float(self.get_vol_snapmirror_last_transfer_size(vol))
                        / 1048576,
                        str(
                            datetime.timedelta(
                                seconds=self.
                                get_vol_snapmirror_last_transfer_duration(vol))
                        ), float(self.get_vol_snapmirror_progress(vol)) /
                        1024 / 1024)
                    report_lag += "\n"

            if report_lag:
                # Output Volumes snapmirrored with more than 24h RPO
                snapmirrored_vols_report = "\n\nThe following volumes are over %.1fh RPO:\n" % (
                    float(rpo) / 3600)

                header = "%30s | %40s | %18s | %20s | %25s | %12s \n" % (
                    'source-location', 'destination-location', 'lag-time(h)',
                    'last-transfer-size(GB)', 'last-transfer-duration(h)',
                    'transfering')
                separator = "-" * len(header) + "\n"

                snapmirrored_vols_report += separator + header + separator
                snapmirrored_vols_report += report_lag

        # Report Filer Name/Header + non protected vols + reported lag
        if report_lag or non_snapmirrored_vols:
            report = "\n" + "=" * 10 + self.get_name().upper(
            ) + "=" * 10 + "\n"

            if non_snapmirrored_vols:
                report += non_snapmirrored_vols_report

            if report_lag:
                report += snapmirrored_vols_report

            return report
        else:
            return ''