Comments (16)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Same issue. You need to change line 60 from resource = ExportClient(exportPolicyID, exportRuleIndex)
to resource = ExportClient(str(exportPolicyID), str(exportRuleIndex))
from ontap-rest-python.
Any update on if this has been fixed in any version yet?
from ontap-rest-python.
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.
Great, any idea if this would work n-2. Our system is still on 9.8
from ontap-rest-python.
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.
Cleaning up stale issues
from ontap-rest-python.
Related Issues (20)
- Sample scripts not working in python3.9 (AttributeError: module 'base64' has no attribute 'encodestring') HOT 1
- Snapmirror relationship HOT 3
- how to upload file to ontap9.8 s3 HOT 2
- How can I list top 5 paths that a specific user consumes most for data storage? HOT 3
- Python list_snapshots.py KeyError: 'records' HOT 3
- ImportError: cannot import name 'Argument' from 'utils' when running HOT 6
- Just continuing testing more sample scripts...some obstacles. HOT 2
- module 'base64' has no attribute 'encodestring' when running svm_operations.py HOT 3
- 'failed to set field "ip_interfaces[0].location.broadcast_domain.name" to "Default_ckjfbvsnkfdjasbdkfsndlfe_cbekjrvckujeakbxjwc"' HOT 7
- Python script for creating vserver cifs is missing some inputs? HOT 1
- apache_scraper.py - add caller IP and user to report HOT 2
- issue with 9.8 Rest API when trying to configure SP IP address HOT 3
- Getting a single LUN mapping HOT 3
- Size field not available in Snapshot HOT 2
- cifs/sessions api issues HOT 3
- QuotaReport from the python API takes a very (very) long time HOT 7
- Using FileInfo does not work. HOT 3
- Wheel build is broken in a clean Python environment HOT 2
- Unable to use LocalCifsGroupMembers HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ontap-rest-python.