diff --git a/.gitignore b/.gitignore index a9d73c8..304a0c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -settings.conf \ No newline at end of file +settings.conf diff --git a/README.md b/README.md index 5175b3d..2c27582 100755 --- a/README.md +++ b/README.md @@ -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: @@ -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. diff --git a/jamf2snipe b/jamf2snipe index 03c9912..a552445 100755 --- a/jamf2snipe +++ b/jamf2snipe @@ -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() @@ -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): @@ -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 @@ -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)) @@ -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: @@ -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") diff --git a/settings.conf b/settings.conf.example similarity index 62% rename from settings.conf rename to settings.conf.example index 5a0ce68..1aa67be 100644 --- a/settings.conf +++ b/settings.conf.example @@ -4,17 +4,17 @@ 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 @@ -22,8 +22,8 @@ _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 \ No newline at end of file +jamf_api_field = location username