grokability / jamf2snipe

Import and sync assets from a JAMFPro instance to Snipe-IT asset management.
MIT License
113 stars 55 forks source link

Error 415 response attempting to update asset_tag in JAMF #99

Closed mcarras8 closed 1 year ago

mcarras8 commented 2 years ago

I've been getting 415 errors when attempting to update the asset_tag field in JAMF. When I look in JAMF the asset_tag field isn't actually updated. This occurs for every asset in Snipe-It that has a different (usually blank) asset_tag in JAMF. Any idea what's going on?

INFO:root:Snipe Record is newer than the JAMF record. Nothing to sync. If this wrong, then force an inventory update in JAMF
DEBUG:root:Not updating the Snipe asset because Snipe has a more recent timestamp: 2022-11-14 21:01:29 < 2022-11-15 00:01:02
INFO:root:JAMF doesn't have the same asset tag as SNIPE so we'll update it because it should be authoritative.
DEBUG:root:Making Get request against: https://myjamfinstance.jamfcloud.com//JSSResource/computers/id/59
Payload for the PUT request is: <?xml version="1.0" encoding="UTF-8"?><computer><general><id>59</id><asset_tag>2546</asset_tag></general></computer>
The username, password, and headers can be found near the beginning of the output.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myjamfinstance.jamfcloud.com:443
DEBUG:urllib3.connectionpool:https://myjamfinstance.jamfcloud.com:443 "PUT //JSSResource/computers/id/59 HTTP/1.1" 415 554
DEBUG:root:Going over snipe rate limit of 120/minute (1.9528952589232917/minute), sleeping for 0.5028952589232918
DEBUG:root:Made 114 requests to Snipe IT in 58.3748664855957 seconds, with a request being sent every 1.9528952589232917 seconds
WARNING:root:Got back an error response code:415 - b'<html>\n<head>\n   <title>Status page</title>\n</head>\n<body style="font-family: sans-serif;">\n<p style="font-size: 1.2em;font-weight: bold;margin: 1em 0px;">Unsupported Media Type</p>\n<p>The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method</p>\n<p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16">here</a>.<br>\nPlease continue your visit at our <a href="/">home page</a>.\n</p>\n</body>\n</html>\n'
ParadoxGuitarist commented 2 years ago

Just double checking.... did you edit this line? DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myjamfinstance.jamfcloud.com:443

mcarras8 commented 2 years ago

Just double checking.... did you edit this line? DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myjamfinstance.jamfcloud.com:443

Yes, our JAMF instance is not actually called "myjamfinstance". That's the only edit.

ParadoxGuitarist commented 2 years ago

Just double checking. :)

Is there a trailing / in your config file? Just trying to figure out https://myjamfinstance.jamfcloud.com//JSSReso[...]

mcarras8 commented 2 years ago

Aha! I totally missed that. Fixed the trailing slash, did another sync, and same problem:

INFO:root:Snipe Record is newer than the JAMF record. Nothing to sync. If this wrong, then force an inventory update in JAMF
DEBUG:root:Not updating the Snipe asset because Snipe has a more recent timestamp: 2022-11-14 21:01:29 < 2022-11-21 15:56:35
INFO:root:JAMF doesn't have the same asset tag as SNIPE so we'll update it because it should be authoritative.
DEBUG:root:Making Get request against: https://myjamfinstance.jamfcloud.com/JSSResource/computers/id/59
Payload for the PUT request is: <?xml version="1.0" encoding="UTF-8"?><computer><general><id>59</id><asset_tag>2546</asset_tag></general></computer>
The username, password, and headers can be found near the beginning of the output.
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): myjamfinstance.jamfcloud.com:443
DEBUG:urllib3.connectionpool:https://myjamfinstance.jamfcloud.com:443 "PUT /JSSResource/computers/id/59 HTTP/1.1" 415 554
DEBUG:root:Made 114 requests to Snipe IT in 58.55422306060791 seconds, with a request being sent every 1.9469133743265905 seconds
WARNING:root:Got back an error response code:415 - b'<html>\n<head>\n   <title>Status page</title>\n</head>\n<body style="font-family: sans-serif;">\n<p style="font-size: 1.2em;font-weight: bold;margin: 1em 0px;">Unsupported Media Type</p>\n<p>The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method</p>\n<p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16">here</a>.<br>\nPlease continue your visit at our <a href="/">home page</a>.\n</p>\n</body>\n</html>\n'

Oddly, I wasn't getting a 404 like #94, and syncing to Snipe-It has been working OK.

ParadoxGuitarist commented 2 years ago

Hm. I'm not sure if I'll have extra time to dig into this one today, but at least it's a starting place. I thought the --debug flag would also dump the payload data in byte format , but that doesn't seem to be the case from the logs you sent.

ParadoxGuitarist commented 2 years ago

Ah.... I know what's wrong... update_jamf_asset_tag calls with jamfheaders... which is says 'Content-Type':'application/json' but the payload is xml.

This needs to be reworked to have separate (or edited) headers for the other content type.

mcarras8 commented 2 years ago

Ah.... I know what's wrong... update_jamf_asset_tag calls with jamfheaders... which is says 'Content-Type':'application/json' but the payload is xml.

This needs to be reworked to have separate (or edited) headers for the other content type.

Ah! Yep, that seems to have been it. After I added a new global with 'Content-Type':'application/xml' and replaced the reference to jamfheaders in update_jamf_asset_tag and update_jamf_mobiledevice_asset_tag the asset tags updated successfully in JAMF.

(By the way, I think these functions could be merged with an additional parameter specifying which payload to use, but that's a different discussion).

ParadoxGuitarist commented 2 years ago

(By the way, I think these functions could be merged with an additional parameter specifying which payload to use, but that's a different discussion).

I agree, I'm glad that it got you up and working again, but I suspect we'll need to figure out a more elegant way of patching it for everyone else.

killer23d commented 1 year ago

Monitoring this as we want to populate JAMF asset tag records via Snipe but it is not working for me as well.

mcarasso-sts commented 1 year ago

@mcarras8 can you provide more detail how you patched this for your environment?

hofftaylor commented 1 year ago

@mcarasso-sts @killer23d I gave it a shot myself inferring from @mcarras8's feedback and managed to get it working. You have to edit the jamf2snipe file in the following places: Insert global jamfxmlheaders at line 200 (below jamfheaders) Insert jamfxmlheaders = {'Authorization': 'Bearer {}'.format(jsonresponse['token']),'Accept': 'application/xml','Content-Type':'application/xml'} at line 227 (below jamfheaders) Change headers=jamfheaders to headers=jamfxmlheaders at line 401 (the response portion of the update_jamf_asset_tag function) Change headers=jamfheaders to headers=jamfxmlheaders at line 424 (the response portion of the update_jamf_mobiledevice_asset_tag function)

The script then runs as expected, but like @mcarras8 mentioned, there's probably a better way to handle this that the author will implement someday. Hope this helps get you going!

mcarasso-sts commented 1 year ago

This worked as expected. Thank you

uberbrady commented 1 year ago

For any of those who are still running in to this issue, please do check out the PR I wrote above. I think it does what it's supposed to but I'd much rather have some folks testing it to see if it does the trick.