Giter VIP home page Giter VIP logo

Comments (16)

github-actions avatar github-actions commented on September 3, 2024

Thank you for reporting an issue! If you haven't already joined our Slack community,
then we invite you to do so. This is a great place to get help and ask questions from our community.

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

I did some testing and was able to verify the same. I checked both 9.8 and 9.9.1 and the issue was as you described. I filed a bug
report for the team that owns the /api/storage/qtrees endpoint to look into the issue. As the team makes any updates, you'll be able
to track it here: https://mysupport.netapp.com/NOW/cgi-bin/bol?Type=Detail&Display=1424170 (note: it may take up to a day
for that link to become active)

In the meantime, as a workaround, you can change your code like this:

def getQtreeExportID(qtreeName):
    print("Getting QTree Export Policy ID")
    print("QTree Name: ", qtreeName)
    qTreeList = list(Qtree.get_collection(fields="export_policy"))
    for qTree in qTreeList:
        if(qTree.name == qtreeName):
            return ExportPolicy.find(name=qTree.export_policy.name).id

This change requires an extra API call to the /api/protocols/nfs/export-policies endpoint, but should serve as a temporary workaround.

from ontap-rest-python.

sweeneyben avatar sweeneyben commented on September 3, 2024

Robert, any ETA on when a patch with this is planned? We have this on multiple places, and have to make the decision to manually update all our code, or wait for the patch. This would be dependent on when you think it would be fixed by.

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

No, I don't have that information. There's not yet an ETA or decided patch release. I will ask the developers to update this thread when they make that decision.

from ontap-rest-python.

asish-prabhakar avatar asish-prabhakar commented on September 3, 2024

It might take a couple of months for the fix to be available in a patch, so please use the above mentioned workaround.

from ontap-rest-python.

sudodevnull avatar sudodevnull commented on September 3, 2024

I tried using the work around:
def getQtreeExportID(qtreeName): print("Getting QTree Export Policy ID") print("QTree Name: ", qtreeName) qTreeList = list(Qtree.get_collection(fields="export_policy")) for qTree in qTreeList: if(qTree.name == qtreeName): return ExportPolicy.find(name=qTree.export_policy.name).id

I'm using netapp-ontap==9.9.1
and I get this error:

Traceback (most recent call last): File "./mount_nfs_v2_workaround.py", line 136, in <module> main(sys.argv[1:]) File "./mount_nfs_v2_workaround.py", line 131, in main setExportPolicy(exportPolicyRootID, ipAddresses) File "./mount_nfs_v2_workaround.py", line 56, in setExportPolicy exportRule = list(ExportRule.get_collection(exportPolicyID)) File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 623, in _get_collection url = sample.get_collection_url(connection=connection) File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 582, in get_collection_url return "%s%s" % (self.get_connection().origin, self._location) File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 270, in __getattribute__ value = super().__getattribute__(name) File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 402, in _location raise NetAppRestError(message=msg, cause=exc) from None netapp_ontap.error.NetAppRestError: Could not compute the location of the ExportRule collection. Values for ['policy.id'] are required. Caused by TypeError('quote_from_bytes() expected bytes',)

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

You appear to be running into bug 1378458: http://support.netapp.com/NOW/cgi-bin/bol?Type=Detail&Display=1378458

To work around that, on line 56 of your mount_nfs_v2_workaround.py script, you can change list(ExportRule.get_collection(exportPolicyId)) to list(ExportRule.get_collection(str(exportPolicyId)))

from ontap-rest-python.

sudodevnull avatar sudodevnull commented on September 3, 2024

I tried that... no luck:

[root@i-0d03741cd10a2d9ce ~]# cat /root/mount.log
Script Starting
Getting Basic Auth Username and Password
Getting Volume Export Policy ID
Getting Volume Export Policy ID
Getting QTree Export Policy ID
QTree Name: dev-jenkins-oc
Getting ASG IPs
IP(s) that are being added
10.217.62.149,10.217.56.216
Updating Export Policy Client IPs
8589934594
Traceback (most recent call last):
File "./mount_nfs_v2_workaround.py", line 136, in
main(sys.argv[1:])
File "./mount_nfs_v2_workaround.py", line 131, in main
setExportPolicy(exportPolicyRootID, ipAddresses)
File "./mount_nfs_v2_workaround.py", line 56, in setExportPolicy
exportRule = list(ExportRule.get_collection(str(exportPolicyId)))
NameError: name 'exportPolicyId' is not defined
[root@i-0d03741cd10a2d9ce ~]#

Here is my script:

import json
import os
import boto3
from botocore.exceptions import ClientError
from netapp_ontap import config, HostConnection
from netapp_ontap.resources import Volume, ExportPolicy, ExportClient, ExportRule, Qtree
import sys, getopt

def establishConnection(region):
  print("Getting Basic Auth Username and Password")
  ssm = boto3.client('ssm', region_name=region)
  parameter = ssm.get_parameter(Name="/netapp/username")
  user=parameter['Parameter']['Value']
  parameter = ssm.get_parameter(Name="/netapp/password", WithDecryption=True)
  password=parameter['Parameter']['Value']
  return user, password

def getVolumeExportID(volName):
  print("Getting Volume Export Policy ID")
  volumesList = list(Volume.get_collection(fields="nas"))
  for volume in volumesList:
    if(volume.name == volName):
      return volume.nas.export_policy.id

def getQtreeExportID(qtreeName):
    print("Getting QTree Export Policy ID")
    print("QTree Name: ", qtreeName)
    qTreeList = list(Qtree.get_collection(fields="export_policy"))
    for qTree in qTreeList:
        if(qTree.name == qtreeName):
            return ExportPolicy.find(name=qTree.export_policy.name).id

def getAsgIps(region, asgName):
  print("Getting ASG IPs")
  asg_client = boto3.client('autoscaling', region_name=region)
  asg=asg_client.describe_auto_scaling_groups(AutoScalingGroupNames=[asgName])
  instanceIds = []
  for a in asg['AutoScalingGroups'][0]['Instances']:
    instanceIds.append(a['InstanceId'])

  ipAddresses = []
  ec2_client = boto3.client('ec2', region_name=region)
  instances=ec2_client.describe_instances(InstanceIds=instanceIds)
  for i in instances['Reservations']:
    ipAddresses.append(i['Instances'][0]['PrivateIpAddress'])
  ipAddressesAsString = ','.join(ipAddresses)
  print("IP(s) that are being added")
  print(ipAddressesAsString)
  return ipAddressesAsString


def setExportPolicy(exportPolicyID, ipAddresses):
  print("Updating Export Policy Client IPs")
  print(exportPolicyID)
  exportRule = list(ExportRule.get_collection(str(exportPolicyId)))
  exportRuleIndex = exportRule[0].index
  resource = ExportClient(exportPolicyID, exportRuleIndex)
  resource.match = ipAddresses
  resource.post()


def main(argv):
  try:
    opts, args = getopt.getopt(argv,"hb:r:v:a:n:q:",["baseurl=","region=","rootvolname=","volname=","asg=","qtreename=","help"])
  except getopt.GetoptError as error:
    print(error + '  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit(2)
  for opt, arg in opts:
    if opt in ("-h", "--help"):
      print('test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
      sys.exit()
    elif opt in ("-b", "--baseurl"):
      baseUrl = arg
    elif opt in ("-r", "--region"):
      region = arg
    elif opt in ("-n", "--rootvolname"):
      rootVolName = arg
    elif opt in ("-v", "--volname"):
      volName = arg
    elif opt in ("-a", "--asg"):
      asgName = arg
    elif opt in ("-q", "--qtreename"):
      qtreeName = arg

  try:
    region
  except NameError:
    print('Missing -r, --region.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    baseUrl
  except NameError:
    print('Missing -b --baseurl.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    rootVolName
  except NameError:
    print('Missing -n --rootvolname.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    volName
  except NameError:
    print('Missing -v --volname.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    asgName
  except NameError:
    print('Missing -a --asg.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    qtreeName
  except NameError:
    print('Missing -q --qtreename.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  print("Script Starting")

  user, password = establishConnection(region)
  os.environ["no_proxy"] = baseUrl
  with HostConnection(baseUrl, username=user, password=password, verify=False):
    exportPolicyRootID = getVolumeExportID(rootVolName)
    exportPolicyVolumeID = getVolumeExportID(volName)
    exportPolicyQtreeID = getQtreeExportID(qtreeName)
    ipAddresses = getAsgIps(region, asgName)
    setExportPolicy(exportPolicyRootID, ipAddresses)
    setExportPolicy(exportPolicyVolumeID, ipAddresses)
    setExportPolicy(exportPolicyQtreeID, ipAddresses)

if __name__ == "__main__":
  main(sys.argv[1:])

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

Sorry, I think my answer just had a typo. Your script has exportPolicyID in it, not exportPolicyId (the D should be capitalized).

from ontap-rest-python.

sudodevnull avatar sudodevnull commented on September 3, 2024

Hey no worries... here's the next error:

Traceback (most recent call last):
File "./mount_nfs_v2_workaround.py", line 136, in
main(sys.argv[1:])
File "./mount_nfs_v2_workaround.py", line 131, in main
setExportPolicy(exportPolicyRootID, ipAddresses)
File "./mount_nfs_v2_workaround.py", line 60, in setExportPolicy
resource.post()
File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resources/export_client.py", line 222, in post
poll_timeout=poll_timeout, **kwargs
File "/usr/local/lib/python3.6/site-packages/netapp_ontap/utils.py", line 51, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 987, in _post
url = "%s%s" % (self.get_connection().origin, self._location)
File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 270, in getattribute
value = super().getattribute(name)
File "/usr/local/lib/python3.6/site-packages/netapp_ontap/resource.py", line 402, in _location
raise NetAppRestError(message=msg, cause=exc) from None
netapp_ontap.error.NetAppRestError: Could not compute the location of the ExportClient collection. Values for ['policy.id', 'export_rule.index'] are required. Caused by TypeError('quote_from_bytes() expected bytes',)

And code:

import json
import os
import boto3
from botocore.exceptions import ClientError
from netapp_ontap import config, HostConnection
from netapp_ontap.resources import Volume, ExportPolicy, ExportClient, ExportRule, Qtree
import sys, getopt

def establishConnection(region):
  print("Getting Basic Auth Username and Password")
  ssm = boto3.client('ssm', region_name=region)
  parameter = ssm.get_parameter(Name="/netapp/username")
  user=parameter['Parameter']['Value']
  parameter = ssm.get_parameter(Name="/netapp/password", WithDecryption=True)
  password=parameter['Parameter']['Value']
  return user, password

def getVolumeExportID(volName):
  print("Getting Volume Export Policy ID")
  volumesList = list(Volume.get_collection(fields="nas"))
  for volume in volumesList:
    if(volume.name == volName):
      return volume.nas.export_policy.id

def getQtreeExportID(qtreeName):
    print("Getting QTree Export Policy ID")
    print("QTree Name: ", qtreeName)
    qTreeList = list(Qtree.get_collection(fields="export_policy"))
    for qTree in qTreeList:
        if(qTree.name == qtreeName):
            return ExportPolicy.find(name=qTree.export_policy.name).id

def getAsgIps(region, asgName):
  print("Getting ASG IPs")
  asg_client = boto3.client('autoscaling', region_name=region)
  asg=asg_client.describe_auto_scaling_groups(AutoScalingGroupNames=[asgName])
  instanceIds = []
  for a in asg['AutoScalingGroups'][0]['Instances']:
    instanceIds.append(a['InstanceId'])

  ipAddresses = []
  ec2_client = boto3.client('ec2', region_name=region)
  instances=ec2_client.describe_instances(InstanceIds=instanceIds)
  for i in instances['Reservations']:
    ipAddresses.append(i['Instances'][0]['PrivateIpAddress'])
  ipAddressesAsString = ','.join(ipAddresses)
  print("IP(s) that are being added")
  print(ipAddressesAsString)
  return ipAddressesAsString


def setExportPolicy(exportPolicyID, ipAddresses):
  print("Updating Export Policy Client IPs")
  print(exportPolicyID)
  exportRule = list(ExportRule.get_collection(str(exportPolicyID)))
  exportRuleIndex = exportRule[0].index
  resource = ExportClient(exportPolicyID, exportRuleIndex)
  resource.match = ipAddresses
  resource.post()


def main(argv):
  try:
    opts, args = getopt.getopt(argv,"hb:r:v:a:n:q:",["baseurl=","region=","rootvolname=","volname=","asg=","qtreename=","help"])
  except getopt.GetoptError as error:
    print(error + '  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit(2)
  for opt, arg in opts:
    if opt in ("-h", "--help"):
      print('test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
      sys.exit()
    elif opt in ("-b", "--baseurl"):
      baseUrl = arg
    elif opt in ("-r", "--region"):
      region = arg
    elif opt in ("-n", "--rootvolname"):
      rootVolName = arg
    elif opt in ("-v", "--volname"):
      volName = arg
    elif opt in ("-a", "--asg"):
      asgName = arg
    elif opt in ("-q", "--qtreename"):
      qtreeName = arg

  try:
    region
  except NameError:
    print('Missing -r, --region.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    baseUrl
  except NameError:
    print('Missing -b --baseurl.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    rootVolName
  except NameError:
    print('Missing -n --rootvolname.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    volName
  except NameError:
    print('Missing -v --volname.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    asgName
  except NameError:
    print('Missing -a --asg.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  try:
    qtreeName
  except NameError:
    print('Missing -q --qtreename.  test.py -b <baseurl> -r <region> -n <rootvolname> -v <volname> -a <autoscaling_group> -q <qtreename>')
    sys.exit()

  print("Script Starting")

  user, password = establishConnection(region)
  os.environ["no_proxy"] = baseUrl
  with HostConnection(baseUrl, username=user, password=password, verify=False):
    exportPolicyRootID = getVolumeExportID(rootVolName)
    exportPolicyVolumeID = getVolumeExportID(volName)
    exportPolicyQtreeID = getQtreeExportID(qtreeName)
    ipAddresses = getAsgIps(region, asgName)
    setExportPolicy(exportPolicyRootID, ipAddresses)
    setExportPolicy(exportPolicyVolumeID, ipAddresses)
    setExportPolicy(exportPolicyQtreeID, ipAddresses)

if __name__ == "__main__":
  main(sys.argv[1:])

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

Same issue. You need to change line 60 from resource = ExportClient(exportPolicyID, exportRuleIndex) to resource = ExportClient(str(exportPolicyID), str(exportRuleIndex))

from ontap-rest-python.

sweeneyben avatar sweeneyben commented on September 3, 2024

Any update on if this has been fixed in any version yet?

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

Yes, the mentioned bug was fixed. You'll want to grab version 9.10.1.0 of the library which was released in January: https://pypi.org/project/netapp-ontap/9.10.1.0/

from ontap-rest-python.

sweeneyben avatar sweeneyben commented on September 3, 2024

Great, any idea if this would work n-2. Our system is still on 9.8

from ontap-rest-python.

RobertBlackhart avatar RobertBlackhart commented on September 3, 2024

Yes, the library is backwards compatible with prior versions of ONTAP. This is because the REST API is itself backwards compatible. My recommendation would to always use the latest version of the library.

from ontap-rest-python.

noorbuchi avatar noorbuchi commented on September 3, 2024

Cleaning up stale issues

from ontap-rest-python.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.