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