lib/jss/api_object/package.rb in ruby-jss-1.2.10 vs lib/jss/api_object/package.rb in ruby-jss-1.3.2

- old
+ new

@@ -63,11 +63,11 @@ # The pkg storage folder on the distribution point DIST_POINT_PKGS_FOLDER = 'Packages'.freeze # The possible values for cpu_type (required_processor) in a JSS package - CPU_TYPES = %w[None x86 ppc].freeze + CPU_TYPES = %w[None Intel/x86 ppc].freeze # the possible priorities PRIORITIES = (1..20) # the default priority, since one is needed for making new pkgs @@ -119,15 +119,37 @@ # Defaults to the corrently active API. See {JSS::APIConnection} # # @return [Array<String>] The current file names # def self.all_filenames(api: JSS.api) - pkgs_in_use = [] - all_ids.each { |pkg_id| pkgs_in_use << fetch(id: pkg_id, api: api).filename } - pkgs_in_use.compact + all_filenames_by(:id, api: api).values end + # A Hash of all dist-point filenames used by all JSS packages, keyed by + # package name or id + # + # Slow cuz we have to instantiate every pkg + # + # @param key[Symbol] either :id, or :name + # + # @param api[JSS::APIConnection] an API connection to use + # Defaults to the corrently active API. See {JSS::APIConnection} + # + # @return [Hash{Ingeter,String => String}] The current file names by key + # + def self.all_filenames_by(key, api: JSS.api) + raise ArgumentError, 'key must be :id or :name' unless %i[id name].include? key + + files_in_use = {} + all_ids(:refresh).each do |pkg_id| + pkg = fetch id: pkg_id, api: api + files_in_use[pkg.send(key)] = pkg.filename + end + + files_in_use + end + # An array of String filenames for all files DIST_POINT_PKGS_FOLDER # that aren't used by a JSS::Package # # Slow cuz we have to instantiate every pkg # @@ -138,18 +160,21 @@ # distribution point when finished. # # @param api[JSS::APIConnection] an API connection to use # Defaults to the corrently active API. See {JSS::APIConnection} # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # # @return [Array<String>] The orphaned files # - def self.orphaned_files(ro_pw, unmount = true, api: JSS.api) - mdp = JSS::DistributionPoint.master_distribution_point api: api - pkgs_dir = mdp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER - files_on_mdp = pkgs_dir.children.map { |f| f.basename.to_s } - mdp.unmount if unmount - files_on_mdp - all_filenames(api: api) + def self.orphaned_files(ro_pw, unmount = true, api: JSS.api, dist_point: nil) + dp = fetch_dist_point(dist_point, api: api) + pkgs_dir = dp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER + files_on_dp = pkgs_dir.children.map { |f| f.basename.to_s } + dp.unmount if unmount + files_on_dp - all_filenames(api: api) end # An array of String filenames for all filenames in any # JSS::Package that don't exist on DIST_POINT_PKGS_FOLDER # @@ -162,18 +187,22 @@ # distribution point when finished. # # @param api[JSS::APIConnection] an API connection to use # Defaults to the corrently active API. See {JSS::APIConnection} # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # + # # @return [Array<String>] The orphaned files # - def self.missing_files(ro_pw, unmount = true, api: JSS.api) - mdp = JSS::DistributionPoint.master_distribution_point api: api - pkgs_dir = mdp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER - files_on_mdp = pkgs_dir.children.map { |f| f.basename.to_s } - mdp.unmount if unmount - all_filenames(api: api) - files_on_mdp + def self.missing_files(ro_pw, unmount = true, api: JSS.api, dist_point: nil) + dp = fetch_dist_point(dist_point, api: api) + pkgs_dir = dp.mount(ro_pw, :ro) + DIST_POINT_PKGS_FOLDER + files_on_dp = pkgs_dir.children.map { |f| f.basename.to_s } + dp.unmount if unmount + all_filenames(api: api) - files_on_dp end # Given a file path, and hash type, generate the checksum for an arbitrary # file. # @@ -187,10 +216,22 @@ def self.calculate_checksum(filepath, type = DEFAULT_CHECKSUM_HASH_TYPE ) raise ArgumentError, 'Unknown checksum hash type' unless CHECKSUM_HASH_TYPES.key? type CHECKSUM_HASH_TYPES[type].file(filepath).hexdigest end + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # + # @return [JSS::DistributionPoint] + def self.fetch_dist_point(dist_point, api: JSS.api) + if dist_point + JSS::DistributionPoint.fetch dist_point, api: api + else + JSS::DistributionPoint.master_distribution_point api: api + end + end + # Attributes ##################################### # @return [String] the filename of the .pkg, .mpkg, or .dmg on the Casper server attr_reader :filename @@ -322,11 +363,11 @@ # def filename=(new_val) new_val = nil if new_val == '' new_val ||= @name return nil if new_val == @filename - warn 'WARNING: you must change the filename on the master Distribution Point. See JSS::Package.update_master_filename.' if @in_jss + @filename = new_val @need_to_update = true end # Change the Fill Existing Users value @@ -588,18 +629,22 @@ # @param unmount[Boolean] whether or not ot unount the distribution point when finished. # # @param chksum [String] the constants CHECKSUM_HASH_TYPE_SHA512 or # CHECKSUM_HASH_TYPE_MD5. Anything else means don't calc. # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # # @return [void] # - def upload_master_file(local_file_path, rw_pw, unmount = true, chksum: DEFAULT_CHECKSUM_HASH_TYPE ) + def upload_master_file(local_file_path, rw_pw, unmount = true, chksum: DEFAULT_CHECKSUM_HASH_TYPE, dist_point: nil) raise JSS::NoSuchItemError, 'Please create this package in the JSS before uploading it.' unless @in_jss - mdp = JSS::DistributionPoint.master_distribution_point api: @api - destination = mdp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}" + dp = self.class.fetch_dist_point(dist_point, api: @api) + destination = dp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}" + local_path = Pathname.new local_file_path raise JSS::NoSuchItemError, "Local file '#{@local_file}' doesn't exist" unless local_path.exist? # should we zip it? if local_path.directory? @@ -635,15 +680,15 @@ FileUtils.copy_entry local_path, destination if CHECKSUM_HASH_TYPES.keys.include? chksum @checksum_type = chksum - @checksum = calculate_checksum local_file: local_path, type: chksum, unmount: false + @checksum = calculate_checksum local_file: local_path, type: chksum, unmount: false, dist_point: dist_point @need_to_update = true end update if @need_to_update - mdp.unmount if unmount + dp.unmount if unmount end # upload master file # Using either a local file, or the file on the master dist. point, # re-set the checksum for this package. Call #update to save the # new one to the JSS. @@ -656,19 +701,20 @@ # # @param @see calculate_checksum # # @return [void] # - def reset_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true) + def reset_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true, dist_point: nil ) type ||= DEFAULT_CHECKSUM_HASH_TYPE new_checksum = calculate_checksum( type: type, local_file: local_file, rw_pw: rw_pw, ro_pw: ro_pw, - unmount: unmount + unmount: unmount, + dist_point: dist_point ) return if @checksum == new_checksum @checksum_type = type @checksum = new_checksum @@ -692,15 +738,18 @@ # point. Either this or the rw_pw must be provided if no local_file # # @param unmount [Boolean] Unmount the master dist point after using it. # Only used if the dist point is mounted. default: true # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # # @return [String] The calculated checksum # - def calculate_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true ) + def calculate_checksum(type: nil, local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true, dist_point: nil ) type ||= DEFAULT_CHECKSUM_HASH_TYPE - mdp = JSS::DistributionPoint.master_distribution_point api: @api + dp = self.class.fetch_dist_point(dist_point, api: @api) if local_file file_to_calc = local_file else if rw_pw @@ -710,14 +759,14 @@ dppw = ro_pw mnt = :ro else raise ArgumentError, 'Either rw_pw: or ro_pw: must be provided' end - file_to_calc = mdp.mount(dppw, mnt) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}" + file_to_calc = dp.mount(dppw, mnt) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}" end new_checksum = self.class.calculate_checksum(file_to_calc, type) - mdp.unmount if unmount && mdp.mounted? + dp.unmount if unmount && dp.mounted? new_checksum end # Is the checksum for this pkg is valid? # @@ -732,21 +781,25 @@ # point. Either this or the rw_pw must be provided if no local_file # # @param unmount [Boolean] Unmount the master dist point after using it. # Only used if the dist point is mounted. default: true # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # # @return [Boolean] false if there is no checksum for this pkg, otherwise, # does the calculated checksum match the one stored for the pkg? # - def checksum_valid?(local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true) + def checksum_valid?(local_file: nil, rw_pw: nil, ro_pw: nil, unmount: true, dist_point: nil ) return false unless @checksum new_checksum = calculate_checksum( type: @checksum_type, local_file: local_file, rw_pw: rw_pw, ro_pw: ro_pw, - unmount: unmount + unmount: unmount, + dist_point: dist_point ) new_checksum == @checksum end # Change the name of a package file on the master distribution point. @@ -758,26 +811,30 @@ # @param unmount[Boolean] whether or not ot unount the distribution point when finished. # # @param rw_pw[String,Symbol] the password for the read/write account on the master Distribution Point, # or :prompt, or :stdin# where # is the line of stdin containing the password See {JSS::DistributionPoint#mount} # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # # @return [nil] # - def update_master_filename(old_file_name, new_file_name, rw_pw, unmount = true) + def update_master_filename(old_file_name, new_file_name, rw_pw, unmount = true, dist_point: nil) raise JSS::NoSuchItemError, "#{old_file_name} does not exist in the jss." unless @in_jss - mdp = JSS::DistributionPoint.master_distribution_point api: @api - pkgs_dir = mdp.mount(rw_pw, :rw) + DIST_POINT_PKGS_FOLDER.to_s + dp = self.class.fetch_dist_point(dist_point, api: @api) + + pkgs_dir = dp.mount(rw_pw, :rw) + DIST_POINT_PKGS_FOLDER.to_s old_file = pkgs_dir + old_file_name raise JSS::NoSuchItemError, "File not found on the master distribution point at #{DIST_POINT_PKGS_FOLDER}/#{old_file_name}." unless \ old_file.exist? new_file = pkgs_dir + new_file_name # use the extension of the original file. new_file = pkgs_dir + (new_file_name + old_file.extname) if new_file.extname.empty? old_file.rename new_file - mdp.unmount if unmount + dp.unmount if unmount nil end # update_master_filename @@ -789,22 +846,25 @@ # @param rw_pw[String] the password for the read/write account on the master Distribution Point # or :prompt, or :stdin# where # is the line of stdin containing the password. See {JSS::DistributionPoint#mount} # # @param unmount[Boolean] whether or not ot unount the distribution point when finished. # + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # # @return [Boolean] was the file deleted? # - def delete_master_file(rw_pw, unmount = true) - mdp = JSS::DistributionPoint.master_distribution_point api: @api - file = mdp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}" + def delete_master_file(rw_pw, unmount = true, dist_point: nil) + dp = self.class.fetch_dist_point(dist_point, api: @api) + file = dp.mount(rw_pw, :rw) + "#{DIST_POINT_PKGS_FOLDER}/#{@filename}" if file.exist? file.delete did_it = true else did_it = false end # if exists - mdp.unmount if unmount + dp.unmount if unmount did_it end # delete master file # Delete this package from the JSS, optionally # deleting the master dist point file also. @@ -814,13 +874,17 @@ # @param rw_pw[String] the password for the read/write account on the master Distribution Point # or :prompt, or :stdin# where # is the line of stdin containing the password. See {JSS::DistributionPoint#mount} # # @param unmount[Boolean] whether or not ot unount the distribution point when finished. # - def delete(delete_file: false, rw_pw: nil, unmount: true) + # @param dist_point [String,Integer] the name or id of the distribution + # point to use. Defaults to the Master Dist. Point + # + # @return [void] + def delete(delete_file: false, rw_pw: nil, unmount: true, dist_point: nil) super() - delete_master_file(rw_pw, unmount) if delete_file + delete_master_file(rw_pw, unmount, dist_point: dist_point) if delete_file end # Install this package via the jamf binary 'install' command from the # distribution point for this machine. # See {JSS::DistributionPoint.my_distribution_point} @@ -883,11 +947,11 @@ # use a provided alternative url for an http download if args[:alt_download_url] # we'll re-add the filename below if needed. src_path = args[:alt_download_url].chomp "/#{@filename}" - + using_http = true # use our appropriate dist. point for download else mdp = JSS::DistributionPoint.my_distribution_point api: @api # how do we access our dist. point? with http? @@ -1018,9 +1082,10 @@ # Private Instance Methods ################################ private + # Return the REST XML for this pkg, with the current values, # for saving or updating # def rest_xml