lib/jss/api_object/computer.rb in ruby-jss-0.10.2a5 vs lib/jss/api_object/computer.rb in ruby-jss-0.10.2

- old
+ new

@@ -61,28 +61,35 @@ # After making any changes, you must call #update to send those # changes to the server. # # === MDM Commands # - # See the {JSS::MDM} mixin module for Class and Instance methods for - # sending MDM commands to computers. + # The following methods can be used to send an APNS command to the + # computer represented by an instance of JSS::Computer, equivalent to + # clicking one of the buttons on the Management Commands section of the + # Management tab of the Computer details page in the JSS UI. # - # To send MDM commands without fetching Computer instances, use the class - # methods, which can take multiple computer identifiers at once. + # - {#blank_push} (aliases blank, noop, send_blank_push) + # - {#device_lock} (aliases lock, lock_device) + # - {#erase_device} (aliases wipe) + # - {#remove_mdm_profile} # - # NOTE: the poorly named 'UnmanageDevice' mdm command is implemented - # as {#remove_mdm_profile} (which is its name in the webUI) as well as - # {#unmanage_device}. - # Calling that method will NOT fully unmanage a computer from the JSS's point + # To send an MDM command without making a Computer instance, use the class + # {JSS::Computer.send_mdm_command} which can take multiple computer + # identifiers at once. + # + # NOTE: the poorly named 'UnmanageDevice' command via the API is implemented + # as the {#remove_mdm_profile} method (which is its name in the webUI). + # Calling that method will NOT unmanage the machine from the JSS's point # of view, it will just remove the mdm management profile from the machine # and all configuration profiles that were installed via the JSS. Those # profiles may be re-installed automatically later if the computer is still in # scope for them # - # To properly unmanage a computer, use the {#make_unmanaged} Instance method - # which removes the mdm profile, but also makes the machine unmanged by the - # JSS, setting the management acct to nil, and requring re-enrollment. + # The {#make_unmanaged} method also removes the mdm profile, but actually + # does make the machine unmanged by the JSS, setting the management acct to + # nil, and requring re-enrollment. # # === Computer History # # Computer instances can now retrieve their management history from the JSS. # @@ -165,12 +172,10 @@ include JSS::Updatable include JSS::Locatable include JSS::Purchasable include JSS::Uploadable include JSS::Extendable - include JSS::Sitable - include JSS::MDM extend JSS::Matchable # Class Constants ##################################### @@ -186,13 +191,10 @@ # The hash key used for the JSON object output. # It's also used in various error messages RSRC_OBJECT_KEY = :computer - # Where is the Site data in the API JSON? - SITE_SUBSET = :general - # these keys, as well as :id and :name, are present in valid API JSON data for this class # DEPRECATED, with be removed in a future release. VALID_DATA_KEYS = %i[sus distribution_point alt_mac_address].freeze # these keys, as well as :id and :name, can be used to look up objects of this class in the JSS @@ -214,13 +216,37 @@ BOOT_FLAG = ' (Boot Partition)'.freeze # file uploads can send attachments to the JSS using :computers as the sub-resource. UPLOAD_TYPES = { attachment: :computers }.freeze - # Tell the MDM module what kind of MDM commands we use. - MDM_COMMAND_TARGET = :computers + # The base REST resource for sending computer MDM commands + COMPUTER_MDM_RSRC = 'computercommands/command'.freeze + # A mapping of Symbols available to the send_mdm_command class method, to + # the String commands actuallly sent via the API. + COMPUTER_MDM_COMMANDS = { + blank_push: 'BlankPush', + blankpush: 'BlankPush', + send_blank_push: 'BlankPush', + blank: 'BlankPush', + noop: 'BlankPush', + device_lock: 'DeviceLock', + devicelock: 'DeviceLock', + lock: 'DeviceLock', + lock_device: 'DeviceLock', + erase_device: 'EraseDevice', + erasedevice: 'EraseDevice', + erase: 'EraseDevice', + wipe: 'EraseDevice', + unmanage_device: 'UnmanageDevice', + unmanagedevice: 'UnmanageDevice', + unmanage: 'UnmanageDevice' + }.freeze + + # these MDM commands require a passcode + COMPUTER_MDM_COMMANDS_NEEDING_PASSCODE = %w[DeviceLock EraseDevice].freeze + # The API resource for app usage APPLICATION_USAGE_RSRC = 'computerapplicationusage'.freeze # The date format for retrieving usage data APPLICATION_USAGE_DATE_FMT = '%Y-%m-%d'.freeze @@ -271,10 +297,12 @@ # The keys are both the subset names in the resrouce URLS (when # converted to strings) and the second-level hash key of the # returned subset data. # + # The values are the key within each history item that contains the + # 'epoch' timestamp, for conver HISTORY_SUBSETS = %i[ computer_usage_logs audits policy_logs casper_remote_logs @@ -283,57 +311,34 @@ commands user_location mac_app_store_applications ].freeze - # Most History Subsets contain Arrays of Hashes. - # - # However, these contain a Hash of Arrays of Hashes: - # - # :commands is a hash with these keys: - # :completed - An array of hashes about completed MDM commands - # :pending - An array of hashes about pending MDM commands - # :failed - An array of hashes about failed MDM commands - # - # :mac_app_store_applications is a hash with these keys: - # :installed - An array of hashes about installed apps - # :pending - An array of hashes about apps pending installation - # :failed - An array of hashes about apps that failed to install. - # - # The .history class and instance methods for JSS::Computer re-organize - # those data structures to be consistent with the other subsets of history - # data by turning them into an Array of Hashes, where each hash has a - # :status key containing :completed/:installed, :pending, or :failed - # - # See {JSS::Computer.full_history}, {JSS::Computer.history_subset} and - # {JSS::Computer.standardize_history_subset} class methods for details. - # - HISTORY_INCONSISTENT_SUBSETS = %i[commands mac_app_store_applications].freeze + # HISTORY_SUBSETS = %i( + # computer_usage_logs date_time_epoch + # audits + # policy_logs date_completed_epoch + # casper_remote_logs date_time_epoch + # screen_sharing_logs date_time_epoch + # casper_imaging_logs + # commands completed_epoch + # user_location + # mac_app_store_applications + # ).freeze POLICY_STATUS_COMPLETED = 'Completed'.freeze POLICY_STATUS_FAILED = 'Failed'.freeze POLICY_STATUS_PENDING = 'Pending'.freeze - COMMAND_STATUS_COMPLETED = :completed - - COMMAND_STATUS_PENDING = :pending - - COMMAND_STATUS_FAILED = :failed - - APP_STORE_APP_STATUS_INSTALLED = :installed - - APP_STORE_APP_STATUS_PENDING = :pending - - APP_STORE_APP_STATUS_FAILED = :failed - # the object type for this object in # the object history table. # See {APIObject#add_object_history_entry} OBJECT_HISTORY_OBJECT_TYPE = 1 + # Class Methods ##################################### # Display the current Computer CheckIn settings in the JSS. # Currently this is read-only in ruby-jss, even tho the API @@ -456,195 +461,60 @@ # @return [Array<Hash>] all macpros in the jss def self.all_macpros(refresh = false, api: JSS.api) all(refresh, api: api).select { |d| d[:model] =~ /^macpro/i } end - # Retrieve Application Usage data for a computer by id, without - # instantiation. + # Send an MDM command to one or more managed computers by id or name # - # @param ident [Integer,String] An identifier (id, name, serialnumber, - # macadress or udid) of the computer for which to retrieve Application Usage # - # @param start_date [Time,Date,DateTime,String] The earliest date to retrieve + # @param targets[String,Integer,Array<String,Integer>] + # the name or id of the computer to receive the command, or + # an array of such names or ids, or a comma-separated string + # of them. + # @param command[Symbol] the command to send, one of the keys + # of COMPUTER_MDM_COMMANDS # - # @param end_date [String,Date,DateTime,Time] Defaults to start_date + # @param passcode[String] some commands require a 6-character passcode # # @param api[JSS::APIConnection] an API connection to use for the query. # Defaults to the corrently active API. See {JSS::APIConnection} # - # @return [Hash{Date=>Array<Hash>}] A Hash with keys (Date instances) for - # each day in the range. + # @return [String] The uuid of the MDM command sent, if applicable + # (blank pushes do not generate uuids) # - # Each hash value contains an Array of apps used - # on that day. - # - # Each item in the array is a hash of data about the app. - # Those hash keys are: - # :name => String, the name of the app - # :version => String ,the version of the app - # :foreground => Integer, the minutes it was in the foreground - # :open => Integer, the minutes it was running. - # - def self.application_usage(ident, start_date, end_date = nil, api: JSS.api) - id = valid_id ident, api: api - raise "No computer matches identifier: #{ident}" unless id - end_date ||= start_date - start_date = Time.parse start_date if start_date.is_a? String - end_date = Time.parse end_date if end_date.is_a? String - unless ([start_date.class, end_date.class] - APPLICATION_USAGE_DATE_CLASSES).empty? - raise JSS::InvalidDataError, 'Invalid Start or End Date' - end - start_date = start_date.strftime APPLICATION_USAGE_DATE_FMT - end_date = end_date.strftime APPLICATION_USAGE_DATE_FMT - data = api.get_rsrc(APPLICATION_USAGE_RSRC + "/id/#{id}/#{start_date}_#{end_date}") - parsed_data = {} - data[APPLICATION_USAGE_KEY].each do |day_hash| - date = Date.parse day_hash[:date] - parsed_data[date] = day_hash[:apps] - end - parsed_data - end # app usage + def self.send_mdm_command(targets, command, passcode = nil, api: JSS.api) + raise JSS::NoSuchItemError, "Unknown command '#{command}'" unless COMPUTER_MDM_COMMANDS.keys.include? command - # The 'computer management' data for a given computer by id, - # looked up on the fly. - # - # Without specifying a subset:, the entire dataset is returned as a hash of - # arrays, one per subset - # - # If a subset is given then only that array is returned, and it contains - # hashes with data about each item (usually :name and :id) - # - # If the only: param is provided with a subset, it is used as a hash-key to - # map the array to just those values, so subset: :smart_groups, only: :name - # will return an array of names of smartgroups that contain the computer. - # - # @param ident [Integer,String] An identifier (id, name, serialnumber, - # macadress or udid) of the computer for which to retrieve Application Usage - # - # @param subset[Symbol] Fetch only a subset of data, as an array. - # must be one of the symbols in MGMT_DATA_SUBSETS - # - # @param only[Symbol] When fetching a subset, only return one value - # per item in the array. meaningless without a subset. - # - # @param api[JSS::APIConnection] an API connection to use for the query. - # Defaults to the corrently active API. See {JSS::APIConnection} - # - # @return [Hash] Without a subset:, a hash of all subsets, each of which is - # an Array - # - # @return [Array] With a subset:, an array of items in that subset, possibly - # limited to just certain values with only: - # - def self.management_data(ident, subset: nil, only: nil, api: JSS.api) - id = valid_id ident, api: api - raise "No computer matches identifier: #{ident}" unless id - if subset - management_data_subset id, subset: subset, only: only, api: api - else - full_management_data id, api: api - end - end + command = COMPUTER_MDM_COMMANDS[command] + cmd_rsrc = "#{COMPUTER_MDM_RSRC}/#{command}" - # The full set of management data for a given computer. - # This private method is called by self.management_data, q.v. - # - def self.full_management_data(id, api: JSS.api) - mgmt_rsrc = MGMT_DATA_RSRC + "/id/#{id}" - api.get_rsrc(mgmt_rsrc)[MGMT_DATA_KEY] - end - private_class_method :full_management_data - - # A subset of management data for a given computer. - # This private method is called by self.management_data, q.v. - # - def self.management_data_subset(id, subset: nil, only: nil, api: JSS.api) - raise "Subset must be one of :#{MGMT_DATA_SUBSETS.join ', :'}" unless MGMT_DATA_SUBSETS.include? subset - subset_rsrc = MGMT_DATA_RSRC + "/id/#{id}/subset/#{subset}" - subset_data = api.get_rsrc(subset_rsrc)[MGMT_DATA_KEY] - return subset_data unless only - subset_data.map { |d| d[only] } - end - private_class_method :management_data_subset - - # Return this computer's management history. - # WARNING: Its huge, better to use a subset. - # - # NOTE: ruby-jss standardizes the inconsistent data-stucture of the subsets, - # so they may not exactly match the raw API output. - # See {JSS::Computer::HISTORY_INCONSISTENT_SUBSETS} for details - # - # @param ident [Integer,String] An identifier (id, name, serialnumber, - # macadress or udid) of the computer for which to retrieve Application Usage - # - # @param subset[Symbol] the subset to return, rather than full history. - # - # @param api[JSS::APIConnection] an API connection to use for the query. - # Defaults to the corrently active API. See {JSS::APIConnection} - # - # @return [Hash] The full history. - # - # @return [Array] The requested subset. - # - def self.history(ident, subset: nil, api: JSS.api) - id = valid_id ident, api: api - raise JSS::NoSuchItemError, "No Computer matches identifier: #{ident}" unless id - - if subset - history_subset id, subset: subset, api: api - else - full_history id, api: api + if COMPUTER_MDM_COMMANDS_NEEDING_PASSCODE.include? command + unless passcode && passcode.is_a?(String) && passcode.length == 6 + raise JSS::MissingDataError, "Command '#{command}' requires a 6-character passcode" + end + cmd_rsrc << "/passcode/#{passcode}" end - end - # The full management history for a given computer. - # This private method is called by self.history, q.v. - # - def self.full_history(id, api: JSS.api) - hist = api.get_rsrc(HISTORY_RSRC + "/id/#{id}")[HISTORY_KEY] + targets = JSS.to_s_and_a(targets.to_s)[:arrayform] unless targets.is_a? Array - # rework the :commands and :mac_app_store_applications into a consistent data structure - HISTORY_INCONSISTENT_SUBSETS.each do |subset| - hist[subset] = standardize_history_subset hist[subset] - end # :commands, :mac_app_store_applications].each do |subsect| - hist - end - private_class_method :full_history + # make sure its an array of ids + targets.map! do |comp| + if all_ids(api: api).include? comp.to_i + comp.to_i + elsif all_names(api: api).include? comp + map_all_ids_to(:name, api: api).invert[comp] + else + raise JSS::NoSuchItemError, "No computer found matching '#{comp}'" + end # if + end # map! - # A subset of the management history for a given computer. - # This private method is called by self.history, q.v. - # - def self.history_subset(id, subset: nil, api: JSS.api) - raise "Subset must be one of :#{HISTORY_SUBSETS.join ', :'}" unless HISTORY_SUBSETS.include? subset - subset_rsrc = HISTORY_RSRC + "/id/#{id}/subset/#{subset}" - subset_data = api.get_rsrc(subset_rsrc)[HISTORY_KEY][subset] - return standardize_history_subset(subset_data) if HISTORY_INCONSISTENT_SUBSETS.include? subset - subset_data - end - private_class_method :history_subset + cmd_rsrc << "/id/#{targets.join ','}" - # rework the inconsistent data structure of :commands and - # :mac_app_store_applications (Hash of Arrays of Hashes) - # to the same structure as the other subsets (Array of Hashes) - # - # @param raw_data [Hash] The raw, inconsistent data structure from the API - # - # @return [Array] the same data restructured to match the rest of the - # computer history subsets: An Array of Hashes, one per event, each with - # a :status key. - # - def self.standardize_history_subset(raw_data) - consistency_array = [] - raw_data.each do |status, events| - events.each do |evt| - evt[:status] = status - consistency_array << evt - end # cmd_events.each - end # raw_hist[:commands].each - consistency_array - end - private_class_method :standardize_history_subset + result = api.post_rsrc cmd_rsrc, nil + result =~ %r{<command_uuid>(.*)</command_uuid>} + Regexp.last_match(1) + end # send mdm command # Attributes ##################################### @@ -968,179 +838,245 @@ @software[:licensed_software] end # Get application usage data for this computer # for a given date range. - # See {JSS::Computer.application_usage} for details # + # TODO: Make this a class method so we can retrieve it without + # instantiating the Computer. + # + # @param start_date [String,Date,DateTime,Time] + # + # @param end_date [String,Date,DateTime,Time] Defaults to start_date + # + # @return [Hash{Date=>Array<Hash>}] For each day in the range, an Array + # with one Hash per application used. The hash keys are: + # :name => String, the name of the app + # :version => String ,the version of the app + # :foreground => Integer, the minutes it was in the foreground + # :open => Integer, the minutes it was running. + # def application_usage(start_date, end_date = nil) - JSS::Computer.application_usage @id, start_date, end_date, api: @api + end_date ||= start_date + start_date = Time.parse start_date if start_date.is_a? String + end_date = Time.parse end_date if end_date.is_a? String + unless ([start_date.class, end_date.class] - APPLICATION_USAGE_DATE_CLASSES).empty? + raise JSS::InvalidDataError, 'Invalid Start or End Date' + end + start_date = start_date.strftime APPLICATION_USAGE_DATE_FMT + end_date = end_date.strftime APPLICATION_USAGE_DATE_FMT + data = @api.get_rsrc(APPLICATION_USAGE_RSRC + "/id/#{@id}/#{start_date}_#{end_date}") + parsed_data = {} + data[APPLICATION_USAGE_KEY].each do |day_hash| + date = Date.parse day_hash[:date] + parsed_data[date] = day_hash[:apps] + end + parsed_data end # app usage - # The 'computer management' data for this computer + # The 'computer management' data for this computer, looked up on the fly. # - # NOTE: the data isn't cached locally, and the API is queried every time + # Without specifying a subset:, the entire dataset is returned as a hash of + # arrays, one per subset + # If a subset is given then only that array is returned, and it contains + # hashes with data about each item (usually :name and :id) # - # See {JSS::Computer.management_data} for details + # If the only: param is provided with a subset, it is used as a hash-key to + # map the array to just those values, so subset: :smart_groups, only: :name + # will return an array of names of smartgroups that contain this computer. # - def management_data(subset: nil, only: nil) - raise JSS::NoSuchItemError, 'Computer not yet saved in the JSS' unless @in_jss - JSS::Computer.management_data @id, subset: subset, only: only, api: @api + # TODO: Make this a class method so we can retrieve it without + # instantiating the Computer. + # + # @param subset[Symbol] Fetch only a subset of data, as an array. + # must be one of the symbols in MGMT_DATA_SUBSETS + # + # @param only[Symbol] When fetching a subset, only return one value + # per item in the array. meaningless without a subset. + # + # @param refresh[Boolean] should the data be re-cached from the API? + # + # @return [Hash] Without a subset:, a hash of all subsets, each of which is + # an Array + # + # @return [Array] With a subset:, an array of items in that subset. + # + def management_data(subset: nil, only: nil, refresh: false) + @management_data ||= {} + if subset + management_data_subset(subset: subset, only: only, refresh: refresh) + else + full_management_data refresh + end end + def full_management_data(refresh = false) + @management_data[:full] = nil if refresh + return @management_data[:full] if @management_data[:full] + mgmt_rsrc = MGMT_DATA_RSRC + "/id/#{@id}" + @management_data[:full] = @api.get_rsrc(mgmt_rsrc)[MGMT_DATA_KEY] + @management_data[:full] + end + private :full_management_data + + def management_data_subset(subset: nil, only: nil, refresh: false) + raise "Subset must be one of :#{MGMT_DATA_SUBSETS.join ', :'}" unless MGMT_DATA_SUBSETS.include? subset + @management_data[subset] = nil if refresh + return @management_data[subset] if @management_data[subset] + subset_rsrc = MGMT_DATA_RSRC + "/id/#{@id}/subset/#{subset}" + @management_data[subset] = @api.get_rsrc(subset_rsrc)[MGMT_DATA_KEY] + return @management_data[subset] unless only + @management_data[subset].map { |d| d[only] } + end + private :management_data_subset + # A shortcut for 'management_data subset: :smart_groups' # - def smart_groups(only: nil) - management_data subset: :smart_groups, only: only + def smart_groups(only: nil, refresh: false) + management_data subset: :smart_groups, only: only, refresh: refresh end # A shortcut for 'management_data subset: :static_groups' # - def static_groups(only: nil) - management_data subset: :static_groups, only: only + def static_groups(only: nil, refresh: false) + management_data subset: :static_groups, only: only, refresh: refresh end # A shortcut for 'management_data subset: :policies' # - def policies(only: nil) - management_data subset: :policies, only: only + def policies(only: nil, refresh: false) + management_data subset: :policies, only: only, refresh: refresh end # A shortcut for 'management_data subset: :os_x_configuration_profiles' # - def configuration_profiles(only: nil) - management_data subset: :os_x_configuration_profiles, only: only + def configuration_profiles(only: nil, refresh: false) + management_data subset: :os_x_configuration_profiles, only: only, refresh: refresh end # A shortcut for 'management_data subset: :ebooks' # - def ebooks(only: nil) + def ebooks(only: nil, refresh: false) management_data subset: :ebooks, only: only, refresh: refresh end # A shortcut for 'management_data subset: :mac_app_store_apps' # - def app_store_apps(only: nil) - management_data subset: :mac_app_store_apps, only: only + def app_store_apps(only: nil, refresh: false) + management_data subset: :mac_app_store_apps, only: only, refresh: refresh end # A shortcut for 'management_data subset: :restricted_software' # - def restricted_software(only: nil) - management_data subset: :restricted_software, only: only + def restricted_software(only: nil, refresh: false) + management_data subset: :restricted_software, only: only, refresh: refresh end # A shortcut for 'management_data subset: :patch_reporting_software_titles' # - def patch_titles(only: nil) - management_data subset: :patch_reporting_software_titles, only: only + def patch_titles(only: nil, refresh: false) + management_data subset: :patch_reporting_software_titles, only: only, refresh: refresh end - # Return this computer's management history. - # WARNING: Its huge, better to use a subset or one of the shortcut methods. + # Return this computer's history. + # WARNING! Its huge, better to use a subset a + # nd one of the shortcut methods. # - # NOTE: This is not the same as a computer's Object History + # TODO: Make this a class method so we can retrieve it without + # instantiating the Computer. # - # NOTE: The data isn't cached locally, the API is queried every time + # @param subset[Symbol] the subset to return, rather than full history. # - # For details, see {JSS::Computer.history} + # @param refresh[Boolean] should we re-cache the data from the API? # - def history(subset: nil) - JSS::Computer.history @id, subset: subset, api: @api + # @return [Hash] The full history + # + # @return [Array] The history subset requested + # + def history(subset: nil, refresh: false) + @history ||= {} + if subset + history_subset(subset: subset, refresh: refresh) + else + full_history refresh + end end + def full_history(refresh = false) + @history[:full] = nil if refresh + return @history[:full] if @history[:full] + history_rsrc = HISTORY_RSRC + "/id/#{@id}" + @history[:full] = @api.get_rsrc(history_rsrc)[HISTORY_KEY] + @history[:full] + end + private :full_history + + def history_subset(subset: nil, refresh: false) + raise "Subset must be one of :#{HISTORY_SUBSETS.join ', :'}" unless HISTORY_SUBSETS.include? subset + @history[subset] = nil if refresh + return @history[subset] if @history[subset] + subset_rsrc = HISTORY_RSRC + "/id/#{@id}/subset/#{subset}" + @history[subset] = @api.get_rsrc(subset_rsrc)[HISTORY_KEY] + @history[subset] + end + private :history_subset + # Shortcut for history(:computer_usage_logs) - def usage_logs - history subset: :computer_usage_logs + def usage_logs(refresh = false) + history(subset: :computer_usage_logs, refresh: refresh) end # Shortcut for history(:audits) - def audits - history subset: :audits + def audits(refresh = false) + history(subset: :audits, refresh: refresh) end # Shortcut for history(:policy_logs) - def policy_logs - history subset: :policy_logs + def policy_logs(refresh = false) + history(subset: :policy_logs, refresh: refresh) end # Shortcut for history(:policy_logs), but just the completed policies - def completed_policies - policy_logs.select { |pl| pl[:status] == POLICY_STATUS_COMPLETED } + def completed_policies(refresh = false) + policy_logs(refresh).select { |pl| pl[:status] == POLICY_STATUS_COMPLETED } end # Shortcut for history(:policy_logs), but just the failes policies - def failed_policies - policy_logs.select { |pl| pl[:status] == POLICY_STATUS_FAILED } + def failed_policies(refresh = false) + policy_log(refresh).select { |pl| pl[:status] == POLICY_STATUS_FAILED } end # Shortcut for history(:casper_remote_logs) - def casper_remote_logs - history subset: :casper_remote_logs + def casper_remote_logs(refresh = false) + history(subset: :casper_remote_logs, refresh: refresh) end # Shortcut for history(:screen_sharing_logs) - def screen_sharing_logs - history subset: :screen_sharing_logs + def screen_sharing_logs(refresh = false) + history(subset: :screen_sharing_logs, refresh: refresh) end # Shortcut for history(:casper_imaging_logs) - def casper_imaging_logs - history subset: :casper_imaging_logs + def casper_imaging_logs(refresh = false) + history(subset: :casper_imaging_logs, refresh: refresh) end # Shortcut for history(:commands) - def commands - history subset: :commands + def commands(refresh = false) + history(subset: :commands, refresh: refresh) end - # Shortcut for history(:commands) but just the completed commands - # - def completed_commands - commands.select { |cmd| cmd[:status] == COMMAND_STATUS_COMPLETED } - end - - # Shortcut for history(:commands) but just the pending commands - # - def pending_commands - commands.select { |cmd| cmd[:status] == COMMAND_STATUS_PENDING } - end - - # Shortcut for history(:commands) but just the failed commands - # - def failed_commands - commands.select { |cmd| cmd[:status] == COMMAND_STATUS_FAILED } - end - # Shortcut for history(:user_location) - def user_location_history - history subset: :user_location + def user_location_history(refresh = false) + history(subset: :user_location, refresh: refresh) end # Shortcut for history(:mac_app_store_applications) - def app_store_app_history - history subset: :mac_app_store_applications + def app_store_app_history(refresh = false) + history(subset: :mac_app_store_applications, refresh: refresh) end - # Shortcut for history(:mac_app_store_applications) but just the installed apps - # - def installed_app_store_apps - app_store_app_history.select { |app| app[:status] == APP_STORE_APP_STATUS_INSTALLED } - end - - # Shortcut for history(:mac_app_store_applications) but just the pending apps - # - def pending_app_store_apps - app_store_app_history.select { |app| app[:status] == APP_STORE_APP_STATUS_PENDING } - end - - # Shortcut for history(:mac_app_store_applications) but just the failed apps - # - def failed_app_store_apps - app_store_app_history.select { |app| app[:status] == APP_STORE_APP_STATUS_FAILED } - end - # Set or unset management acct and password for this computer # # @param name[String] the name of the management acct. # # @param password[String] the password of the management acct @@ -1239,13 +1175,14 @@ # Send changes to the API # # @return [void] # def update - remove_mdm_profile if mdm_capable && @unmange_at_update + id = super + remove_mdm_profile if mdm_capable && managed? && @unmange_at_update @unmange_at_update = false - super + id end # Delete this computer from the JSS # # @return [void] @@ -1289,11 +1226,52 @@ @peripherals = nil @purchasing = nil @software = nil end # delete + # Send a blank_push MDM command + # + # See JSS::Computer.send_mdm_command + # + def blank_push + self.class.send_mdm_command @id, :blank_push, api: @api + end + alias noop blank_push + alias send_blank_push blank_push + # Send a device_lock MDM command + # + # See JSS::Computer.send_mdm_command + # + def device_lock(passcode) + self.class.send_mdm_command @id, :device_lock, passcode, api: @api + end + alias lock device_lock + alias lock_device device_lock + + # Send an erase_device MDM command + # + # See JSS::Computer.send_mdm_command + # + def erase_device(passcode) + self.class.send_mdm_command @id, :erase_device, passcode, api: @api + end + alias erase erase_device + alias wipe erase_device + + # Remove MDM management profile without + # un-enrolling from the JSS or + # resetting the JSS management acct. + # + # To do those things as well, see {#make_unmanaged} + # + # See JSS::Computer.send_mdm_command + # + def remove_mdm_profile + self.class.send_mdm_command @id, :unmanage_device, api: @api + end + # aliases alias alt_macaddress alt_mac_address alias bar_code_1 barcode_1 alias bar_code_2 barcode_2 alias managed? managed @@ -1334,16 +1312,14 @@ rmgmt = general.add_element('remote_management') rmgmt.add_element('managed').text = @managed rmgmt.add_element('management_username').text = @management_username rmgmt.add_element('management_password').text = @management_password if @management_password - computer << ext_attr_xml + computer << ext_attr_xml if @changed_eas && !@changed_eas.empty? computer << location_xml if has_location? computer << purchasing_xml if has_purchasing? - - add_site_to_xml(doc) doc.to_s end # rest_xml end # class Computer