Hello,
tl;dr
I'm trying to create a new storage object on a single node Proxmox box using Python 3 and the Proxmox API. When I try, it gives me a 401 No Ticket error. I am grabbing the CSRFPreventionToken, and the Ticket. I have tried passing them through to the API via the data section and via the headers section. It doesn't seem to like either of those. So I'm wondering if the token and ticket need to be passed some other way.
/tl;dr
I am working with the Proxmox API on Proxmox 6.2-10, and am using Python 3 with the requests module. I've got my get commands working as expected. Then, as I understand it, when doing a post, put, or delete, I need to use the CSRFPreventionToken and the Ticket that I got when authenticating with the API.
Here's the start:
A little ugly, but that's the result of a bunch of troubleshooting I had done. I'll get that cleaned up. But for now, it works. If I jump into pdb3 and print self.debug.content, I get this.
And to format that a little better,
Okay, so we see the CSRFPrevention token and the ticket. Great. Now let's jump ahead to the usage. Here's the work in pdb3.
What I'm not sure about is if I'm putting the token and ticket in the right spot. I've tried putting it in the headers section, because that works for get commands where just the token is needed. I've also tried adding the token and ticket to the data section. I have also tried adding the username to the headers and data sections, but to no avail. Everything I do results in 401 No Ticket.
Not sure if I'm using the API wrong, or just can't Python.
tl;dr
I'm trying to create a new storage object on a single node Proxmox box using Python 3 and the Proxmox API. When I try, it gives me a 401 No Ticket error. I am grabbing the CSRFPreventionToken, and the Ticket. I have tried passing them through to the API via the data section and via the headers section. It doesn't seem to like either of those. So I'm wondering if the token and ticket need to be passed some other way.
/tl;dr
I am working with the Proxmox API on Proxmox 6.2-10, and am using Python 3 with the requests module. I've got my get commands working as expected. Then, as I understand it, when doing a post, put, or delete, I need to use the CSRFPreventionToken and the Ticket that I got when authenticating with the API.
Here's the start:
Python:
self.proxsession = requests.Session()
self.debug = self.proxsession.post(url,data={"username": "{}".format(self.user_name), "realm": "{}".format(self.realm), "password": "{}".format(self.password)},verify=False)
Code:
b'{"data":{"CSRFPreventionToken":"5F4B6D6E:3yiC4dgr08WOz2iGYiRhfeoaqn8dYYHX9iK4ssOmjdg","username":"root@pam","cap":{"access":{"Permissions.Modify":1,"Group.Allocate":1,"User.Modify":1},"storage":{"Datastore.AllocateSpace":1,"Datastore.Audit":1,"Permissions.Modify":1,"Datastore.AllocateTemplate":1,"Datastore.Allocate":1},"sdn":{"SDN.Allocate":1,"Permissions.Modify":1,"SDN.Audit":1},"vms":{"VM.Snapshot":1,"VM.Backup":1,"VM.Console":1,"VM.Allocate":1,"VM.Config.CDROM":1,"Permissions.Modify":1,"VM.Config.Disk":1,"VM.PowerMgmt":1,"VM.Config.HWType":1,"VM.Monitor":1,"VM.Clone":1,"VM.Config.Options":1,"VM.Config.Cloudinit":1,"VM.Config.Network":1,"VM.Snapshot.Rollback":1,"VM.Config.Memory":1,"VM.Migrate":1,"VM.Config.CPU":1,"VM.Audit":1},"dc":{"SDN.Allocate":1,"Sys.Audit":1,"SDN.Audit":1},"nodes":{"Sys.PowerMgmt":1,"Sys.Syslog":1,"Permissions.Modify":1,"Sys.Audit":1,"Sys.Modify":1,"Sys.Console":1}},"ticket":"PVE:root@pam:5F4B6D6E::H9Bz6nPuOVeBRG03Cw/pfqXBvnpe9Xgkr7q8Y1TqfDwnwKBr0CcvkHa0CP3pE/hUZ9AekgMCHdzQB11w1W0En0gWZjFkX4veZ1fA6rpOVpg2ZW29YalqL1ZLktX57yr32v/Gb06lonF38q0/nUke0M1DPQOUX0QU68VJdHtM27M28QNaj2mr4fgGBN0yAqsY/SKXWNYbB9a8OTawevlxgkye7uz3Soy+NMxarUSkX16qX3PpSk8daK6zt9lgpvZxc6bggJ9tlWuqyKiDCN88vxnmlmsB5HZLDGo6KnpEfxhYyG3szU47dFgX/1P4yWAfysklpBzwSXWqWa+sGxBLTw=="}}'
And to format that a little better,
Code:
b'{
"data": {
"CSRFPreventionToken": "5F4B6D6E:3yiC4dgr08WOz2iGYiRhfeoaqn8dYYHX9iK4ssOmjdg",
"username": "root@pam",
"cap": {
"access": {
"Permissions.Modify": 1,
"Group.Allocate": 1,
"User.Modify": 1
},
"storage": {
"Datastore.AllocateSpace": 1,
"Datastore.Audit": 1,
"Permissions.Modify": 1,
"Datastore.AllocateTemplate": 1,
"Datastore.Allocate": 1
},
"sdn": {
"SDN.Allocate": 1,
"Permissions.Modify": 1,
"SDN.Audit": 1
},
"vms": {
"VM.Snapshot": 1,
"VM.Backup": 1,
"VM.Console": 1,
"VM.Allocate": 1,
"VM.Config.CDROM": 1,
"Permissions.Modify": 1,
"VM.Config.Disk": 1,
"VM.PowerMgmt": 1,
"VM.Config.HWType": 1,
"VM.Monitor": 1,
"VM.Clone": 1,
"VM.Config.Options": 1,
"VM.Config.Cloudinit": 1,
"VM.Config.Network": 1,
"VM.Snapshot.Rollback": 1,
"VM.Config.Memory": 1,
"VM.Migrate": 1,
"VM.Config.CPU": 1,
"VM.Audit": 1
},
"dc": {
"SDN.Allocate": 1,
"Sys.Audit": 1,
"SDN.Audit": 1
},
"nodes": {
"Sys.PowerMgmt": 1,
"Sys.Syslog": 1,
"Permissions.Modify": 1,
"Sys.Audit": 1,
"Sys.Modify": 1,
"Sys.Console": 1
}
},
"ticket": "PVE:root@pam:5F4B6D6E::H9Bz6nPuOVeBRG03Cw/pfqXBvnpe9Xgkr7q8Y1TqfDwnwKBr0CcvkHa0CP3pE/hUZ9AekgMCHdzQB11w1W0En0gWZjFkX4veZ1fA6rpOVpg2ZW29YalqL1ZLktX57yr32v/Gb06lonF38q0/nUke0M1DPQOUX0QU68VJdHtM27M28QNaj2mr4fgGBN0yAqsY/SKXWNYbB9a8OTawevlxgkye7uz3Soy+NMxarUSkX16qX3PpSk8daK6zt9lgpvZxc6bggJ9tlWuqyKiDCN88vxnmlmsB5HZLDGo6KnpEfxhYyG3szU47dFgX/1P4yWAfysklpBzwSXWqWa+sGxBLTw=="
}
}'
Okay, so we see the CSRFPrevention token and the ticket. Great. Now let's jump ahead to the usage. Here's the work in pdb3.
Code:
(Pdb) mytoken = json.loads(self.debug.content)["data"]["CSRFPreventionToken"]
(Pdb) print(mytoken)
5F4B6E21:XdRZNmVvnvX3hcmTpphFL8w9J3MXPuErkec1pChNtu0
(Pdb) myticket = json.loads(self.debug.content)["data"]["ticket"]
(Pdb) print(myticket)
PVE:root@pam:5F4B6E21::cDvOJXxf6cWj1yyt4yV1wWeEDmVOqOyx1jMw2E0nRXuPFT/NQj4vcc7lhDSrRD5LoPB867hsUhGmov53ZEsktWoR0kU6mPWKSGPGXUAnJ/Fy/zYTnj982+YvlJC5mf9bNWLuJVUl87RW2E1IywF69BurRbTaOcDpLrrf2jLDU631Snm6dSTOqEIaXTkJM46xdg9wR8QRGFwumKrPZ1Ur5CAcYxun6ezLqi/ZZwXgSHozzdppFE2fpkQUQAImqdv4+t+kysVCiGABs2PK90estmc5ZkFCB8FlVGp+KGFlFLMsy4+QRLA+ct9KMQ2pXYaULMEVy1R0dZ8amsbQI6xkbw==
(Pdb) print(url)
https://192.168.15.130:8006/api2/json/storage
(Pdb) print(data)
{'storage': 'Customer02', 'type': 'zfspool', 'sparse': 1, 'content': 'images'}
(Pdb) self.proxsession.post(url,data=data,headers={"CSRFPreventionToken": mytoken, "ticket": myticket},verify=False)
DEBUG:urllib3.connectionpool:Resetting dropped connection: 192.168.15.130
send: b'POST /api2/json/storage HTTP/1.1\r\nHost: 192.168.15.130:8006\r\nUser-Agent: python-requests/2.22.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nCSRFPreventionToken: 5F4B6E21:XdRZNmVvnvX3hcmTpphFL8w9J3MXPuErkec1pChNtu0\r\nticket: PVE:root@pam:5F4B6E21::cDvOJXxf6cWj1yyt4yV1wWeEDmVOqOyx1jMw2E0nRXuPFT/NQj4vcc7lhDSrRD5LoPB867hsUhGmov53ZEsktWoR0kU6mPWKSGPGXUAnJ/Fy/zYTnj982+YvlJC5mf9bNWLuJVUl87RW2E1IywF69BurRbTaOcDpLrrf2jLDU631Snm6dSTOqEIaXTkJM46xdg9wR8QRGFwumKrPZ1Ur5CAcYxun6ezLqi/ZZwXgSHozzdppFE2fpkQUQAImqdv4+t+kysVCiGABs2PK90estmc5ZkFCB8FlVGp+KGFlFLMsy4+QRLA+ct9KMQ2pXYaULMEVy1R0dZ8amsbQI6xkbw==\r\nContent-Length: 55\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n'
send: b'storage=Customer02&type=zfspool&sparse=1&content=images'
reply: 'HTTP/1.1 401 No ticket\r\n'
header: Cache-Control: max-age=0
header: Connection: close
header: Date: Sun, 30 Aug 2020 09:18:00 GMT
header: Pragma: no-cache
header: Server: pve-api-daemon/3.0
header: Expires: Sun, 30 Aug 2020 09:18:00 GMT
DEBUG:urllib3.connectionpool:https://192.168.15.130:8006 "POST /api2/json/storage HTTP/1.1" 401 None
<Response [401]>
What I'm not sure about is if I'm putting the token and ticket in the right spot. I've tried putting it in the headers section, because that works for get commands where just the token is needed. I've also tried adding the token and ticket to the data section. I have also tried adding the username to the headers and data sections, but to no avail. Everything I do results in 401 No Ticket.
Not sure if I'm using the API wrong, or just can't Python.