Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checkin assets with no assigned user #69

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
settings.conf
settings.conf
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ Lastly, if the asset_tag field is blank in JAMF when it is being created in Snip
4. Install dependencies
- `pip install -r /path/to/jamf2snipe/requirements.txt`

5. Configure settings.conf
5. Copy settings.conf.example to settings.conf and configure
6. Run `python jamf2snipe` & profit

### Linux

1. Copy the files to your system (recommend installing to /opt/jamf2snipe/* ). Make sure you meet all the system requirements.
2. Edit the settings.conf to match your current environment. The script will look for a valid settings.conf in /opt/jamf2snipe/settings.conf, /etc/jamf2snipe/settings.conf, or in the current folder (in that order): so either copy the file to one of those locations, or be sure that the user running the program is in the same folder as the settings.conf.
2. Copy settings.conf.example to settings.conf. Edit settings.conf to match your current environment. The script will look for a valid settings.conf in /opt/jamf2snipe/settings.conf, /etc/jamf2snipe/settings.conf, or in the current folder (in that order): so either copy the file to one of those locations, or be sure that the user running the program is in the same folder as the settings.conf.

## Configuration - settings.conf:

Expand Down Expand Up @@ -117,6 +117,16 @@ Some example API mappings can be found below:

More information can be found in the ./jamf2snipe file about associations and [valid subsets](https://github.com/ParadoxGuitarist/jamf2snipe/blob/master/jamf2snipe#L33).

### Environment variables

Config values can be set through environment variables, e.g.:
```
[jamf]
url = $JAMF_URL
username = $JAMF_USERNAME
password = $JAMF_PASSWORD
```

## Testing

It is *always* a good idea to create a test environment to ensure everything works as expected before running anything in production.
Expand Down
23 changes: 19 additions & 4 deletions jamf2snipe
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ import time
import configparser
import argparse
import logging
import os

class EnvironmentInterpolation(configparser.BasicInterpolation):
def before_get(self, parser, section, option, value, defaults):
value = super().before_get(parser, section, option, value, defaults)
return os.path.expandvars(value)

# Set us up for using runtime arguments by defining them.
runtimeargs = argparse.ArgumentParser()
Expand Down Expand Up @@ -86,7 +92,7 @@ if user_args.dryrun:

# Find a valid settings.conf file.
logging.info("Searching for a valid settings.conf file.")
config = configparser.ConfigParser()
config = configparser.ConfigParser(interpolation=EnvironmentInterpolation())
logging.debug("Checking for a settings.conf in /opt/jamf2snipe ...")
config.read("/opt/jamf2snipe/settings.conf")
if 'snipe-it' not in set(config):
Expand Down Expand Up @@ -444,6 +450,10 @@ def update_snipe_asset(snipe_id, payload):
logging.debug("Got back status code: 200 - Checking the payload updated properly: If you error here it's because you configure the API mapping right.")
jsonresponse = response.json()
for key in payload:
if key == 'purchase_date':
payload[key] = payload[key] + " 00:00:00"
if payload[key] is '':
payload[key] = None
if jsonresponse['payload'][key] != payload[key]:
logging.warning('Unable to update ID: {}. We failed to update the {} field with "{}"'.format(snipe_id, key, payload[key]))
goodupdate = False
Expand Down Expand Up @@ -472,6 +482,9 @@ def checkin_snipe_asset(asset_id):
# Function that checks out an asset in snipe
def checkout_snipe_asset(user, asset_id, checked_out_user=None):
logging.debug('Asset {} is being checked out to {}'.format(user, asset_id))
if user == '':
logging.info("Checking in {}".format(asset_id))
return checkin_snipe_asset(asset_id)
user_id = get_snipe_user_id(user)
if user_id == 'NotFound':
logging.info("User {} not found".format(user))
Expand Down Expand Up @@ -511,11 +524,13 @@ logging.info("SSL Verification is set to: {}".format(user_args.do_not_verify_ssl
logging.info("Running tests to see if hosts are up.")
try:
SNIPE_UP = True if requests.get(snipe_base, verify=user_args.do_not_verify_ssl, hooks={'response': request_handler}).status_code is 200 else False
except:
except Exception as e:
logging.exception(e)
SNIPE_UP = False
try:
JAMF_UP = True if requests.get(jamfpro_base, verify=user_args.do_not_verify_ssl, hooks={'response': request_handler}).status_code in (200, 401) else False
except:
except Exception as e:
logging.exception(e)
JAMF_UP = False

if SNIPE_UP is False:
Expand Down Expand Up @@ -747,7 +762,7 @@ for jamf_type in jamf_types:
# The user arg below is set to false if it's called, so this would fail if the user called it.
if (jamf['general']['asset_tag'] != snipe['rows'][0]['asset_tag']) and user_args.do_not_update_jamf :
logging.info("JAMF doesn't have the same asset tag as SNIPE so we'll update it because it should be authoritative.")
if snipe['rows'][0]['asset_tag'][0].isdigit():
if snipe['rows'][0]['asset_tag'][0]:
if jamf_type == 'computers':
update_jamf_asset_tag("{}".format(jamf['general']['id']), '{}'.format(snipe['rows'][0]['asset_tag']))
logging.info("Device is a computer, updating computer record")
Expand Down
16 changes: 8 additions & 8 deletions settings.conf → settings.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ username = a-valid-username
password = a-valid-password

[snipe-it]
#Required
# Required
url = http://FQDN.your.snipe.instance.com
apikey = YOUR-API-KEY-HERE
manufacturer_id = 2
defaultStatus = 2
defaultStatus = 2
computer_model_category_id = 2
mobile_model_category_id = 3
#Not Required, uncomment to use
#computer_custom_fieldset_id = 3
#mobile_custom_fieldset_id = 4
#asset_tag = general serial_number # If not specified, defaults to jamf-{id} or jamf-m-{id}
# Not Required, uncomment to use
# computer_custom_fieldset_id = 3
# mobile_custom_fieldset_id = 4
# asset_tag = general serial_number # If not specified, defaults to jamf-{id} or jamf-m-{id}

[computers-api-mapping]
name = general name
_snipeit_mac_address_1 = general mac_address


[mobile_devices-api-mapping]
_snipeit_imei_4 = network imei
_snipeit_imei_4 = network imei
name = general name

[user-mapping] # The field from jamf that you want to search Snipe with
jamf_api_field = location username
jamf_api_field = location username