Exemplo n.º 1
0
def vol_size(module):

    cluster = module.params['cluster']
    user_name = module.params['user_name']
    password = module.params['password']
    vserver = module.params['vserver']
    volume = module.params['volume']
    size = module.params['size']

    results = {}

    results['changed'] = False

    s = NaServer(cluster, 1, 15)
    s.set_server_type("FILER")
    s.set_transport_type("HTTPS")
    s.set_port(443)
    s.set_style("LOGIN")
    s.set_admin_user(user_name, password)
    s.set_vserver(vserver)

    api = NaElement("volume-size")
    api.child_add_string("volume", volume)
    api.child_add_string("new-size", size)
    xo = s.invoke_elem(api)

    if (xo.results_errno() != 0):
        r = xo.results_reason()
        module.fail_json(msg=r)
        results['changed'] = False

    else:
        results['changed'] = True

    return results
def snmp_community_add(module):

  cluster = module.params['cluster']
  user_name = module.params['user_name']
  password = module.params['password']
  vserver = module.params['vserver']
  access_control = module.params['access_control']
  community = module.params['community']

  results = {}

  results['changed'] = False

  s = NaServer(cluster, 1 , 15)
  s.set_server_type("FILER")
  s.set_transport_type("HTTPS")
  s.set_port(443)
  s.set_style("LOGIN")
  s.set_admin_user(user_name, password)
  s.set_vserver(vserver)

  api = NaElement("snmp-community-add")
  api.child_add_string("access-control", access_control)
  api.child_add_string("community", community)
  xo = s.invoke_elem(api)

  if(xo.results_errno() != 0):
    r = xo.results_reason()
    module.fail_json(msg=r)
    results['changed'] = False

  else:
    results['changed'] = True

  return results
Exemplo n.º 3
0
def connect_to_api(module, vserver=None):
    cluster = module.params['cluster']
    user_name = module.params['user_name']
    password = module.params['password']
    validate_certs = module.params['validate_certs']

    if not validate_certs:
        invoke_ssl_no_verify()

    connection = NaServer(cluster, 1, 0)
    connection.set_server_type("FILER")
    connection.set_transport_type("HTTPS")
    connection.set_port(443)
    connection.set_style("LOGIN")
    connection.set_admin_user(user_name, password)
    if vserver:
        connection.set_vserver(vserver)
    return connection
def nfs_service_create(module):

    cluster = module.params['cluster']
    user_name = module.params['user_name']
    password = module.params['password']
    vserver = module.params['vserver']
    nfs_access = module.params['nfs_access']
    nfsv3_enabled = module.params['nfsv3_enabled']
    nfsv40_enabled = module.params['nfsv40_enabled']
    nfsv41_enabled = module.params['nfsv41_enabled']
    vstorage_enabled = module.params['vstorage_enabled']
    nfsv41_pnfs_enabled = module.params['nfsv41_pnfs_enabled']

    results = {}

    results['changed'] = False

    s = NaServer(cluster, 1, 15)
    s.set_server_type("FILER")
    s.set_transport_type("HTTPS")
    s.set_port(443)
    s.set_style("LOGIN")
    s.set_admin_user(user_name, password)
    s.set_vserver(vserver)

    api = NaElement("nfs-service-create")
    api.child_add_string("is-nfs-access-enabled", nfs_access)
    api.child_add_string("is-nfsv3-enabled", nfsv3_enabled)
    api.child_add_string("is-nfsv40-enabled", nfsv40_enabled)
    api.child_add_string("is-nfsv41-enabled", nfsv41_enabled)
    api.child_add_string("is-vstorage-enabled", vstorage_enabled)
    api.child_add_string("is-nfsv41-pnfs-enabled", nfsv41_pnfs_enabled)
    xo = s.invoke_elem(api)

    if (xo.results_errno() != 0):
        r = xo.results_reason()
        module.fail_json(msg=r)
        results['changed'] = False

    else:
        results['changed'] = True

    return results
Exemplo n.º 5
0
def main():
	
	module = AnsibleModule(
   		argument_spec=dict(
        		storage=dict(default=None, required=True),
			user=dict(default='admin', required=False),
			password=dict(default='P@ssw0rd', required=False),
			vserver_name=dict(default=None, required=True),
			volume_name=dict(default=None, required=True),
			security_style=dict(default='unix', required=False),
			guarantee=dict(default='volume', required=False),
			aggr_name=dict(default=None, required=True),
		),
	)
	
	storage        = module.params['storage']
	user           = module.params['user']
	password       = module.params['password']
	vserver_name   = module.params['vserver_name']
	volume_name    = module.params['volume_name']
	security_style = module.params['security_style']
	guarantee      = module.params['guarantee']
	aggr_name      = module.params['aggr_name']

	s = NaServer(storage, 1, 20)
	s.set_admin_user(user, password)
	s.set_vserver(vserver_name)

	api = NaElement('volume-create')
	api.child_add_string('volume', volume_name)
	api.child_add_string('space-reserve', guarantee)
	api.child_add_string('containing-aggr-name', aggr_name)

	output = s.invoke_elem(api)
	#print(output.results_status())
	#print(output.sprintf())

	module.exit_json(changed=True)
def export_policy_create(module):

  cluster = module.params['cluster']
  user_name = module.params['user_name']
  password = module.params['password']
  vserver = module.params['vserver']
  policy_name = module.params['policy_name']
  return_record = module.params['return_record']

  results = {}

  results['changed'] = False

  s = NaServer(cluster, 1 , 15)
  s.set_server_type("FILER")
  s.set_transport_type("HTTPS")
  s.set_port(443)
  s.set_style("LOGIN")
  s.set_admin_user(user_name, password)
  s.set_vserver(vserver)

  api = NaElement("export-policy-create")
  api.child_add_string("policy-name", policy_name)
  if module.params['return_record']:
    api.child_add_string("return-record", return_record)
  xo = s.invoke_elem(api)

  if(xo.results_errno() != 0):
    r = xo.results_reason()
    module.fail_json(msg=r)
    results['changed'] = False

  else:
    results['changed'] = True

  return results
Exemplo n.º 7
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)
        dossl = 1
        vserver = sys.argv[2]

    else:
        print_usage()

else:
    vserver  = opt
    storage = sys.argv[2]
    user = sys.argv[3]
    password = sys.argv[4] 
    arguments = sys.argv[5:]

# open server
server = NaServer(storage, 1, 15)
if(not server.set_vserver(vserver)):
    sys.exit (1)

server.set_admin_user(user, password)

if (dossl) :
    resp = server.set_transport_type("HTTPS")
    if (resp and resp.results_errno() != 0) :
        r = resp.results_reason()
        print ("Unable to set HTTPS transport " + r + "\n")
        sys.exit (1)
length = len(arguments)
if(length > 0):
    # invoke the api with api name and any supplied key-value pairs
    x = NaElement(arguments[0])
    k = 0
Exemplo n.º 9
0
def login():
    if 'username' in session:
        return redirect(url_for('vols'))

    error = None
    try:
        if request.method == 'POST':
            session['username'] = request.form['username']
            session['pass'] = request.form['password']
            session['vserver'] = request.form['vserver']
            if session['vserver'] == "KW1PESANV01":
                IP = '10.200.5.100'
            elif session['vserver'] == "SG1PESANV01":
                IP = '10.201.18.70'

            try:

                s = NaServer(IP, 1, 30)
                s.set_server_type("FILER")
                s.set_transport_type("HTTPS")
                s.set_port(443)
                s.set_style("LOGIN")
                s.set_admin_user(session['username'], session['pass'])
                s.set_vserver(session['vserver'])
                s.set_server_cert_verification("False")
                s.set_hostname_verification("False")

                api = NaElement("volume-get-iter")

                xi = NaElement("desired-attributes")
                api.child_add(xi)

                xi = NaElement("desired-attributes")
                api.child_add(xi)

                xi1 = NaElement("volume-attributes")
                xi.child_add(xi1)
                xi11 = NaElement("volume-id-attributes")
                xi1.child_add(xi11)
                xi11.child_add_string("name", "name")

                xi27 = NaElement("volume-space-attributes")
                xi1.child_add(xi27)
                xi27.child_add_string("size-total", "<size-total>")
                xi27.child_add_string("percentage-size-used",
                                      "<percentage-size-used>")
                api.child_add_string("max-records", "1000")
                xo = s.invoke_elem(api)
                if (xo.results_status() == "failed"):
                    print("Error:\n")
                    print(xo.sprintf())
                    sys.exit(1)
                else:
                    # print (xo.sprintf())
                    vols = xo.child_get("attributes-list").children_get()
                    data = []
                    for vol in vols:
                        mydict = xmltodict.parse(vol.sprintf())
                        if 'volume-space-attributes' not in mydict[
                                'volume-attributes']:
                            continue

                        dicty = mydict['volume-attributes'][
                            'volume-id-attributes'].copy()
                        dicty.update(mydict['volume-attributes']
                                     ['volume-space-attributes'])
                        dicty['size-total'] = (
                            '%.0f' % (float(int(dicty['size-total'].strip())) /
                                      1024 / 1024 / 1024))
                        del dicty['owning-vserver-name']
                        dictyy = OrderedDict()
                        dictyy['name'] = dicty['name']
                        dictyy['size-total'] = dicty['size-total'] + ' GB'
                        dictyy['percentage-size-used'] = dicty[
                            'percentage-size-used'] + ' %'
                        data.append(dictyy)

            except Exception, err:
                print "Error!"
                print Exception, err

    except ServerError as e:
        error = str(e)

    return render_template('login.html', error=error)
Exemplo n.º 10
0
def export_rule_create(module):

    cluster = module.params['cluster']
    user_name = module.params['user_name']
    password = module.params['password']
    vserver = module.params['vserver']
    policy_name = module.params['policy_name']
    client_match = module.params['client_match']
    ro_rule = module.params['ro_rule']
    rw_rule = module.params['rw_rule']
    protocol = module.params['protocol']
    super_user_security = module.params['super_user_security']
    rule_index = module.params['rule_index']
    allow_suid = module.params['allow_suid']

    results = {}

    results['changed'] = False

    s = NaServer(cluster, 1, 15)
    s.set_server_type("FILER")
    s.set_transport_type("HTTPS")
    s.set_port(443)
    s.set_style("LOGIN")
    s.set_admin_user(user_name, password)
    s.set_vserver(vserver)

    api = NaElement('export-rule-create')
    api.child_add_string('policy-name', policy_name)
    api.child_add_string('client-match', client_match)
    if module.params['ro_rule']:
        xi = NaElement('ro-rule')
        api.child_add(xi)
        for flavor in ro_rule:
            xi.child_add_string('security-flavor', flavor)
    if module.params['rw_rule']:
        xi = NaElement("rw-rule")
        api.child_add(xi)
        for flavor in rw_rule:
            xi.child_add_string("security-flavor", flavor)
    if module.params['protocol']:
        xi = NaElement('protocol')
        api.child_add(xi)
        for proto in protocol:
            xi.child_add_string('access-protocol', proto)
    if module.params['super_user_security']:
        xi = NaElement('super-user-security')
        api.child_add(xi)
        for flavor in super_user_security:
            xi.child_add_string('security-flavor', flavor)
    if module.params['rule_index']:
        api.child_add_string('rule-index', rule_index)
    if module.params['allow_suid']:
        api.child_add_string('is-allow-set-uid-enabled', allow_suid)

    xo = s.invoke_elem(api)

    if (xo.results_errno() != 0):
        r = xo.results_reason()
        module.fail_json(msg=r)
        results['changed'] = False

    else:
        results['changed'] = True

    return results
Exemplo n.º 11
0
except AttributeError:
    pass
else:
    ssl._create_default_https_context = _create_unverified_https_context

with open('config.yml') as stream:
    config = yaml.safe_load(stream)

try:
    s = NaServer(config['filer'], 1, 30)
    s.set_server_type("FILER")
    s.set_transport_type("HTTPS")
    s.set_port(443)
    s.set_style("LOGIN")
    s.set_admin_user(config['username'], config['password'])
    s.set_vserver(config['vserver'])
    s.set_server_cert_verification("False")
    s.set_hostname_verification("False")

    api = NaElement("volume-get-iter")

    xi = NaElement("desired-attributes")
    api.child_add(xi)

    xi1 = NaElement("volume-attributes")
    xi.child_add(xi1)

    xi11 = NaElement("volume-id-attributes")
    xi1.child_add(xi11)
    xi11.child_add_string("name", "name")
Exemplo n.º 12
0
    cluster_name = cluster_info.child_get_string('cluster-name')
    cluster_serial = cluster_info.child_get_string('cluster-serial-number')
    cluster_location = cluster_info.child_get_string('cluster-location')

    # Pull SVMs from NTAP
    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'))
    dprint(svm_list)

    for svm_inst in svm_list:
        netapp.set_vserver(svm_inst)
        dprint("Processing SVM: " + svm_inst)
        # Discover volumes that have LUNs.  Will exclude them later
        if NAS_ONLY:
            has_luns = True
            result = netapp.invoke('lun-get-iter')
            ntap_invoke_err_check(result)
            try:
                lun_info = result.child_get('attributes-list').children_get()
            except AttributeError:
                has_luns = False
            if has_luns:
                for lun in lun_info:
                    lun_vol = lun.child_get_string('volume')
                    lun_svm = lun.child_get_string('vserver')
                    try:
Exemplo n.º 13
0
def volume_create(module):

    cluster = module.params['cluster']
    user_name = module.params['user_name']
    password = module.params['password']
    vserver = module.params['vserver']
    volume = module.params['volume']
    aggregate = module.params['aggregate']
    size = module.params['size']
    state = module.params['state']
    type = module.params['type']
    policy = module.params['policy']
    percentage_snapshot_reserve = module.params['percentage_snapshot_reserve']
    junction_path = module.params['junction_path']
    snapshot_policy = module.params['snapshot_policy']
    space_reserve = module.params['space_reserve']

    results = {}

    results['changed'] = False

    s = NaServer(cluster, 1, 15)
    s.set_server_type("FILER")
    s.set_transport_type("HTTPS")
    s.set_port(443)
    s.set_style("LOGIN")
    s.set_admin_user(user_name, password)
    s.set_vserver(vserver)

    api = NaElement("volume-create")
    api.child_add_string("volume", volume)
    if module.params['aggregate']:
        api.child_add_string("containing-aggr-name", aggregate)
    if module.params['size']:
        api.child_add_string("size", size)
    if module.params['state']:
        api.child_add_string("volume-state", state)
    if module.params['type']:
        api.child_add_string("volume-type", type)
    if module.params['policy']:
        api.child_add_string("export-policy", policy)
    if module.params['percentage_snapshot_reserve']:
        api.child_add_string("percentage-snapshot-reserve",
                             percentage_snapshot_reserve)
    if module.params['junction_path']:
        api.child_add_string("junction-path", junction_path)
    if module.params['snapshot_policy']:
        api.child_add_string("snapshot-policy", snapshot_policy)
    if module.params['space_reserve']:
        api.child_add_string("space-reserve", space_reserve)

    xo = s.invoke_elem(api)

    if (xo.results_errno() != 0):
        r = xo.results_reason()
        module.fail_json(msg=r)
        results['changed'] = False

    else:
        results['changed'] = True

    return results
Exemplo n.º 14
0
def cluster_setup(cluster):
	print("> " + cluster["cluster-name"] + ": Creating Cluster ")
	
	for node in cluster["cluster-nodes"]:
	
		print("---> " + node["node-name"] + ": Working on node ")
		session = NaServer(node["ip"], 1, 140)
		session.set_server_type("Filer")
		session.set_admin_user(node["user"], node["password"])
		session.set_transport_type("HTTPS")
		
		# STEP: Create cluster
		if("-01" in node["node-name"]):
			print("---> " + node["node-name"] + ": Creating cluster...")
			zapi_post = NaElement("cluster-create")
			zapi_post.child_add_string("cluster-name", cluster["cluster-name"])
			if len(cluster["cluster-nodes"]) > 1:
				zapi_post.child_add_string("single-node-cluster", "false")
			else:
				zapi_post.child_add_string("single-node-cluster", "true")

			zapi_post_return = session.invoke_elem(zapi_post)
			if(zapi_post_return.results_status() == "failed"):
				print("--- " + node["node-name"] + ": " + zapi_post.sprintf().strip())
				print("--- " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
				sys.exit(1)
			else:
				zapi_get = NaElement("cluster-create-join-progress-get")
				is_complete = ""
				create_iterator = 1
				while is_complete != "true" and \
						create_iterator < 13:
					time.sleep(10)
					zapi_get_return = session.invoke_elem(zapi_get)
					is_complete = zapi_get_return.child_get("attributes").child_get("cluster-create-join-progress-info").child_get_string("is-complete")
					action_status = zapi_get_return.child_get("attributes").child_get("cluster-create-join-progress-info").child_get_string("status")
					create_iterator = create_iterator + 1
				if(is_complete == "true") and (action_status == "success"):
					print("---> " + node["node-name"] + ": SUCCESS")
				else:
					print("---> " + node["node-name"] + ": " + zapi_get.sprintf().strip())
					print("---> " + node["node-name"] + ": " + zapi_get_return.sprintf().strip())
					sys.exit(1)
		
		# STEP: Create cluster management LIF
		if("-01" in node["node-name"]):
			print("--- " + node["node-name"] + ": Creating cluster management LIF...")
			found = False
			for lif in cluster["net-interfaces"]:
				if lif["role"] == "cluster-mgmt":
					found = True
					zapi_post = NaElement("net-interface-create")
					zapi_post.child_add_string("vserver", cluster["cluster-name"])
					for k, v in lif.items():
						zapi_post.child_add_string(k, v)
					break
			if found:
				zapi_post_return = session.invoke_elem(zapi_post)
				if (zapi_post_return.results_status() == "failed"):
					print("---> " + node["node-name"] + ": " + zapi_post.sprintf().strip())
					print("---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
				else:
					print("---> " + node["node-name"] + ": SUCCESS")
		
		# STEP: Remove existing cluster LIFs
		print("---> " + node["node-name"] + ": Removing existing cluster LIFs...")
		zapi_get = NaElement("net-interface-get-iter")
		elementQuery = NaElement("query")
		elementInterfaces = NaElement("net-interface-info")
		elementInterfaces.child_add_string("role", "cluster")
		elementQuery.child_add(elementInterfaces)
		zapi_get.child_add(elementQuery)
		zapi_get_return = session.invoke_elem(zapi_get)
		if (zapi_get_return.results_status() == "failed"):
			print("---> " + node["node-name"] + ": " + zapi_get.sprintf().strip())
			print("---> " + node["node-name"] + ": " + zapi_get_return.sprintf())
		else:
			if(int(zapi_get_return.child_get_string("num-records")) > 0):
				for lif in zapi_get_return.child_get("attributes-list").children_get():
					print("   --- " + node["node-name"] + ": Deleting " + lif.child_get_string("interface-name") + "...")
					zapi_post = NaElement("net-interface-delete")
					zapi_post.child_add_string("vserver", "Cluster")
					zapi_post.child_add_string("interface-name", lif.child_get_string("interface-name"))
					zapi_post_return = session.invoke_elem(zapi_post)
					if (zapi_post_return.results_status() == "failed"):
						print("   ---> " + node["node-name"] + ": " + zapi_post.sprintf().strip())
						print("   ---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
					else:
						print("   ---> " + node["node-name"] + ": SUCCESS")
			else:
				print("---> " + node["node-name"] + ": Nothing to delete")
		
		# STEP: Modifying port configuration
		print("--- " + node["node-name"] + ": Modifying network ports...")
		zapi_get = NaElement("net-port-get-iter")
		zapi_get_return = session.invoke_elem(zapi_get)
		
		if(int(zapi_get_return.child_get_string("num-records")) > 1):
			for port in zapi_get_return.child_get("attributes-list").children_get():
				if port.child_get_string("port") != "e0M":
					# Remove from broadcast domain
					if(port.child_get_string("node") != "localhost"):
						print("   --- " + node["node-name"] + ": Removing " + port.child_get_string("port") + " from broadcast domain...")
						if not port.child_get_string("broadcast-domain") is None:
							zapi_post = NaElement("net-port-broadcast-domain-remove-ports")
							elementPorts = NaElement("ports")
							elementPorts.child_add_string("net-qualified-port-name", port.child_get_string("node") + ":" + port.child_get_string("port"))
							zapi_post.child_add_string("ipspace", port.child_get_string("ipspace"))
							zapi_post.child_add_string("broadcast-domain", port.child_get_string("broadcast-domain"))
							zapi_post.child_add(elementPorts)
							zapi_post_return = session.invoke_elem(zapi_post)
							if (zapi_post_return.results_status() == "failed"):
								print("   ---> " + node["node-name"] + ": " + zapi_post.sprintf().strip())
								print("   ---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
							else:
								print("   ---> " + node["node-name"] + ": SUCCESS")
						else:
							print("   ---> " + node["node-name"] + ": Skipping (port has no broadcast domain assigned")
					# Modify port
					print("   --- " + node["node-name"] + ": Modifying " + port.child_get_string("port") + "...")
					zapi_post = NaElement("net-port-modify")
					for params in node["net-ports"]:
						if params["port"] == port.child_get_string("port"):
							zapi_post.child_add_string("port", params["port"])
							zapi_post.child_add_string("node", port.child_get_string("node"))
							zapi_post.child_add_string("is-administrative-auto-negotiate", params["is-administrative-auto-negotiate"])
							zapi_post.child_add_string("administrative-duplex", params["administrative-duplex"])
							zapi_post.child_add_string("administrative-speed", params["administrative-speed"])
							zapi_post.child_add_string("administrative-flowcontrol", params["administrative-flowcontrol"])
							zapi_post.child_add_string("is-administrative-up", "true")
							if port.child_get_string("node") == "localhost":
								zapi_post.child_add_string("mtu", params["mtu"])
								zapi_post.child_add_string("role", params["role"])
								zapi_post.child_add_string("ipspace", params["ipspace"])
							zapi_post_return = session.invoke_elem(zapi_post)
							if (zapi_post_return.results_status() == "failed"):
								print("   ---> " + node["node-name"] + ": " + zapi_post.sprintf().strip())
								print("   ---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
							else:
								print("   ---> " + node["node-name"] + ": SUCCESS")
					# Add to broadcast domain
					if(port.child_get_string("node") != "localhost"):
						for params in node["net-ports"]:
							if params["port"] == port.child_get_string("port"):
								print("   --- Adding " + port.child_get_string("port") + " to broadcast domain 'Cluster'...")
								if(params["broadcast-domain"] == "Cluster"):
									zapi_post = NaElement("net-port-broadcast-domain-add-ports")
									elementPorts = NaElement("ports")
									elementPorts.child_add_string("net-qualified-port-name", node["node-name"] + ":" + params["port"])
									zapi_post.child_add_string("ipspace", params["ipspace"])
									zapi_post.child_add_string("broadcast-domain", params["broadcast-domain"])
									zapi_post.child_add(elementPorts)
									zapi_post_return = session.invoke_elem(zapi_post)
									if(zapi_post_return.results_status() == "failed"):
										print("   ---> " + node["node-name"] + ": " + zapi_post.sprintf().strip())
										print("   ---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
									else:
										print("   ---> " + node["node-name"] + ": SUCCESS")
								else:
									print("   ---> " + node["node-name"] + ": Skipping (port is not a cluster port)")
		time.sleep(15)
		
		# STEP: Create new cluster LIFs
		print("--- " + node["node-name"] + ": Creating cluster LIFs...")
		zapi_get = NaElement("net-port-get-iter")
		elementQuery = NaElement("query")
		elementPorts = NaElement("net-port-info")
		elementPorts.child_add_string("ipspace", "Cluster")
		elementQuery.child_add(elementPorts)
		zapi_get.child_add(elementQuery)
		zapi_get_return = session.invoke_elem(zapi_get)
		if(int(zapi_get_return.child_get_string("num-records")) > 0):
			lif_iterator = 1
			lif_count = int(zapi_get_return.child_get_string("num-records"))
			while lif_iterator < lif_count + 1:
				print("   --- " + node["node-name"] + ": Creating cluster LIF #" + str(lif_iterator) + "...")
				zapi_post = NaElement("net-interface-create")
				zapi_post.child_add_string("vserver", "Cluster")
				zapi_post.child_add_string("interface-name", "clus" + str(lif_iterator))
				zapi_post.child_add_string("role", "Cluster")
				zapi_post.child_add_string("home-node", zapi_get_return.child_get("attributes-list").children_get()[lif_iterator - 1].child_get_string("node"))
				zapi_post.child_add_string("home-port", zapi_get_return.child_get("attributes-list").children_get()[lif_iterator - 1].child_get_string("port"))
				zapi_post.child_add_string("is-ipv4-link-local", "true")
				zapi_post_return = session.invoke_elem(zapi_post)
				if(zapi_post_return.results_status() == "failed"):
					print("   ---> " + node["node-name"] + ": " + zapi_post.sprintf().strip())
					print("   ---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
				else:
					print("   ---> " + node["node-name"] + ": SUCCESS")
				lif_iterator = lif_iterator + 1
		else:
			print("---> " + node["node-name"] + ": No ports found to create LIFs on!")
			
		# STEP: Reading cluster LIF IP for joining additional nodes later
		if("-01" in node["node-name"]):
			print("--- " + node["node-name"] + ": Reading cluster LIF IP for joining further nodes later...")
			clus_lif_ip = ""
			zapi_get = NaElement("net-interface-get-iter")
			elementQuery = NaElement("query")
			elementInterface = NaElement("net-interface-info")
			elementInterface.child_add_string("vserver", "Cluster")
			elementQuery.child_add(elementInterface)
			zapi_get.child_add_string("max-records", 1)
			zapi_get.child_add(elementQuery)
			zapi_get_return = session.invoke_elem(zapi_get)
			if(zapi_get_return.results_status() == "failed"):
				print("---> " + node["node-name"] + ": " + zapi_get.sprintf().strip())
				print("---> " + node["node-name"] + ": " + zapi_get_return.sprintf().strip())
			else:
				if(int(zapi_get_return.child_get_string("num-records")) == 0):
					print("---> " + node["node-name"] + ": No LIFs found")
				else:
					clus_lif_ip = zapi_get_return.child_get("attributes-list").child_get("net-interface-info").child_get_string("address")
					print("---> " + node["node-name"] + ": SUCCESS")

		# STEP: Join nodes to cluster
		if(not "-01" in node["node-name"]):
			print("--- " + node["node-name"] + ": Joining node to cluster...")
			zapi_post = NaElement("cluster-join")
			zapi_post.child_add_string("cluster-ip-address", clus_lif_ip)
			zapi_post_return = session.invoke_elem(zapi_post)
			if(zapi_post_return.results_status() == "failed"):
				print("---> " + node["node-name"] + ": " + zapi_post_return.sprintf().strip())
				sys.exit(1)
			else:
				zapi_get = NaElement("cluster-create-join-progress-get")
				is_complete = ""
				join_iterator = 1
				while is_complete != "true" and \
						join_iterator < 13:
					time.sleep(10)
					zapi_get_return = session.invoke_elem(zapi_get)
					is_complete = zapi_get_return.child_get("attributes").child_get("cluster-create-join-progress-info").child_get_string("is-complete")
					action_status = zapi_get_return.child_get("attributes").child_get("cluster-create-join-progress-info").child_get_string("status")
					join_iterator = join_iterator + 1
				if(is_complete == "true") and (action_status == "success"):
					print("---> " + node["node-name"] + ": SUCCESS")
				else:
					print("---> " + node["node-name"] + ": " + zapi_get.sprintf().strip())
					print("---> " + node["node-name"] + ": " + zapi_get_return.sprintf().strip())
					sys.exit(1)
	
	print("> " + cluster["cluster-name"] + ": Configuring Cluster")
	
	session = NaServer(cluster["ip"], 1, 140)
	session.set_server_type("Filer")
	session.set_admin_user(cluster["user"], cluster["password"])
	session.set_transport_type("HTTPS")
		
	# STEP: Correcting network ports
	print("--- " + cluster["cluster-name"] + ": Cleaning port configuration...")
	zapi_get = NaElement("net-port-get-iter")
	zapi_get_return = session.invoke_elem(zapi_get)
	if(int(zapi_get_return.child_get_string("num-records")) > 0):
		for port in zapi_get_return.child_get("attributes-list").children_get():
			if(port.child_get_string("ipspace") != "Cluster") and \
				(port.child_get_string("port") != "e0M") and \
				(not port.child_get_string("broadcast-domain") is None):
				# Remove from broadcast domain
				print("   --- " + cluster["cluster-name"] + ": Removing " + port.child_get_string("port") + " from broadcast domain...")
				zapi_post = NaElement("net-port-broadcast-domain-remove-ports")
				elementPorts = NaElement("ports")
				elementPorts.child_add_string("net-qualified-port-name", port.child_get_string("node") + ":" + port.child_get_string("port"))
				zapi_post.child_add_string("ipspace", port.child_get_string("ipspace"))
				zapi_post.child_add_string("broadcast-domain", port.child_get_string("broadcast-domain"))
				zapi_post.child_add(elementPorts)
				zapi_post_return = session.invoke_elem(zapi_post)
				if (zapi_post_return.results_status() == "failed"):
					print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
					print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
				else:
					print("   ---> " + cluster["cluster-name"] + ": SUCCESS")

	# STEP: Create IPspaces
	print("--- " + cluster["cluster-name"] + ": Creating IPspaces...")
	for ipspace in cluster["net-ipspaces"]:
		print("   --- " + cluster["cluster-name"] + ": Creating IPspace " + ipspace["ipspace"])
		zapi_post = NaElement("net-ipspaces-create")
		for k, v in ipspace.items():
			zapi_post.child_add_string(k, v)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Create VLANs
	print("--- " + cluster["cluster-name"] + ": Creating VLANs...")
	for node in cluster["cluster-nodes"]:
		for port in node["net-ports"]:
			if "-" in port["port"]:
				print("   --- " + cluster["cluster-name"] + ": Creating VLAN " + port["port"] + " on node " + node["node-name"])
				zapi_post = NaElement("net-vlan-create")
				elementVLAN = NaElement("vlan-info")
				elementVLAN.child_add_string("node", node["node-name"])
				elementVLAN.child_add_string("parent-interface", port["port"].split("-")[0])
				elementVLAN.child_add_string("vlanid", port["port"].split("-")[1])
				zapi_post.child_add(elementVLAN)
				zapi_post_return = session.invoke_elem(zapi_post)
				if (zapi_post_return.results_status() == "failed"):
					print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
					print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
				else:
					print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Create broadcast domains
	print("--- " + cluster["cluster-name"] + ": Creating broadcast domains...")
	for bcdomain in cluster["net-port-broadcast-domains"]:
		print("   --- " + cluster["cluster-name"] + ": Creating broadcast domain " + bcdomain["broadcast-domain"])
		zapi_post = NaElement("net-port-broadcast-domain-create")
		for k, v in bcdomain.items():
			zapi_post.child_add_string(k, v)
		elementPorts = NaElement("ports")
		for node in cluster["cluster-nodes"]:
			for port in node["net-ports"]:
				if(port["ipspace"] != "Cluster") and \
					(port["port"] != "e0M") and \
					(bcdomain["broadcast-domain"] == port["broadcast-domain"]):
					print("   --- " + cluster["cluster-name"] + ": adding " + port["port"] + " on node " + node["node-name"])
					elementPorts.child_add_string("net-qualified-port-name", node["node-name"] + ":" + port["port"])
		if(len(elementPorts.children_get()) > 0):
			zapi_post.child_add(elementPorts)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Set options
	print("--- " + cluster["cluster-name"] + ": Setting options...")
	for k, v in cluster["options"].items():
		print("   --- " + cluster["cluster-name"] + ": modifying " + k)
		zapi_post = NaElement("options-modify-iter")
		elementAttributes = NaElement("attributes")
		elementAttributesInfo = NaElement("option-info")
		elementAttributesInfo.child_add_string("value", v)
		elementQuery = NaElement("query")
		elementQueryInfo = NaElement("option-info")
		elementQueryInfo.child_add_string("name", k)
		elementAttributes.child_add(elementAttributesInfo)
		elementQuery.child_add(elementQueryInfo)
		zapi_post.child_add(elementQuery)
		zapi_post.child_add(elementAttributes)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Set network options
	print("--- " + cluster["cluster-name"] + ": Setting network options...")
	zapi_post = NaElement("net-options-modify")
	elementNetOptions = NaElement("net-options")
	for option in cluster["net-options"]:
		print("   --- " + cluster["cluster-name"] + ": adding " + option)
		elementOption = NaElement(option)
		for k, v in cluster["net-options"][option].items():
			elementOption.child_add_string(k, v)
		elementNetOptions.child_add(elementOption)
	zapi_post.child_add(elementNetOptions)
	zapi_post_return = session.invoke_elem(zapi_post)
	if (zapi_post_return.results_status() == "failed"):
		print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
		print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
	else:
		print("   ---> " + cluster["cluster-name"] + ": SUCCESS")

	# STEP: Create DNS
	session.set_vserver(cluster["cluster-name"])
	print("--- " + cluster["cluster-name"] + ": Creating DNS...")
	zapi_post = NaElement("net-dns-create")
	elementDomains = NaElement("domains")
	for domain in cluster["net-dns"]["domains"]["string"]:
		elementDomains.child_add_string("string", domain)
	elementServers = NaElement("name-servers")
	for dnsserver in cluster["net-dns"]["name-servers"]["ip-address"]:
		elementServers.child_add_string("ip-address", dnsserver)
	zapi_post.child_add(elementDomains)
	zapi_post.child_add(elementServers)
	zapi_post_return = session.invoke_elem(zapi_post)
	if (zapi_post_return.results_status() == "failed"):
		print("---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
		print("---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
	else:
		print("---> " + cluster["cluster-name"] + ": SUCCESS")
	session.set_vserver("")
	
	# STEP: Create NTP
	print("--- " + cluster["cluster-name"] + ": Creating NTP...")
	for timeserver in cluster["ntp-servers"]:
		zapi_post = NaElement("ntp-server-create")
		for k, v in timeserver.items():
			zapi_post.child_add_string(k, v)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Set timezone
	print("--- " + cluster["cluster-name"] + ": Setting timezone...")
	zapi_post = NaElement("system-cli")
	elementArgs = NaElement("args")
	elementArgs.child_add_string("arg", "timezone " + cluster["timezone"])
	zapi_post.child_add_string("priv", "admin")
	zapi_post.child_add(elementArgs)
	zapi_post_return = session.invoke_elem(zapi_post)
	if (zapi_post_return.results_status() == "failed"):
		print("---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
		print("---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
	else:
		print("---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Create LIFs
	print("--- " + cluster["cluster-name"] + ": Creating LIFs...")
	for lif in cluster["net-interfaces"]:
		if(lif["role"] != "cluster-mgmt"):
			print("   --- " + cluster["cluster-name"] + ": Creating " + lif["interface-name"])
			zapi_post = NaElement("net-interface-create")
			for k, v in lif.items():
				zapi_post.child_add_string(k, v)
			zapi_post_return = session.invoke_elem(zapi_post)
			if (zapi_post_return.results_status() == "failed"):
				print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
				print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
			else:
				print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Install licenses
	print("--- " + cluster["cluster-name"] + ": Adding Licenses...")
	zapi_post = NaElement("license-v2-add")
	elementCodes = NaElement("codes")
	for k, v in cluster["licenses"].items():
		print("   --- " + cluster["cluster-name"] + ": Adding " + k)
		elementCodes.child_add_string("license-code-v2", v)
	zapi_post.child_add(elementCodes)
	zapi_post_return = session.invoke_elem(zapi_post)
	if (zapi_post_return.results_status() == "failed"):
		print("---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
		print("---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
	else:
		print("---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Create subnets
	print("--- " + cluster["cluster-name"] + ": Creating subnets...")
	for subnet in cluster["net-subnets"]:
		print("   --- Creating subnet " + subnet["subnet-name"])
		zapi_post = NaElement("net-subnet-create")
		elementIPRanges = NaElement("ip-ranges")
		for k, v in subnet.items():
			if(k == "ip-ranges"):
				for range in v["ip-range"]:
					elementIPRanges.child_add_string("ip-range", range)
			else:
				zapi_post.child_add_string(k, v)
		zapi_post.child_add(elementIPRanges)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Create aggrs
	print("--- " + cluster["cluster-name"] + ": Creating aggregates...")
	for node in cluster["cluster-nodes"]:
		for aggregate in node["aggregates"]:
			print("   --- " + cluster["cluster-name"] + ": Creating aggregates " + aggregate["aggregate"])
			zapi_post = NaElement("aggr-create")
			elementNodes = NaElement("nodes")
			for k, v in aggregate.items():
				if(k == "nodes"):
					for nodename in v["node-name"]:
						if(nodename == ""):
							elementNodes.child_add_string("node-name", node["node-name"])
						else:
							elementNodes.child_add_string("node-name", nodename)
				else:
					zapi_post.child_add_string(k, v)
			zapi_post.child_add(elementNodes)
			zapi_post_return = session.invoke_elem(zapi_post)
			if (zapi_post_return.results_status() == "failed"):
				print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
				print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
			else:
				print("   ---> " + cluster["cluster-name"] + ": SUCCESS")

	#STEP: Disable ASUP
	print("--- " + cluster["cluster-name"] + ": Configuring Autosupport...")
	for node in cluster["cluster-nodes"]:
		print("   --- " + cluster["cluster-name"] + ": ASUP on node " + node["node-name"])
		zapi_post = NaElement("autosupport-config-modify")
		zapi_post.child_add_string("node-name", node["node-name"])
		for k, v in cluster["autosupport"].items():
			zapi_post.child_add_string(k, v)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("   ---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("   ---> " + cluster["cluster-name"] + ": SUCCESS")
	
	#STEP: Allow ssh access for user 'admin'
	print("--- " + cluster["cluster-name"] + ": Allowing admin ssh access...")
	zapi_post = NaElement("security-login-create")
	zapi_post.child_add_string("vserver", cluster["cluster-name"])
	zapi_post.child_add_string("user-name", "admin")
	zapi_post.child_add_string("application", "ssh")
	zapi_post.child_add_string("authentication-method", "password")
	zapi_post.child_add_string("role-name", "admin")
	zapi_post_return = session.invoke_elem(zapi_post)
	if (zapi_post_return.results_status() == "failed"):
		print("---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
		print("---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
	else:
		print("---> " + cluster["cluster-name"] + ": SUCCESS")
	
	# STEP: Set special options
	# NOTE: The session might be closed by the ONTAP, if the option value is really changed (interrupts HTTP(S) traffic)
	try:
		print("--- " + cluster["cluster-name"] + ": Enabling HTTP...")
		zapi_post = NaElement("system-cli")
		elementArgs = NaElement("args")
		elementArgs.child_add_string("arg", "system services web modify -http-enabled true")
		zapi_post.child_add_string("priv", "advanced")
		zapi_post.child_add(elementArgs)
		zapi_post_return = session.invoke_elem(zapi_post)
		if (zapi_post_return.results_status() == "failed"):
			print("---> " + cluster["cluster-name"] + ": " + zapi_post.sprintf().strip())
			print("---> " + cluster["cluster-name"] + ": " + zapi_post_return.sprintf().strip())
		else:
			print("---> " + cluster["cluster-name"] + ": SUCCESS")
	except:
		print("---> " + cluster["cluster-name"] + ": I have modified the branch I am currently sitting on... Session gone ;-)")
		print("---> " + cluster["cluster-name"] + ": Waiting for 10 seconds...")
		# making sure, cluster recovers from HTTP(S) modification
		time.sleep(10)
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)
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)