def netappSnapshot(
    ontapClusterMgmtHostname: str, 
    pvName: str, 
    verifySSLCert: bool = True
) -> str :
    # Install netapp_ontap package
    import sys, subprocess;
    subprocess.run([sys.executable, '-m', 'pip', 'install', 'netapp_ontap'])
    
    # Import needed functions/classes
    from netapp_ontap import config as netappConfig
    from netapp_ontap.host_connection import HostConnection as NetAppHostConnection
    from netapp_ontap.resources import Volume, Snapshot
    from datetime import datetime
    import json

    # Retrieve ONTAP cluster admin account details from mounted K8s secrets
    usernameSecret = open('/mnt/secret/username', 'r')
    ontapClusterAdminUsername = usernameSecret.read().strip()
    passwordSecret = open('/mnt/secret/password', 'r')
    ontapClusterAdminPassword = passwordSecret.read().strip()
    
    # Configure connection to ONTAP cluster/instance
    netappConfig.CONNECTION = NetAppHostConnection(
        host = ontapClusterMgmtHostname,
        username = ontapClusterAdminUsername,
        password = ontapClusterAdminPassword,
        verify = verifySSLCert
    )
    
    # Convert pv name to ONTAP volume name
    # The following will not work if you specified a custom storagePrefix when creating your
    #   Trident backend. If you specified a custom storagePrefix, you will need to update this
    #   code to match your prefix.
    volumeName = 'trident_%s' % pvName.replace("-", "_")
    print('\npv name: ', pvName)
    print('ONTAP volume name: ', volumeName)

    # Create snapshot; print API response
    volume = Volume.find(name = volumeName)
    timestamp = datetime.today().strftime("%Y%m%d_%H%M%S")
    snapshot = Snapshot.from_dict({
        'name': 'kfp_%s' % timestamp,
        'comment': 'Snapshot created by a Kubeflow pipeline',
        'volume': volume.to_dict()
    })
    response = snapshot.post()
    print("\nAPI Response:")
    print(response.http_response.text)

    # Retrieve snapshot details
    snapshot.get()

    # Convert snapshot details to JSON string and print
    snapshotDetails = snapshot.to_dict()
    print("\nSnapshot Details:")
    print(json.dumps(snapshotDetails, indent=2))

    # Return name of newly created snapshot
    return snapshotDetails['name']
Beispiel #2
0
def delete_volume(volume_name: str) -> None:
    """Delete a volume in a SVM"""

    volume = Volume.find(name=volume_name)

    try:
        volume.delete()
        print("Volume %s deleted successfully" % volume.name)
    except NetAppRestError as err:
        print("Error: Volume was not deleted: %s" % err)
    return
def get_volume(volume_name: str) -> None:
    """Get the details of a volume"""
    volume = Volume.find(name=volume_name)
    #volumemetrics = VolumeMetrics(volume.uuid)
    volumemetrics = VolumeMetrics.get_collection(volume.uuid,
                                                 fields="iops.total",
                                                 interval="1h")
    print(
        f"IOPs over the last hour for volume {volume.name} was {volumemetrics.iops.total}"
    )
    return
def make_snap_pycl(vol_name: str, snapshot_name: str, svm_name: str) -> None:
    """Create a new snapshot with default settings for a given volume"""

    volume = Volume.find(**{'svm.name': svm_name, 'name': vol_name})
    snapshot = Snapshot(volume.uuid, name=snapshot_name)

    try:
        snapshot.post()
        print("Snapshot %s created successfully" % snapshot.name)
    except NetAppRestError as err:
        print("Error: Snapshot was not created: %s" % err)
Beispiel #5
0
def get_volume(volume_name: str) -> None:
    """Get the details of a volume"""

    volume = Volume.find(name=volume_name)

    try:
        volume.get()
        print(volume.name)
        print("Volume details for %s obtained successfully" % volume.name)
    except NetAppRestError as err:
        print("Error: Volume details not obtained: %s" % err)
    return
Beispiel #6
0
    async def delete_volume(self, message):
        """
        A skills function to delete a volume. The parser looks for the message argument.

        Arguments:
            message {str} -- delete volume {name} on svm {svm}
        """
        name = message.regex.group('name')
        svm = message.regex.group('svm')
        volume = Volume.find(name=name, svm=svm)
        volume.delete()
        await message.respond('All done! Response: {}'.format(volume))
Beispiel #7
0
def resize_volume(volume_name: str, volume_resize: int) -> None:
    """Resize a volume in a SVM"""

    volume = Volume.find(name=volume_name)
    volume.size = volume_resize

    try:
        volume.patch()
        print("Volume %s resized successfully" % volume.name)
    except NetAppRestError as err:
        print("Error: Volume was not resized: %s" % err)
    return
def make_snap(vol_name: str, snapshot_name: str) -> Optional[Snapshot]:
    """Create a new snapshot with default settings for a given volume"""

    volume = Volume.find(name=vol_name)
    snapshot = Snapshot(volume.uuid, name=snapshot_name)

    try:
        snapshot.post()
        print("Snapshot %s created successfullys" % snapshot.name)
        return snapshot
    except NetAppRestError as err:
        print("Error: Snapshot was not created: %s" % err)
    return None
Beispiel #9
0
def move_volume(volume_name: str, move_aggr_name: str) -> None:
    """Move the volume to a new aggregate"""

    volume = Volume.find(name=volume_name)
    volume.movement = VolumeMovement(
        destination_aggregate={'name': move_aggr_name})

    try:
        volume.patch()
        print("Volume %s moved successfully" % volume.name)
    except NetAppRestError as err:
        print("Error: Volume was not moved: %s" % err)
    return
Beispiel #10
0
def delete_volume(api, apiuser, apipass):
    config.CONNECTION = HostConnection(api, apiuser, apipass, verify=False)

    print("=============================================")
    print()
    show_volume(api, apiuser, apipass)
    print()
    volname = input("Enter the name of the volume that needs to be Deleted:- ")
    vol = Volume.find(name=volname)

    try:
        if (vol.delete(poll=True)):
            print("Volume  has been deleted Successfully.")
    except NetAppRestError as e:
        print("HTTP Error Code is " % e.http_err_response.http_response.text)
        print("Exception caught :" + str(e))
    return
Beispiel #11
0
    async def create_snapshot(self, message):
        """
        A skills function to take a snapshot of a volume. The parser looks for the message argument.

        Arguments:
            message {str} -- create a snapshot of {volume} on svm {svm}
        """
        name = message.regex.group('name')
        svm = message.regex.group('svm')
        time = datetime.now()
        time = str(time)
        volume = Volume.find(name=name, svm={'name': svm})
        volume.get()
        snapshot = Snapshot.from_dict({
            'name': 'snapshot_%s' % time,
            'volume': volume.to_dict(),
        })
        snapshot.post()
        await message.respond('All done! Response: {}'.format(snapshot))
Beispiel #12
0
def delete_volume() -> None:
    """Delete Volume"""
    print("=============================================")
    print()
    show_volume()
    print()
    volname = input("Enter the name of the volume that needs to be Deleted:- ")

    try:
        vol = Volume.find(name=volname)
    except NetAppRestError as error:
        print("Error:- " % error.http_err_response.http_response.text)
        print("Exception caught :" + str(error))

    try:
        if vol.delete(poll=True):
            print("Volume  has been deleted Successfully.")
    except NetAppRestError as error:
        print("Error:- " % error.http_err_response.http_response.text)
        print("Exception caught :" + str(error))
Beispiel #13
0
def patch_volume(api, apiuser, apipass):
    config.CONNECTION = HostConnection(api, apiuser, apipass, verify=False)

    print("=============================================")
    print()
    show_volume(api, apiuser, apipass)
    print()
    vol_name = input(
        "Enter the name  of the volume that needs to be modified:- ")

    vol = Volume.find(name=vol_name)

    dataObj = {}
    print()
    nambool = input("Would you like to change the volume name (y/n):- ")
    if nambool == 'y':
        nam = input("Enter the new name of the Volume: ")
        vol.name = nam

    print()
    sizebool = input("Would you like to change the volume size (y/n) :- ")
    if sizebool == 'y':
        vol_size = input("Enter the new size of the Volume: ")
        vol_size_format = get_size(vol_size)
        vol.size = vol_size_format

    print()
    statebool = input("Would you like to change the volume state (y/n) :- ")
    if statebool == 'y':
        vol_state = input(
            "Enter the new state of the Volume [offline/online]: ")
        vol.state = vol_state

    try:
        if (vol.patch(poll=True)):
            print("The Volume  has been updated/patched Successfully")
    except NetAppRestError as e:
        print("HTTP Error Code is " % e.http_err_response.http_response.text)
        print("Exception caught :" + str(e))

    return
Beispiel #14
0
def patch_volume() -> None:
    """Update Volume"""
    print("=============================================")
    print()
    show_volume()
    print()
    vol_name = input(
        "Enter the name  of the volume that needs to be modified:- ")

    try:
        vol = Volume.find(name=vol_name)
    except NetAppRestError as error:
        print("Error:- " % error.http_err_response.http_response.text)
        print("Exception caught :" + str(error))

    print()
    nambool = input("Would you like to change the volume name (y/n):- ")
    if nambool == 'y':
        nam = input("Enter the new name of the Volume: ")
        vol.name = nam

    print()
    sizebool = input("Would you like to change the volume size (y/n) :- ")
    if sizebool == 'y':
        vol_size = input("Enter the new size of the Volume: ")
        vol_size_format = get_size(vol_size)
        vol.size = vol_size_format

    print()
    autosizebool = input(
        "Would you like to change the autosize options of the volume (y/n):- ")
    if autosizebool == 'y':
        print("Enter the following Details")
        grow_threshold = input("grow_threshold?:- ")
        maximum = input("maximum?:- ")
        minimum = input("minimum?:- ")
        mode = input("mode?:- ")
        shrink_threshold = input("shrink_threshold?:- ")
        autosizejson = {
            "grow_threshold": grow_threshold,
            "maximum": maximum,
            "minimum": minimum,
            "mode": mode,
            "shrink_threshold": shrink_threshold
        }
        vol.autosize = autosizejson

    print()
    efficiency = input("Would you like to enable Efficiency (y/n): ")
    if efficiency == 'y':
        print("Enter the following Details")
        compaction = input("compaction?:- ")
        compression = input("compression?:- ")
        cross_volume_dedupe = input("cross_volume_dedupe?:- ")
        dedupe = input("dedupe?:- ")
        policy_name_e = input("Efficiency Policy Name?:- ")
        efficiencyjson = {
            "compaction": compaction,
            "compression": compression,
            "cross_volume_dedupe": cross_volume_dedupe,
            "dedupe": dedupe,
            "policy": {
                "name": policy_name_e
            }
        }
        vol.efficiency = efficiencyjson

    print()
    encryption = input("Would you like to enable Encryption (y/n): ")
    if encryption == 'y':
        print("Enter the following Details")
        enabled_encry = input("Enable Encryption ?:- ")
        encryptionjson = {"enabled": bool(enabled_encry), "status": {}}
        vol.encryption = encryptionjson

    print()
    files = input("Would you like to enable Max File Count (y/n): ")
    if files == 'y':
        print("Enter the following Details")
        maximum_files = input("Max File Count?:- ")
        filesjson = {"maximum": maximum_files}
        vol.files = filesjson

    print()
    nas = input("Would you like to enable NAS parameters (y/n): ")
    if nas == 'y':
        print("Enter the following Details")
        export_policy_name = input("export_policy_name?:- ")
        path = input("path?:- ")
        security_style = input("security_style?:- ")
        unix_permissions = input("unix_permissions?:- ")
        nasjson = {
            "export_policy": {
                "name": export_policy_name
            },
            "path": path,
            "security_style": security_style,
            "unix_permissions": unix_permissions
        }
        vol.nas = nasjson

    print()
    qos = input("Would you like to enable QoS (y/n): ")
    if qos == 'y':
        print("Enter the following Details")
        max_throughput_iops = input("max_throughput_iops?:- ")
        max_throughput_mbps = input("max_throughput_mbps?:- ")
        min_throughput_iops = input("min_throughput_iops?:- ")
        qosname = input("qosname?:- ")
        qosjson = {
            "policy": {
                "max_throughput_iops": max_throughput_iops,
                "max_throughput_mbps": max_throughput_mbps,
                "min_throughput_iops": min_throughput_iops,
                "name": qosname
            }
        }
        vol.qos = qosjson

    print()
    quota = input("Would you like to enable Quota (y/n): ")
    if quota == 'y':
        print("Enter the following Details")
        enable_quota = input("enable_quota?:- ")
        quotajson = {"enabled": bool(enable_quota)}
        vol.quota = quotajson

    try:
        if vol.patch(poll=True):
            print("The Volume  has been updated/patched Successfully")
    except NetAppRestError as error:
        print("Error:- " % error.http_err_response.http_response.text)
        print("Exception caught :" + str(error))
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

conn = HostConnection('192.168.1.200', username='******', password='******', verify=False)

config.CONNECTION = conn

name = 'rubrik'
size = 20971520
aggr = 'ntap_study_data'
svm = 'study'

volume = Volume.from_dict({'name': name, 'svm': {'name': svm}, 'nas': {'path': '/'+name} , 'size': size, 'aggregates': [{'name': aggr}]})
volume.post()

vol = Volume.find(name=name)
vol.get(fields='nas.path')
print(vol.nas.path)

"""
#volume = Volume.find(name=name, svm=svm)
#volume.delete()

#for svm in Svm.get_collection():
#    svm.get()
#    print(svm.to_dict())

volumes = []
for vol in Volume.get_collection(svm=svm):
    vol.get(fields='name')
    volumes.append(vol.name)
from netapp_ontap import config
from netapp_ontap import HostConnection
from netapp_ontap.resources import Cluster, Aggregate, Port, Volume, Autosupport, IpInterface, Disk, Chassis, Account, Svm, Snapshot
from datetime import datetime
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

conn = HostConnection('192.168.1.200',
                      username='******',
                      password='******',
                      verify=False)

config.CONNECTION = conn
#vol = Volume.find(name='movies')
#vol.get()
#print(vol)

#volume = Volume(name='vol1', svm={'name': 'study'}, aggregates=[{'name': 'ntap_study_data'}])
#volume.post()

time = datetime.now()
time = str(time)
volume = Volume.find(name='soccer', svm={'name': 'study'})
volume.get()
snapshot = Snapshot.from_dict({
    'name': 'snapshot_%s' % time,
    'volume': volume.to_dict(),
})
snapshot.post()
Beispiel #17
0
def get_volume(volume_name):
    return (Volume.find(name=volume_name))