示例#1
0
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()