You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Set us up for using runtime arguments by defining them.
57
60
runtimeargs=argparse.ArgumentParser()
@@ -61,8 +64,9 @@ runtimeargs.add_argument("--dryrun", help="This checks your config and tries to
61
64
runtimeargs.add_argument("-d", "--debug", help="Sets logging to include additional DEBUG messages.", action="store_true")
62
65
runtimeargs.add_argument("--do_not_update_jamf", help="Does not update Jamf with the asset tags stored in Snipe.", action="store_false")
63
66
runtimeargs.add_argument('--do_not_verify_ssl', help="Skips SSL verification for all requests. Helpful when you use self-signed certificate.", action="store_false")
64
-
runtimeargs.add_argument("-r", "--ratelimited", help="Puts a half second delay between Snipe IT API calls to adhere to the standard 120/minute rate limit", action="store_true")
67
+
runtimeargs.add_argument("-r", "--ratelimited", help="Puts a half second delay between API calls to adhere to the standard 120/minute rate limit", action="store_true")
65
68
runtimeargs.add_argument("-f", "--force", help="Updates the Snipe asset with information from Jamf every time, despite what the timestamps indicate.", action="store_true")
69
+
runtimeargs.add_argument("--version", help="Prints the version and exits.", action="store_true")
user_opts.add_argument("-u", "--users", help="Checks out the item to the current user in Jamf if it's not already deployed", action="store_true")
68
72
user_opts.add_argument("-ui", "--users_inverse", help="Checks out the item to the current user in Jamf if it's already deployed", action="store_true")
@@ -73,6 +77,10 @@ type_opts.add_argument("-m", "--mobiles", help="Runs against the Jamf mobiles en
73
77
type_opts.add_argument("-c", "--computers", help="Runs against the Jamf computers endpoint only.", action="store_true")
74
78
user_args=runtimeargs.parse_args()
75
79
80
+
ifuser_args.version:
81
+
print(version)
82
+
raiseSystemExit
83
+
76
84
# Notify users they're going to get a wall of text in verbose mode.
77
85
ifuser_args.verbose:
78
86
logging.basicConfig(level=logging.INFO)
@@ -101,31 +109,44 @@ if 'snipe-it' not in set(config):
101
109
logging.error("No valid settings.conf was found. We'll need to quit while you figure out where the settings are at. You can check the README for valid locations.")
102
110
raiseSystemExit("Error: No valid settings.conf - Exiting.")
103
111
104
-
logging.info("Great, we found a settings file. Let's get started by parsing all fo the settings.")
105
-
106
-
# Set some Variables from the settings.conf:
107
-
# This is the address, cname, or FQDN for your JamfPro instance.
108
-
jamfpro_base=config['jamf']['url']
109
-
logging.info("The configured JAMFPro base url is: {}".format(jamfpro_base))
110
-
jamf_apiKey=config['jamf']['apikey']
111
-
logging.debug("The API key you provided for Jamf is: {}".format(jamf_apiKey))
112
-
113
-
# This is the address, cname, or FQDN for your snipe-it instance.
114
-
snipe_base=config['snipe-it']['url']
115
-
logging.info("The configured Snipe-IT base url is: {}".format(snipe_base))
116
-
snipe_apiKey=config['snipe-it']['apikey']
117
-
logging.debug("The API key you provided for Snipe is: {}".format(snipe_apiKey))
118
-
defaultStatus=config['snipe-it']['defaultStatus']
119
-
logging.info("The default status we'll be setting updated computer to is: {} (I sure hope this is a number or something is probably wrong)".format(defaultStatus))
logging.debug('Request headers for JamfPro will be: {}\nRequest headers for Snipe will be: {}'.format(jamfheaders, snipeheaders))
114
+
# While setting the variables, use a try loop so we can raise a error if something goes wrong.
115
+
try:
116
+
# Set some Variables from the settings.conf:
117
+
# This is the address, cname, or FQDN for your JamfPro instance.
118
+
logging.info("Setting the Jamf Pro Base url.")
119
+
jamfpro_base=config['jamf']['url']
120
+
logging.debug("The configured Jamf Pro base url is: {}".format(jamfpro_base))
121
+
122
+
logging.info("Setting the username to request an api key.")
123
+
jamf_user=config['jamf']['username']
124
+
logging.debug("The user you provided for Jamf is: {}".format(jamf_user))
125
+
126
+
logging.info("Setting the password to request an api key.")
127
+
jamf_password=config['jamf']['password']
128
+
logging.debug("The password you provided for Jamf is: {}".format(jamf_user))
129
+
130
+
# This is the address, cname, or FQDN for your snipe-it instance.
131
+
logging.info("Setting the base URL for SnipeIT.")
132
+
snipe_base=config['snipe-it']['url']
133
+
logging.debug("The configured Snipe-IT base url is: {}".format(snipe_base))
134
+
135
+
logging.info("Setting the API key for SnipeIT.")
136
+
snipe_apiKey=config['snipe-it']['apikey']
137
+
logging.debug("The API key you provided for Snipe is: {}".format(snipe_apiKey))
138
+
139
+
logging.info("Setting the default status for SnipeIT assets.")
140
+
defaultStatus=config['snipe-it']['defaultStatus']
141
+
logging.debug("The default status we'll be setting updated assets to is: {} (I sure hope this is a number or something is probably wrong)".format(defaultStatus))
142
+
143
+
logging.info("Setting the Snipe ID for Apple Manufacturer devices.")
logging.debug("The configured manufacturer ID for Apple computers in snipe is: {} (Pretty sure this needs to be a number too)".format(apple_manufacturer_id))
146
+
147
+
except:
148
+
logging.error("Some of the required settings from the settings.conf were missing or invalid. Re-run jamf2snipe with the --verbose or --debug flag to get more details on which setting is missing or misconfigured.")
149
+
raiseSystemExit("Error: Missing or invalid settings in settings.conf - Exiting.")
129
150
130
151
# Check the config file for correct headers
131
152
@@ -154,30 +175,84 @@ for key in config['computers-api-mapping']:
154
175
raiseSystemExit("Invalid Subset found in settings.conf")
155
176
156
177
### Setup Some Functions ###
157
-
snipe_api_count=0
158
-
first_snipe_call=None
159
-
# This function is run every time a request is made, handles rate limiting for Snipe IT.
178
+
api_count=0
179
+
first_api_call=None
180
+
181
+
# Headers for the API call.
182
+
logging.info("Creating the headers we'll need for API calls")
# If there's less than 5 minutes (300 seconds) left on the token, get a new one.
234
+
iftimeleft<datetime.timedelta(seconds=300):
235
+
request_jamf_token()
236
+
237
+
# Slow and steady wins the race. Limit all API calls (not just to snipe) to the Rate limit.
238
+
ifuser_args.ratelimited:
164
239
if'"messages":429'inr.text:
165
240
logging.warn("Despite respecting the rate limit of Snipe, we've still been limited. Trying again after sleeping for 2 seconds.")
166
241
time.sleep(2)
167
242
re_req=r.request
168
243
s=requests.Session()
169
244
returns.send(re_req)
170
-
ifsnipe_api_count==0:
171
-
first_snipe_call=time.time()
245
+
ifapi_count==0:
246
+
first_api_call=time.time()
172
247
time.sleep(0.5)
173
-
snipe_api_count+=1
174
-
time_elapsed= (time.time() -first_snipe_call)
175
-
snipe_api_rate=snipe_api_count/time_elapsed
176
-
ifsnipe_api_rate>1.95:
177
-
sleep_time=0.5+ (snipe_api_rate-1.95)
178
-
logging.debug('Going over snipe rate limit of 120/minute ({}/minute), sleeping for {}'.format(snipe_api_rate,sleep_time))
248
+
api_count+=1
249
+
time_elapsed= (time.time() -first_api_call)
250
+
api_rate=api_count/time_elapsed
251
+
ifapi_rate>1.95:
252
+
sleep_time=0.5+ (api_rate-1.95)
253
+
logging.debug('Going over snipe rate limit of 120/minute ({}/minute), sleeping for {}'.format(api_rate,sleep_time))
179
254
time.sleep(sleep_time)
180
-
logging.debug("Made {} requests to Snipe IT in {} seconds, with a request being sent every {} seconds".format(snipe_api_count, time_elapsed, snipe_api_rate))
255
+
logging.debug("Made {} requests to Snipe IT in {} seconds, with a request being sent every {} seconds".format(api_count, time_elapsed, api_rate))
181
256
if'"messages":429'inr.text:
182
257
logging.error(r.content)
183
258
raiseSystemExit("We've been rate limited. Use option -r to respect the built in Snipe IT API rate limit of 120/minute.")
logging.warning("The serial number is not available in JAMF. This is normal for DEP enrolled devices that have not yet checked in for the first time and for personal mobile devices. Since there's no serial number yet, we'll skip it for now.")
755
+
continue
756
+
ifjamf['general']['serial_number'] ==None:
757
+
logging.warning("The serial number is not available in JAMF. This is normal for DEP enrolled devices that have not yet checked in for the first time and for personal mobile devices. Since there's no serial number yet, we'll skip it for now.")
758
+
continue
759
+
676
760
# Check that the model number exists in snipe, if not create it.
logging.warning("The serial number is not available in JAMF. This is normal for DEP enrolled devices that have not yet checked in for the first time. Since there's no serial number yet, we'll skip it for now.")
0 commit comments