def upload_computergroup( jamf_url, enc_creds, computergroup_name, template_contents, cli_custom_keys, verbosity, obj_id=None, ): """Upload computer group""" # if we find an object ID we put, if not, we post if obj_id: url = "{}/JSSResource/computergroups/id/{}".format(jamf_url, obj_id) else: url = "{}/JSSResource/computergroups/id/0".format(jamf_url) if verbosity > 2: print("Computer Group data:") print(template_contents) print("Uploading Computer Group...") # write the template to temp file template_xml = curl.write_temp_file(template_contents) count = 0 while True: count += 1 if verbosity > 1: print("Computer Group upload attempt {}".format(count)) method = "PUT" if obj_id else "POST" r = curl.request(method, url, enc_creds, verbosity, template_xml) # check HTTP response if curl.status_check(r, "Computer Group", computergroup_name) == "break": break if count > 5: print( "WARNING: Computer Group upload did not succeed after 5 attempts" ) print("\nHTTP POST Response Code: {}".format(r.status_code)) break sleep(30) if verbosity > 1: api_get.get_headers(r) # clean up temp files if os.path.exists(template_xml): os.remove(template_xml)
def upload_mobileconfig( jamf_url, enc_creds, mobileconfig_name, description, category, mobileconfig_plist, computergroup_name, template_contents, profile_uuid, verbosity, obj_id=None, ): """Update Configuration Profile metadata.""" # if we find an object ID we put, if not, we post if obj_id: url = "{}/JSSResource/osxconfigurationprofiles/id/{}".format(jamf_url, obj_id) else: url = "{}/JSSResource/osxconfigurationprofiles/id/0".format(jamf_url) # remove newlines, tabs, leading spaces, and XML-escape the payload mobileconfig_plist = mobileconfig_plist.decode("UTF-8") mobileconfig_list = mobileconfig_plist.rsplit("\n") mobileconfig_list = [x.strip("\t") for x in mobileconfig_list] mobileconfig_list = [x.strip(" ") for x in mobileconfig_list] mobileconfig = "".join(mobileconfig_list) # substitute user-assignable keys replaceable_keys = { "mobileconfig_name": mobileconfig_name, "description": description, "category": category, "payload": mobileconfig, "computergroup_name": computergroup_name, "uuid": "com.github.grahampugh.jamf-upload.{}".format(profile_uuid), } # substitute user-assignable keys (escaping for XML) template_contents = actions.substitute_assignable_keys( template_contents, replaceable_keys, verbosity, xml_escape=True ) if verbosity > 2: print("Configuration Profile to be uploaded:") print(template_contents) print("Uploading Configuration Profile..") # write the template to temp file template_xml = curl.write_temp_file(template_contents) count = 0 while True: count += 1 if verbosity > 1: print("Configuration Profile upload attempt {}".format(count)) method = "PUT" if obj_id else "POST" r = curl.request(method, url, enc_creds, verbosity, template_xml) # check HTTP response if curl.status_check(r, "Configuration Profile", mobileconfig_name) == "break": break if count > 5: print( "ERROR: Configuration Profile upload did not succeed after 5 attempts" ) print("\nHTTP POST Response Code: {}".format(r.status_code)) break sleep(10) if verbosity > 1: api_get.get_headers(r) return r
def update_pkg_metadata(jamf_url, enc_creds, pkg_name, pkg_metadata, hash_value, verbosity, pkg_id=None): """Update package metadata. Currently only serves category""" if hash_value: hash_type = "SHA_512" else: hash_type = "MD5" # build the package record XML pkg_data = ( "<package>" + f"<name>{pkg_name}</name>" + f"<filename>{pkg_name}</filename>" + f"<category>{escape(pkg_metadata['category'])}</category>" + f"<info>{escape(pkg_metadata['info'])}</info>" + f"<notes>{escape(pkg_metadata['notes'])}</notes>" + f"<priority>{pkg_metadata['priority']}</priority>" + f"<reboot_required>{pkg_metadata['reboot_required']}</reboot_required>" + f"<required_processor>{pkg_metadata['required_processor']}</required_processor>" + f"<os_requirement>{pkg_metadata['os_requirement']}</os_requirement>" + f"<hash_type>{hash_type}</hash_type>" + f"<hash_value>{hash_value}</hash_value>" + f"<send_notification>{pkg_metadata['send_notification']}</send_notification>" + "</package>") # ideally we upload to the package ID but if we didn't get a good response # we fall back to the package name if pkg_id: method = "PUT" url = "{}/JSSResource/packages/id/{}".format(jamf_url, pkg_id) else: method = "POST" url = "{}/JSSResource/packages/name/{}".format(jamf_url, pkg_name) if verbosity > 2: print("Package data:") print(pkg_data) count = 0 while True: count += 1 if verbosity > 1: print(f"Package metadata upload attempt {count}") pkg_xml = curl.write_temp_file(pkg_data) r = curl.request(method, url, enc_creds, verbosity, pkg_xml) # check HTTP response if curl.status_check(r, "Package", pkg_name) == "break": break if count > 5: print( "WARNING: Package metadata update did not succeed after 5 attempts" ) print(f"HTTP POST Response Code: {r.status_code}") print("ERROR: Package metadata upload failed ") exit(-1) sleep(30) if verbosity: api_get.get_headers(r) # clean up temp files if os.path.exists(pkg_xml): os.remove(pkg_xml)
def upload_ea( jamf_url, enc_creds, ea_name, script_path, verbosity, cli_custom_keys, obj_id=None, ): """Update extension attribute metadata.""" # import script from file and replace any keys in the script with open(script_path, "r") as file: script_contents = file.read() # substitute user-assignable keys # pylint is incorrectly stating that 'verbosity' has no value. So... # pylint: disable=no-value-for-parameter script_contents = actions.substitute_assignable_keys( script_contents, cli_custom_keys, verbosity ) # XML-escape the script script_contents_escaped = escape(script_contents) # build the object ea_data = ( "<computer_extension_attribute>" + "<name>{}</name>".format(ea_name) + "<enabled>true</enabled>" + "<description/>" + "<data_type>String</data_type>" + "<input_type>" + " <type>script</type>" + " <platform>Mac</platform>" + " <script>{}</script>".format(script_contents_escaped) + "</input_type>" + "<inventory_display>Extension Attributes</inventory_display>" + "<recon_display>Extension Attributes</recon_display>" + "</computer_extension_attribute>" ) # if we find an object ID we put, if not, we post if obj_id: url = "{}/JSSResource/computerextensionattributes/id/{}".format( jamf_url, obj_id ) else: url = "{}/JSSResource/computerextensionattributes/id/0".format(jamf_url) if verbosity > 2: print("Extension Attribute data:") print(ea_data) print("Uploading Extension Attribute..") # write the template to temp file template_xml = curl.write_temp_file(ea_data) count = 0 while True: count += 1 if verbosity > 1: print("Extension Attribute upload attempt {}".format(count)) method = "PUT" if obj_id else "POST" r = curl.request(method, url, enc_creds, verbosity, template_xml) # check HTTP response if curl.status_check(r, "Extension Attribute", ea_name) == "break": break if count > 5: print("ERROR: Extension Attribute upload did not succeed after 5 attempts") print("\nHTTP POST Response Code: {}".format(r.status_code)) break sleep(10) if verbosity > 1: api_get.get_headers(r) # clean up temp files if os.path.exists(template_xml): os.remove(template_xml)