grokability / jamf2snipe

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

Mapping extension attribute to username for checkout_snipe_asset function? #44

Closed graffaelli closed 4 years ago

graffaelli commented 4 years ago

Your script is running great to import assets from Jamf to Snipe and I am able to get User assignment synced as well but I'm getting strange results. The result is that if a username is not populated in Jamf, there is a default user that just gets assigned the app in Snipe-IT. So there is one user that looks to have 100+ assets assigned.

I went looking further into Jamf and the person that set it up created an extension attribute that logs the last logged in user.

Is it possible to use an extension attribute instead of the Jamf username?

I tried to set this in the settings.conf [user-mapping] section [user-mapping] jamf_api_field = extension_attributes 5

When I did, I got this error in the verbose output: File "./jamf2snipe", line 655, in <module> checkout_snipe_asset(jamf['{}'.format(jamfsplit[0])]['{}'.format(jamfsplit[1])], snipe_id, snipe['rows'][0]['assigned_to']) TypeError: list indices must be integers or slices, not str

Hoping that there's a way to get it working. Let me know.

Thanks!

ParadoxGuitarist commented 4 years ago

Just to be clear, you're not actually using a line called: [user-mapping] jamf_api_field = extension_attributes 5 but you're line is using: jamf_api_field = extension_attributes 5 and jamf_api_field = general username is working fine right?

Can you provide a sanitized version of the JSON structure that JAMF returns on an item lookup?

ParadoxGuitarist commented 4 years ago

Actually, Looking at the examples from https://developer.jamf.com/#/computers/findComputersById Here's the relevant section on Extension attributes:

  "extension_attributes": [
    {
      "extension_attribute": {
        "id": 1,
        "name": "Battery Cycle Count",
        "type": "String",
        "value": 191
      }
    }

So let's say you needed the value of 191, The code would actually need to loop through all of the objects in extension_attributes find the one where id matches jamfsplit[1] (5 in your example) and then grab asset.value

We do this in the api mapping here: https://github.com/ParadoxGuitarist/jamf2snipe/blob/689a4e2045a1f5686513a4e14937dfeb7fd960f3/jamf2snipe#L695

https://github.com/ParadoxGuitarist/jamf2snipe/blob/689a4e2045a1f5686513a4e14937dfeb7fd960f3/jamf2snipe#L734 would need to be updated to do something similar.

I'm not sure when I'm going to have time to work on this, but you're welcome make something

We could also turn this into a function where it would split and parse the payload and return the propper value like


jamf_payload_split(Jamf_computer_payload_object, settings_Item_to_be_split)
jamfsplit = settings_Item_to_be_split.split()
for i, item in enumerate(jamfsplit):
  try:
    item = int(item)
    except ValueError:
    logging.debug('{} is not an integer'.format(item))
    if i == 0:
      jamf_value = Jamf_computer_payload_object[item]
    else:
      if jamfsplit[0] == 'extension_attributes':
        for attribute in jamf_value:
          if attribute['id'] == item:
            return attribute['value']
          else:
            return jamf_value[item] ```
graffaelli commented 4 years ago

Thanks for getting back to me on this. For now, I'm just going to use a script to update the username field in Jamf with the last logged in user at checkin. That should work fine for now. That said, this may be handy to have in the back pocket anyway.