def main(): """Do the main thing here""" print("\n** Jamf package upload script") print("** Uploads packages to Jamf Cloud or SMB Distribution Points.") # parse the command line arguments args = get_args() # grab values from a prefs file if supplied jamf_url, jamf_user, jamf_password, enc_creds = api_connect.get_creds_from_args( args) if args.prefs: smb_url, smb_user, smb_password = api_connect.get_smb_credentials( args.prefs) else: smb_url = "" smb_user = "" smb_password = "" # repeat for optional SMB share (but must supply a share path to invoke this) if args.share: smb_url = args.share if smb_url: if args.shareuser: smb_user = args.shareuser elif not smb_user: smb_user = input( "Enter a user with read/write permissions to {} : ".format( smb_url)) if args.sharepass: smb_password = args.sharepass elif not smb_password: smb_password = getpass.getpass( "Enter the password for '{}' : ".format(smb_user)) # get HTTP request timeout r_timeout = float(args.timeout) if not args.pkg: pkg = input("Enter the full path to the package to upload: ") args.pkg = pkg # establish a web login session which is reusable for scraping tokens if args.direct: r, login_session = login(jamf_url, jamf_user, jamf_password, args.verbose) if r.status_code != 200: print("Failed to log in to the Jamf instance at: {}".format( jamf_url)) # get the id for a category if supplied if args.category: print("Checking ID for {}".format(args.category)) category_id = api_get.get_uapi_obj_id_from_name( jamf_url, enc_creds, args.category, args.verbose, "categories") if not category_id: print("WARNING: Category not found!") category_id = "-1" # now process the list of packages for pkg_path in args.pkg: pkg_name = os.path.basename(pkg_path) # See if the package is non-flat (requires zipping prior to upload). if os.path.isdir(pkg_path): pkg_path = zip_pkg_path(pkg_path) pkg_name += ".zip" # check for existing package print("\nChecking '{}' on {}".format(pkg_name, jamf_url)) if args.verbose: print("Full path: {}".format(pkg_path)) replace_pkg = True if args.replace else False obj_id = check_pkg(pkg_name, jamf_url, enc_creds) # post the package (won't run if the pkg exists and replace_pkg is False) # process for SMB shares if defined if smb_url: # mount the share mount_smb(smb_url, smb_user, smb_password, args.verbose) # check for existing package local_pkg = check_local_pkg(args.share, pkg_name, args.verbose) if not local_pkg or replace_pkg: # copy the file copy_pkg(smb_url, pkg_path, pkg_name) # unmount the share umount_smb(smb_url) # otherwise process for cloud DP else: if obj_id == "-1" or replace_pkg: # JCDS direct upload method option if args.direct: jcds_url, jcds_token, session_token = scrape_upload_token( login_session, jamf_url, args.verbose) if jcds_url and jcds_token and session_token: if args.verbose: print("JCDS URL: {}".format(jcds_url)) print("JCDS Upload token: {}".format(jcds_token)) print("Session token: {}".format(session_token)) # post the package as chunks post_pkg_chunks( pkg_name, pkg_path, jcds_url, jcds_token, obj_id, args.chunksize, args.verbose, ) # now create the package object and get the pkg ID pkg_id = update_pkg_by_form( login_session, session_token, jamf_url, pkg_name, pkg_path, obj_id, category_id, args.verbose, ) # curl -> dbfileupload upload method option elif args.curl: r = curl_pkg( pkg_name, pkg_path, jamf_url, enc_creds, obj_id, r_timeout, args.verbose, ) try: pkg_id = ElementTree.fromstring(r).findtext("id") if pkg_id: print("\nPackage uploaded successfully, ID={}". format(pkg_id)) except ElementTree.ParseError: print("Could not parse XML. Raw output:") print(r.decode("ascii")) else: if args.verbose: if r: print("\nResponse:\n") print(r.decode("ascii")) else: print("No HTTP response") # requests -> dbfileupload upload method option else: r = post_pkg( pkg_name, pkg_path, jamf_url, enc_creds, obj_id, r_timeout, args.verbose, ) # print result of the request if r.status_code == 200 or r.status_code == 201: pkg_id = ElementTree.fromstring(r.text).findtext("id") print("\nPackage uploaded successfully, ID={}".format( pkg_id)) if args.verbose: print("HTTP POST Response Code: {}".format( r.status_code)) else: print("\nHTTP POST Response Code: {}".format( r.status_code)) if args.verbose: api_get.get_headers(r) # now process the package metadata if a category is supplied, # or if we are dealing with an SMB share if (args.category or smb_url) and not args.direct: try: pkg_id update_pkg_metadata(jamf_url, enc_creds, pkg_name, args.category, args.verbose, pkg_id) except UnboundLocalError: update_pkg_metadata(jamf_url, enc_creds, pkg_name, args.category, args.verbose) print()
def main(): """Do the main thing here""" print("\n** Jamf package upload script") print("** Uploads packages to Jamf Cloud or SMB Distribution Points.") # parse the command line arguments args = get_args() verbosity = args.verbose # create a dictionary of package metadata from the args pkg_metadata = { "category": args.category, "info": args.info, "notes": args.notes, "reboot_required": args.reboot_required, "priority": args.priority, "os_requirement": args.os_requirement, "required_processor": args.required_processor, "send_notification": args.send_notification, } # grab values from a prefs file if supplied ( jamf_url, jamf_user, jamf_password, slack_webhook, enc_creds, ) = api_connect.get_creds_from_args(args) if args.prefs: smb_url, smb_user, smb_pass = api_connect.get_smb_credentials( args.prefs) else: smb_url = "" smb_user = "" smb_pass = "" # repeat for optional SMB share (but must supply a share path to invoke this) if args.smb_url: smb_url = args.smb_url if args.smb_user: smb_user = args.smb_user if not smb_user: smb_user = input( "Enter a user with read/write permissions to {} : ".format( smb_url)) if args.smb_pass: smb_pass = args.smb_pass if not smb_pass: if not smb_pass: smb_pass = getpass.getpass( "Enter the password for '{}' : ".format(smb_user)) # get HTTP request timeout r_timeout = float(args.timeout) if not args.pkg: pkg = input("Enter the full path to the package to upload: ") args.pkg = pkg # establish a web login session which is reusable for scraping tokens if args.direct: r, login_session = login(jamf_url, jamf_user, jamf_password, verbosity) if r.status_code != 200: print("Failed to log in to the Jamf instance at: {}".format( jamf_url)) # get the id for a category if supplied if args.category: print("Checking ID for category '{}'".format(args.category)) # now get the session token token = api_connect.get_uapi_token(jamf_url, enc_creds, verbosity) category_id = api_get.get_uapi_obj_id_from_name( jamf_url, "categories", args.category, token, verbosity) if not category_id: print("WARNING: Category not found!") category_id = "-1" # add to the pkg_metadata dictionary pkg_metadata["category_id"] = category_id # now process the list of packages for pkg_path in args.pkg: pkg_name = os.path.basename(pkg_path) # See if the package is non-flat (requires zipping prior to upload). if os.path.isdir(pkg_path): pkg_path = zip_pkg_path(pkg_path) pkg_name += ".zip" # calculate the SHA-512 hash of the package sha512string = sha512sum(pkg_path) # check for existing package print("\nChecking '{}' on {}".format(pkg_name, jamf_url)) if verbosity: print("Full path: {}".format(pkg_path)) replace_pkg = True if args.replace else False obj_id = check_pkg(pkg_name, jamf_url, enc_creds, verbosity) if obj_id != "-1": print("Package '{}' already exists: ID {}".format( pkg_name, obj_id)) pkg_id = obj_id # assign pkg_id for smb runs - JCDS runs get it from the pkg upload else: pkg_id = "" # post the package (won't run if the pkg exists and replace_pkg is False) # process for SMB shares if defined if args.smb_url: # mount the share smb_actions.mount_smb(args.smb_url, args.smb_user, args.smb_pass, verbosity) # check for existing package local_pkg = check_local_pkg(args.smb_url, pkg_name, verbosity) if not local_pkg or replace_pkg: # copy the file smb_actions.copy_pkg(args.smb_url, pkg_path, pkg_name) # unmount the share smb_actions.umount_smb(args.smb_url) # otherwise process for cloud DP else: if obj_id == "-1" or replace_pkg: # JCDS direct upload method option if args.direct: jcds_url, jcds_token, session_token = scrape_upload_token( login_session, jamf_url, verbosity) if jcds_url and jcds_token and session_token: if verbosity: print("JCDS URL: {}".format(jcds_url)) print("JCDS Upload token: {}".format(jcds_token)) print("Session token: {}".format(session_token)) # post the package as chunks post_pkg_chunks( pkg_name, pkg_path, jcds_url, jcds_token, obj_id, args.chunksize, verbosity, ) # now create the package object and get the pkg ID pkg_id = update_pkg_by_form( login_session, session_token, jamf_url, pkg_name, pkg_path, obj_id, pkg_metadata, verbosity, ) # curl -> dbfileupload upload method option elif args.nscurl: r = nscurl_pkg( pkg_name, pkg_path, jamf_url, enc_creds, obj_id, r_timeout, verbosity, ) try: pkg_id = ElementTree.fromstring(r).findtext("id") if pkg_id: print("\nPackage uploaded successfully, ID={}". format(pkg_id)) except ElementTree.ParseError: print("Could not parse XML. Raw output:") print(r.decode("ascii")) else: if verbosity: if r: print("\nResponse:\n") print(r.decode("ascii")) else: print("No HTTP response") # requests -> dbfileupload upload method option elif args.requests: r = post_pkg( pkg_name, pkg_path, jamf_url, enc_creds, obj_id, r_timeout, verbosity, ) # print result of the request if r.status_code == 200 or r.status_code == 201: pkg_id = ElementTree.fromstring(r.text).findtext("id") print("\nPackage uploaded successfully, ID={}".format( pkg_id)) if verbosity: print("HTTP POST Response Code: {}".format( r.status_code)) else: print("\nHTTP POST Response Code: {}".format( r.status_code)) if verbosity: api_get.get_headers(r) # curl -> dbfileupload upload method option else: r = curl_pkg( pkg_name, pkg_path, jamf_url, enc_creds, obj_id, r_timeout, verbosity, ) try: pkg_id = ElementTree.fromstring(r).findtext("id") if pkg_id: print("\nPackage uploaded successfully, ID={}". format(pkg_id)) except ElementTree.ParseError: print("Could not parse XML. Raw output:") print(r.decode("ascii")) else: if verbosity: if r: print("\nResponse:\n") print(r.decode("ascii")) else: print("No HTTP response") # now process the package metadata if a category is supplied, # or if we are dealing with an SMB share if not args.direct: if pkg_id: if verbosity: print("Updating package metadata for {}".format(pkg_id)) update_pkg_metadata( jamf_url, enc_creds, pkg_name, pkg_metadata, sha512string, verbosity, pkg_id, ) else: if verbosity: print("Creating package metadata") update_pkg_metadata(jamf_url, enc_creds, pkg_name, pkg_metadata, sha512string, verbosity) print()