ruby-jss 0.8.2 → 0.9.0.b1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGES.md +37 -1
- data/README.md +15 -15
- data/bin/cgrouper +1 -1
- data/bin/netseg-update +1 -1
- data/lib/jss/api_connection.rb +307 -25
- data/lib/jss/api_object.rb +123 -54
- data/lib/jss/api_object/account.rb +6 -1
- data/lib/jss/api_object/advanced_search.rb +12 -12
- data/lib/jss/api_object/computer.rb +570 -141
- data/lib/jss/api_object/computer_invitation.rb +9 -0
- data/lib/jss/api_object/creatable.rb +1 -1
- data/lib/jss/api_object/distribution_point.rb +1 -1
- data/lib/jss/api_object/extension_attribute.rb +6 -6
- data/lib/jss/api_object/group.rb +1 -1
- data/lib/jss/api_object/matchable.rb +1 -1
- data/lib/jss/api_object/mobile_device.rb +690 -304
- data/lib/jss/api_object/mobile_device_application.rb +11 -1
- data/lib/jss/api_object/package.rb +1 -1
- data/lib/jss/api_object/policy.rb +206 -2
- data/lib/jss/api_object/restricted_software.rb +126 -42
- data/lib/jss/api_object/scopable/scope.rb +20 -21
- data/lib/jss/api_object/self_servable.rb +9 -6
- data/lib/jss/api_object/updatable.rb +1 -1
- data/lib/jss/api_object/uploadable.rb +1 -1
- data/lib/jss/server.rb +57 -56
- data/lib/jss/utility.rb +4 -0
- data/lib/jss/version.rb +1 -1
- metadata +4 -24
@@ -58,6 +58,10 @@ module JSS
|
|
58
58
|
# Class Methods
|
59
59
|
#####################################
|
60
60
|
|
61
|
+
def self.all_invitations
|
62
|
+
all.map { |ci| ci[:invitation] }
|
63
|
+
end
|
64
|
+
|
61
65
|
# Class Constants
|
62
66
|
#####################################
|
63
67
|
|
@@ -74,6 +78,11 @@ module JSS
|
|
74
78
|
# these keys, as well as :id and :name, are present in valid API JSON data for this class
|
75
79
|
VALID_DATA_KEYS = [:invitation].freeze
|
76
80
|
|
81
|
+
# See JSS::APIObject
|
82
|
+
OTHER_LOOKUP_KEYS = {
|
83
|
+
invitation: {rsrc_key: :invitation, list: :all_invitations}
|
84
|
+
}.freeze
|
85
|
+
|
77
86
|
# Attributes
|
78
87
|
#####################################
|
79
88
|
|
@@ -76,7 +76,7 @@ module JSS
|
|
76
76
|
def create
|
77
77
|
raise JSS::UnsupportedError, "Creating or editing #{self.class::RSRC_LIST_KEY} isn't yet supported. Please use other Casper workflows." unless respond_to? :create
|
78
78
|
raise AlreadyExistsError, "This #{self.class::RSRC_OBJECT_KEY} already exists. Use #update to make changes." if @in_jss
|
79
|
-
JSS
|
79
|
+
JSS.api_connection.post_rsrc(@rest_rsrc, rest_xml) =~ %r{><id>(\d+)</id><}
|
80
80
|
@id = Regexp.last_match(1).to_i
|
81
81
|
@in_jss = true
|
82
82
|
@need_to_update = false
|
@@ -258,7 +258,7 @@ module JSS
|
|
258
258
|
if args[:id] == :master
|
259
259
|
|
260
260
|
self.class.all_ids.each do |id|
|
261
|
-
@init_data = JSS
|
261
|
+
@init_data = JSS.api_connection.get_rsrc("#{RSRC_BASE}/id/#{id}")[RSRC_OBJECT_KEY]
|
262
262
|
if @init_data[:is_master]
|
263
263
|
@id = @init_data[:id]
|
264
264
|
@name = @init_data[:name]
|
@@ -201,15 +201,15 @@ module JSS
|
|
201
201
|
### @see JSS::APIObject#delete
|
202
202
|
###
|
203
203
|
def delete
|
204
|
-
orig_open_timeout = JSS
|
205
|
-
orig_timeout = JSS
|
206
|
-
JSS
|
207
|
-
JSS
|
204
|
+
orig_open_timeout = JSS.api_connection.cnx.options[:open_timeout]
|
205
|
+
orig_timeout = JSS.api_connection.cnx.options[:timeout]
|
206
|
+
JSS.api_connection.timeout = orig_timeout + 1800
|
207
|
+
JSS.api_connection.open_timeout = orig_open_timeout + 1800
|
208
208
|
begin
|
209
209
|
super
|
210
210
|
ensure
|
211
|
-
JSS
|
212
|
-
JSS
|
211
|
+
JSS.api_connection.timeout = orig_timeout
|
212
|
+
JSS.api_connection.open_timeout = orig_open_timeout
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
data/lib/jss/api_object/group.rb
CHANGED
@@ -304,7 +304,7 @@ module JSS
|
|
304
304
|
### @return [Array<Hash>] the refresh membership
|
305
305
|
###
|
306
306
|
def refresh_members
|
307
|
-
@members = JSS
|
307
|
+
@members = JSS.api_connection.get_rsrc(@rest_rsrc)[self.class::RSRC_OBJECT_KEY][self.class::MEMBER_CLASS::RSRC_LIST_KEY]
|
308
308
|
end
|
309
309
|
|
310
310
|
###
|
@@ -90,7 +90,7 @@ module JSS
|
|
90
90
|
def match(term)
|
91
91
|
raise JSS::InvalidDataError, "Match term may not be empty" if term.to_s.empty?
|
92
92
|
rsrc = "#{self::RSRC_BASE}/#{JSS::Matchable::MATCH_RSRC}/#{term}"
|
93
|
-
JSS
|
93
|
+
JSS.api_connection.get_rsrc(rsrc)[self::RSRC_LIST_KEY]
|
94
94
|
end
|
95
95
|
|
96
96
|
end # module Matchable
|
@@ -26,63 +26,59 @@
|
|
26
26
|
###
|
27
27
|
module JSS
|
28
28
|
|
29
|
-
|
30
|
-
### Module Variables
|
29
|
+
# Module Variables
|
31
30
|
#####################################
|
32
31
|
|
33
|
-
|
34
|
-
### Module Methods
|
32
|
+
# Module Methods
|
35
33
|
#####################################
|
36
34
|
|
37
|
-
|
38
|
-
### Classes
|
35
|
+
# Classes
|
39
36
|
#####################################
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
38
|
+
#
|
39
|
+
# This class represents a Mobile Device stored in the JSS.
|
40
|
+
#
|
41
|
+
# ---
|
42
|
+
# ===Adding devices to the JSS
|
43
|
+
#
|
44
|
+
# This class cannot be used to add new mobile devices to the JSS. That can only be done
|
45
|
+
# via the enrollment process. See JSS::MobileDeviceInvitation for sending
|
46
|
+
# an enrollment invite to a device.
|
47
|
+
#
|
48
|
+
# ---
|
49
|
+
# ===Editing values
|
50
|
+
#
|
51
|
+
# Only a few values can be changed via the API, using these methods, q.v:
|
52
|
+
# - #asset_tag= String
|
53
|
+
# - #extension_attribute= Hash of :name or :id, and :value
|
54
|
+
# - #location= Hash of values in @location, not all are required
|
55
|
+
# - #purchasing= Hash of values in @purchasing, not all are required
|
56
|
+
#
|
57
|
+
# After modfying any values, #save must be called to save changes to the JSS.
|
58
|
+
#
|
59
|
+
# ---
|
60
|
+
# ===MDM Commands
|
61
|
+
#
|
62
|
+
# The following methods can be used to send an APNS command to the device represented by an
|
63
|
+
# instance of JSS::MobileDevice, equivalent to clicking one of the buttons on
|
64
|
+
# the Management Commands section of the Management tab of the Mobile Device details page in the JSS UI.
|
65
|
+
#
|
66
|
+
# The methods supported are:
|
67
|
+
# - blank_push (aliases blank, noop, send_blank_push)
|
68
|
+
# - update_inventory (alias recon)
|
69
|
+
# - device_lock (aliases lock, lock_device)
|
70
|
+
# - erase_device (aliases wipe)
|
71
|
+
# - clear_passcode
|
72
|
+
# - unmanage_device (alias unmanage)
|
73
|
+
#
|
74
|
+
# Each returns true if the command as sent.
|
75
|
+
#
|
76
|
+
# @see JSS::APIObject
|
77
|
+
#
|
78
|
+
#
|
82
79
|
class MobileDevice < JSS::APIObject
|
83
80
|
|
84
|
-
|
85
|
-
### Mix-Ins
|
81
|
+
# Mix-Ins
|
86
82
|
#####################################
|
87
83
|
|
88
84
|
include JSS::Updatable
|
@@ -93,317 +89,412 @@ module JSS
|
|
93
89
|
|
94
90
|
extend JSS::Matchable
|
95
91
|
|
92
|
+
# Class Constants
|
96
93
|
#####################################
|
97
|
-
|
94
|
+
|
95
|
+
# The base for REST resources of this class
|
96
|
+
RSRC_BASE = 'mobiledevices'.freeze
|
97
|
+
|
98
|
+
# the hash key used for the JSON list output of all objects in the JSS
|
99
|
+
RSRC_LIST_KEY = :mobile_devices
|
100
|
+
|
101
|
+
# The hash key used for the JSON object output.
|
102
|
+
# It's also used in various error messages
|
103
|
+
RSRC_OBJECT_KEY = :mobile_device
|
104
|
+
|
105
|
+
# these keys, as well as :id and :name, are present in valid API JSON data for this class
|
106
|
+
VALID_DATA_KEYS = %i[device_name capacity tethered].freeze
|
107
|
+
|
108
|
+
# these keys, as well as :id and :name, can be used to look up objects of this class in the JSS
|
109
|
+
OTHER_LOOKUP_KEYS = {
|
110
|
+
udid: { rsrc_key: :udid, list: :all_udids },
|
111
|
+
serialnumber: { rsrc_key: :serialnumber, list: :all_serial_numbers },
|
112
|
+
serial_number: { rsrc_key: :serialnumber, list: :all_serial_numbers },
|
113
|
+
macaddress: { rsrc_key: :macaddress, list: :all_wifi_mac_addresses },
|
114
|
+
mac_address: { rsrc_key: :macaddress, list: :all_wifi_mac_addresses }
|
115
|
+
}.freeze
|
116
|
+
|
117
|
+
# This class lets us seach for computers
|
118
|
+
SEARCH_CLASS = JSS::AdvancedMobileDeviceSearch
|
119
|
+
|
120
|
+
# This is the class for relevant Extension Attributes
|
121
|
+
EXT_ATTRIB_CLASS = JSS::MobileDeviceExtensionAttribute
|
122
|
+
|
123
|
+
# the rsrc for mobile dev commands
|
124
|
+
MDM_RSRC = 'mobiledevicecommands/command'.freeze
|
125
|
+
|
126
|
+
# The MDM commands sendable via the api
|
127
|
+
# and alternative versions
|
128
|
+
#
|
129
|
+
MDM_COMMANDS = {
|
130
|
+
blank_push: 'BlankPush',
|
131
|
+
send_blank_push: 'BlankPush',
|
132
|
+
blank: 'BlankPush',
|
133
|
+
noop: 'BlankPush',
|
134
|
+
|
135
|
+
settings: 'Settings',
|
136
|
+
|
137
|
+
update_inventory: 'UpdateInventory',
|
138
|
+
recon: 'UpdateInventory',
|
139
|
+
|
140
|
+
device_lock: 'DeviceLock',
|
141
|
+
lock: 'DeviceLock',
|
142
|
+
lock_device: 'DeviceLock',
|
143
|
+
|
144
|
+
erase_device: 'EraseDevice',
|
145
|
+
erase: 'EraseDevice',
|
146
|
+
wipe: 'EraseDevice',
|
147
|
+
|
148
|
+
clear_passcode: 'ClearPasscode',
|
149
|
+
|
150
|
+
clear_restrictions_password: 'ClearRestrictionsPassword',
|
151
|
+
|
152
|
+
enable_data_roaming: 'SettingsEnableDataRoaming',
|
153
|
+
disable_data_roaming: 'SettingsDisableDataRoaming',
|
154
|
+
|
155
|
+
enable_voice_roaming: 'SettingsEnableVoiceRoaming',
|
156
|
+
disable_voice_roaming: 'SettingsDisableVoiceRoaming',
|
157
|
+
|
158
|
+
enable_app_analytics: 'SettingsEnableAppAnalytics',
|
159
|
+
disable_app_analytics: 'SettingsDisableAppAnalytics',
|
160
|
+
|
161
|
+
enable_diagnostic_submission: 'SettingsEnableDiagnosticSubmission',
|
162
|
+
disable_diagnostic_submission: 'SettingsDisableDiagnosticSubmission',
|
163
|
+
|
164
|
+
# wallpaper: 'Wallpaper',
|
165
|
+
|
166
|
+
device_name: 'DeviceName',
|
167
|
+
|
168
|
+
shutdown_device: 'ShutDownDevice',
|
169
|
+
shutdown: 'ShutDownDevice',
|
170
|
+
|
171
|
+
restart_device: 'RestartDevice',
|
172
|
+
restart: 'RestartDevice',
|
173
|
+
|
174
|
+
# passcode_lock_grace_period: 'PasscodeLockGracePeriod',
|
175
|
+
|
176
|
+
unmanage_device: 'UnmanageDevice',
|
177
|
+
unmanage: 'UnmanageDevice'
|
178
|
+
|
179
|
+
}.freeze
|
180
|
+
|
181
|
+
# These MDM commands need extra data.
|
182
|
+
MDM_COMMANDS_REQUIRING_DATA = %w[DeviceLock DeviceName Wallpaper].freeze
|
183
|
+
|
184
|
+
# The History resource
|
185
|
+
HISTORY_RSRC = 'mobiledevicehistory'.freeze
|
186
|
+
|
187
|
+
# Available history subsets
|
188
|
+
HISTORY_SUBSETS = %i[management_commands user_location audits applications ebooks].freeze
|
189
|
+
|
190
|
+
|
191
|
+
# Class Methods
|
98
192
|
#####################################
|
99
193
|
|
100
|
-
|
194
|
+
# @return [Array<String>] all mobiledevice serial_numbers
|
101
195
|
def self.all_serial_numbers(refresh = false)
|
102
|
-
|
196
|
+
all(refresh).map { |i| i[:serial_number] }
|
103
197
|
end
|
104
198
|
|
105
|
-
|
199
|
+
# @return [Array<String>] all mobiledevice phone numbers
|
106
200
|
def self.all_phone_numbers(refresh = false)
|
107
|
-
|
201
|
+
all(refresh).map { |i| i[:phone_number] }.reject(&:empty?)
|
108
202
|
end
|
109
203
|
|
110
|
-
|
204
|
+
# @return [Array<String>] all mobiledevice wifi mac addrs
|
111
205
|
def self.all_wifi_mac_addresses(refresh = false)
|
112
|
-
|
206
|
+
all(refresh).map { |i| i[:wifi_mac_address] }
|
207
|
+
end
|
208
|
+
|
209
|
+
# @return [Array<String>] all mobiledevice wifi mac addrs
|
210
|
+
def self.all_mac_addresses(refresh = false)
|
211
|
+
all_wifi_mac_addresses(refresh)
|
113
212
|
end
|
114
213
|
|
115
|
-
|
214
|
+
# @return [Array<String>] all mobiledevice udids
|
116
215
|
def self.all_udids(refresh = false)
|
117
|
-
|
216
|
+
all(refresh).map { |i| i[:udid] }
|
118
217
|
end
|
119
218
|
|
120
|
-
|
219
|
+
# @return [Array<Hash>] the list of all managed mobile devices
|
121
220
|
def self.all_managed(refresh = false)
|
122
|
-
|
221
|
+
all(refresh).select { |d| d[:managed] }
|
123
222
|
end
|
124
223
|
|
125
|
-
|
224
|
+
# @return [Array<Hash>] the list of all unmanaged mobile devices
|
126
225
|
def self.all_unmanaged(refresh = false)
|
127
|
-
|
226
|
+
all(refresh).reject { |d| d[:managed] }
|
128
227
|
end
|
129
228
|
|
130
|
-
|
229
|
+
# @return [Array<Hash>] the list of all iPhones
|
131
230
|
def self.all_iphones(refresh = false)
|
132
|
-
|
231
|
+
all(refresh).select { |d| d[:model].start_with? 'iPhone' }
|
133
232
|
end
|
134
233
|
|
135
|
-
|
234
|
+
# @return [Array<Hash>] the list of all iPads
|
136
235
|
def self.all_ipads(refresh = false)
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
###
|
141
|
-
### Send an MDM command to a managed mobile device.
|
142
|
-
###
|
143
|
-
### @param dev[Integer,String] the id, name, serialnum, udid, phone num, or wifi macaddr of the device
|
144
|
-
###
|
145
|
-
### @param command[Symbol] the command to send, one of the keys of MOBILE_DEV_MDM_COMMANDS
|
146
|
-
###
|
147
|
-
### @return [Boolean] true if command was sent successfully
|
148
|
-
###
|
149
|
-
### See also {#blank_push}, {#update_inventory}, {#device_lock},
|
150
|
-
### {#erase_device}, {#clear_passcode}, and {#unmanage_device}
|
151
|
-
###
|
152
|
-
def self.send_mdm_command(dev,command)
|
153
|
-
|
154
|
-
raise JSS::NoSuchItemError, "Unknown command '#{command}'" unless MOBILE_DEV_MDM_COMMANDS.keys.include? command
|
155
|
-
command_xml ="#{JSS::APIConnection::XML_HEADER}<mobile_device><command>#{MOBILE_DEV_MDM_COMMANDS[command]}</command></mobile_device>"
|
156
|
-
the_id = nil
|
157
|
-
self.all_managed.each do |mmd|
|
158
|
-
if [mmd[:id], mmd[:name], mmd[:serial_number], mmd[:phone_number], mmd[:udid], mmd[:wifi_mac_address]].include? dev
|
159
|
-
the_id = mmd[:id]
|
160
|
-
break
|
161
|
-
end
|
162
|
-
end # each do mmd
|
163
|
-
|
164
|
-
if the_id
|
165
|
-
response = JSS::API.put_rsrc( "#{RSRC_BASE}/id/#{the_id}", command_xml)
|
166
|
-
response =~ %r{<notification_sent>(.+)</notification_sent>}
|
167
|
-
return ($1 and $1 == "true")
|
168
|
-
end
|
169
|
-
raise JSS::UnmanagedError, "Cannot send command to unknown/unmanaged device '#{dev}'"
|
236
|
+
all(refresh).select { |d| d[:model].start_with? 'iPad' }
|
170
237
|
end
|
171
238
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
RSRC_BASE = "mobiledevices"
|
177
|
-
|
178
|
-
### the hash key used for the JSON list output of all objects in the JSS
|
179
|
-
RSRC_LIST_KEY = :mobile_devices
|
239
|
+
# @return [Array<Hash>] the list of all iPads
|
240
|
+
def self.all_apple_tvs(refresh = false)
|
241
|
+
all(refresh).select { |d| d[:model_identifier].start_with? 'AppleTV' }
|
242
|
+
end
|
180
243
|
|
181
|
-
|
182
|
-
|
183
|
-
|
244
|
+
# Send an MDM command to one or more mobile devices by id or name
|
245
|
+
#
|
246
|
+
#
|
247
|
+
# @param targets[String,Integer,Array<String,Integer>]
|
248
|
+
# the name or id of the mobile devices to receive the command, or
|
249
|
+
# an array of such names or ids, or a comma-separated string
|
250
|
+
# of them.
|
251
|
+
# @param command[Symbol] the command to send, one of the keys
|
252
|
+
# of MDM_COMMANDS
|
253
|
+
#
|
254
|
+
# @param data[String] Some commands require extra data.
|
255
|
+
#
|
256
|
+
# @return [String] The uuid of the MDM command sent, if applicable
|
257
|
+
# (blank pushes do not generate uuids)
|
258
|
+
#
|
259
|
+
def self.send_mdm_command(targets, command, data = nil)
|
260
|
+
raise JSS::NoSuchItemError, "Unknown command '#{command}'" unless MDM_COMMANDS.keys.include? command
|
261
|
+
|
262
|
+
command = MDM_COMMANDS[command]
|
263
|
+
cmd_rsrc = "#{MDM_RSRC}/#{command}"
|
264
|
+
|
265
|
+
if MDM_COMMANDS_REQUIRING_DATA.include? command
|
266
|
+
raise "MDM command '#{command}' requires additional data." unless data
|
267
|
+
cmd_rsrc << "/#{data}"
|
268
|
+
end
|
184
269
|
|
185
|
-
|
186
|
-
VALID_DATA_KEYS = [:device_name, :capacity, :tethered ]
|
270
|
+
targets = JSS.to_s_and_a(targets.to_s)[:arrayform] unless targets.is_a? Array
|
187
271
|
|
188
|
-
|
189
|
-
|
272
|
+
# make sure its an array of ids
|
273
|
+
targets.map! do |md|
|
274
|
+
if all_ids.include? md.to_i
|
275
|
+
md.to_i
|
276
|
+
elsif all_names.include? md
|
277
|
+
map_all_ids_to(:name).invert[md]
|
278
|
+
else
|
279
|
+
raise JSS::NoSuchItemError, "No mobile device found matching '#{md}'"
|
280
|
+
end # if
|
281
|
+
end # map!
|
190
282
|
|
191
|
-
|
192
|
-
SEARCH_CLASS = JSS::AdvancedMobileDeviceSearch
|
283
|
+
cmd_rsrc << "/id/#{targets.join ','}"
|
193
284
|
|
194
|
-
|
195
|
-
|
285
|
+
result = JSS::API.post_rsrc cmd_rsrc, nil
|
286
|
+
result =~ %r{<uuid>(.*)</uuid>}
|
287
|
+
Regexp.last_match(1)
|
288
|
+
end
|
196
289
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
290
|
+
def self.management_history(identifier, subset = nil )
|
291
|
+
id = nil
|
292
|
+
if identifier.is_a? Integer
|
293
|
+
id = identifier
|
294
|
+
else
|
295
|
+
key = case identifier
|
296
|
+
when *all_names then :name
|
297
|
+
when *all_serial_numbers then :serial_number
|
298
|
+
when *all_mac_addresses then :mac_address
|
299
|
+
when *all_udids then :udid
|
300
|
+
end
|
301
|
+
id = map_all_ids_to(key).invert[identifier]
|
302
|
+
end # if identifier.is_a? Integer
|
303
|
+
|
304
|
+
raise JSS::NoSuchItemError, "No MobileDevice found matching #{identifier}" unless id && all_ids.include?(id)
|
305
|
+
|
306
|
+
rsrc = "#{HISTORY_RSRC}/id/#{id}"
|
307
|
+
|
308
|
+
if subset
|
309
|
+
raise "subset must be one of: :#{HISTORY_SUBSETS.join ', :'}" unless HISTORY_SUBSETS.include? subset
|
310
|
+
rsrc << "/subset/#{subset}"
|
311
|
+
end
|
218
312
|
|
313
|
+
hist = JSS.api.get_rsrc(rsrc)[:mobile_device_history]
|
314
|
+
subset ? hist[subset] : hist
|
315
|
+
end
|
219
316
|
|
220
|
-
|
221
|
-
### Attributes
|
317
|
+
# Attributes
|
222
318
|
#####################################
|
223
319
|
|
224
320
|
############
|
225
|
-
|
226
|
-
|
321
|
+
# The values returned in the General and Location subset are stored as direct attributes
|
322
|
+
# Here are the Location values
|
227
323
|
|
228
|
-
|
324
|
+
# @return [String] the airplay passwd on devices that can receive AirPlay (i.e. apple tvs)
|
229
325
|
attr_reader :airplay_password
|
230
326
|
|
231
|
-
|
327
|
+
# @return [String] the asset tag
|
232
328
|
attr_reader :asset_tag
|
233
329
|
|
234
|
-
|
330
|
+
# @return [Intger] how much space available on the device?
|
235
331
|
attr_reader :available_mb
|
236
332
|
|
237
|
-
|
333
|
+
# @return [Integer] total storage on the device
|
238
334
|
attr_reader :capacity_mb
|
239
335
|
|
240
|
-
|
336
|
+
# @return [Integer] how much of the capacity is in use?
|
241
337
|
attr_reader :percentage_used
|
242
338
|
|
243
|
-
|
339
|
+
# @return [Integer] what percentage of the battery is remaining
|
244
340
|
attr_reader :battery_level
|
245
341
|
|
246
|
-
|
342
|
+
# @return [String] the bluetooth mac addr
|
247
343
|
attr_reader :bluetooth_mac_address
|
248
344
|
|
249
|
-
|
345
|
+
# @return [String] the wifi mac addr
|
250
346
|
attr_reader :wifi_mac_address
|
251
347
|
|
252
|
-
|
348
|
+
# @return [Hash] !{:name=>"xxx", :id=>nnn} the computer associated with this device
|
253
349
|
attr_reader :computer
|
254
350
|
|
255
|
-
|
351
|
+
# @return [String] what is this??
|
256
352
|
attr_reader :device_id
|
257
353
|
|
258
|
-
|
354
|
+
# @return [String] the API's device_name and display_name are not used.
|
259
355
|
attr_reader :name
|
260
356
|
|
261
|
-
|
357
|
+
# @return [Time] uses the value from the API's initial_entry_date_epoch
|
262
358
|
attr_reader :initial_entry_date
|
263
359
|
|
264
|
-
|
360
|
+
# @return [String] the IP addr
|
265
361
|
attr_reader :ip_address
|
266
362
|
|
267
|
-
|
363
|
+
# @return [String] the language setting
|
268
364
|
attr_reader :languages
|
269
365
|
|
270
|
-
|
271
|
-
### @return [Time] uses the value from the API's last_backup_time_epoch
|
366
|
+
# @return [Time] uses the value from the API's last_backup_time_epoch
|
272
367
|
attr_reader :last_backup_time
|
273
368
|
|
274
|
-
|
369
|
+
# @return [Time] uses the value from the API's last_inventory_update_utc
|
275
370
|
attr_reader :last_inventory_update
|
276
371
|
|
277
|
-
|
372
|
+
# @return [Time] the last time this device enrolled in Jamf
|
278
373
|
attr_reader :last_enrollment
|
279
374
|
|
280
|
-
|
375
|
+
# @return [String] the locales
|
281
376
|
attr_reader :locales
|
282
377
|
|
283
|
-
|
378
|
+
# @return [Boolean] is this device managed?
|
284
379
|
attr_reader :managed
|
285
380
|
|
286
|
-
|
381
|
+
# @return [Boolean] is this device supervised?
|
287
382
|
attr_reader :supervised
|
288
383
|
|
289
|
-
|
384
|
+
# @return [String] the display name of the model
|
290
385
|
attr_reader :model_display
|
291
386
|
alias model model_display
|
292
387
|
|
293
|
-
|
388
|
+
# @return [String] the model identifier
|
294
389
|
attr_reader :model_identifier
|
295
390
|
|
296
|
-
|
391
|
+
# @return [String] the model firmware
|
297
392
|
attr_reader :modem_firmware
|
298
393
|
|
299
|
-
|
394
|
+
# @return [String] the OS version
|
300
395
|
attr_reader :os_version
|
301
396
|
|
302
|
-
|
397
|
+
# @return [String] the OS build
|
303
398
|
attr_reader :os_build
|
304
399
|
|
305
|
-
|
400
|
+
# @return [String] the phone number of the device's SIM card
|
306
401
|
attr_reader :phone_number
|
307
402
|
|
308
|
-
|
403
|
+
# @return [String] the serial numbee
|
309
404
|
attr_reader :serial_number
|
310
405
|
|
311
|
-
|
312
|
-
### @return [String] the site associated with this device
|
406
|
+
# @return [String] the site associated with this device
|
313
407
|
attr_reader :site
|
314
408
|
|
315
|
-
|
409
|
+
# @return [Boolean] Is this device supervised?
|
316
410
|
attr_reader :supervised
|
317
411
|
|
318
|
-
|
412
|
+
# @return [String] the tether state of the device
|
319
413
|
attr_reader :tethered
|
320
414
|
|
321
|
-
|
415
|
+
# @return [String] the udid
|
322
416
|
attr_reader :udid
|
323
417
|
|
324
|
-
|
418
|
+
# @return [Array<Hash>] the applications on the devices
|
325
419
|
attr_reader :applications
|
326
420
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
421
|
+
# @return [Array<Hash>]
|
422
|
+
#
|
423
|
+
# The certificates on the device
|
424
|
+
#
|
425
|
+
# Each has has two keys:
|
426
|
+
# - :identity => Boolean
|
427
|
+
# - :common_name => String, possibly a udid
|
334
428
|
attr_reader :certificates
|
335
429
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
430
|
+
# @return [Array<Hash>]
|
431
|
+
#
|
432
|
+
# One for each ConfigurationProfile on the device
|
433
|
+
#
|
434
|
+
# The Hash keys are:
|
435
|
+
# - :identifier => a unique id, often the sams as the uuid
|
436
|
+
# - :display_name => its name in the JSS
|
437
|
+
# - :uuid => the ConfigurationProfile uuid
|
438
|
+
# - :version => a String
|
345
439
|
attr_reader :configuration_profiles
|
346
440
|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
### - :id => the group id in the JSS
|
441
|
+
# @return [Array<Hash>]
|
442
|
+
#
|
443
|
+
# One for each group to which the device belongs
|
444
|
+
#
|
445
|
+
# The Hash keys are:
|
446
|
+
# - :name => the group name
|
447
|
+
# - :id => the group id in the JSS
|
355
448
|
attr_reader :mobile_device_groups
|
356
449
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
450
|
+
# @return [Hash]
|
451
|
+
#
|
452
|
+
# A Hash of network data
|
453
|
+
#
|
454
|
+
# The Hash keys are:
|
455
|
+
# - :voice_roaming_enabled=>"Disabled",
|
456
|
+
# - :current_mobile_network_code=>"nnn",
|
457
|
+
# - :imei=>"nn nnnnnn nnnnnn n",
|
458
|
+
# - :home_mobile_country_code=>"nnn",
|
459
|
+
# - :iccid=>"nnnn nnnn nnnn nnnn nnnn",
|
460
|
+
# - :home_mobile_network_code=>"nnn",
|
461
|
+
# - :current_carrier_network=>"",
|
462
|
+
# - :data_roaming_enabled=>false,
|
463
|
+
# - :home_carrier_network=>"AT&T",
|
464
|
+
# - :carrier_settings_version=>"16.0",
|
465
|
+
# - :roaming=>false,
|
466
|
+
# - :cellular_technology=>"GSM",
|
467
|
+
# - :current_mobile_country_code=>"nnn"
|
375
468
|
attr_reader :network
|
376
469
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
470
|
+
# @return [Array<Hash>]
|
471
|
+
#
|
472
|
+
# One per provisioning profile
|
473
|
+
#
|
381
474
|
attr_reader :provisioning_profiles
|
382
475
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
476
|
+
# @return [Hash]
|
477
|
+
#
|
478
|
+
# A Hash of security data
|
479
|
+
#
|
480
|
+
# The Hash has these keys, all of which are Boolean
|
481
|
+
# - :passcode_present=>true,
|
482
|
+
# - :passcode_compliant=>true,
|
483
|
+
# - :passcode_compliant_with_profile=>true,
|
484
|
+
# - :data_protection=>true,
|
485
|
+
# - :block_level_encryption_capable=>true,
|
486
|
+
# - :file_level_encryption_capable=>true
|
394
487
|
attr_reader :security
|
395
488
|
|
396
|
-
|
397
489
|
#####################################
|
398
|
-
|
490
|
+
# Instance Methods
|
399
491
|
#####################################
|
400
492
|
|
401
|
-
|
402
|
-
|
403
|
-
|
493
|
+
#
|
494
|
+
# @see APIObject#initialize
|
495
|
+
#
|
404
496
|
def initialize(args = {})
|
405
|
-
|
406
|
-
super args, [:udid, :serialnumber, :macaddress]
|
497
|
+
super args
|
407
498
|
|
408
499
|
gen = @init_data[:general]
|
409
500
|
@airplay_password = gen[:airplay_password]
|
@@ -419,7 +510,7 @@ module JSS
|
|
419
510
|
@initial_entry_date = JSS.epoch_to_time gen[:initial_entry_date_epoch]
|
420
511
|
@ip_address = gen[:ip_address]
|
421
512
|
@languages = gen[:languages]
|
422
|
-
@last_backup_time = JSS.epoch_to_time
|
513
|
+
@last_backup_time = JSS.epoch_to_time gen[:last_backup_time_epoch]
|
423
514
|
@last_inventory_update = JSS.epoch_to_time gen[:last_inventory_update_epoch]
|
424
515
|
@last_enrollment = JSS.epoch_to_time gen[:last_enrollment_epoch]
|
425
516
|
@locales = gen[:locales]
|
@@ -447,81 +538,383 @@ module JSS
|
|
447
538
|
@provisioning_profiles = @init_data[:provisioning_profiles]
|
448
539
|
@security = @init_data[:security]
|
449
540
|
@applications = @init_data[:applications]
|
450
|
-
|
451
541
|
end # initialize
|
452
542
|
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
###
|
543
|
+
# Send a blank_push MDM command
|
544
|
+
#
|
545
|
+
# @see MobileDevice.send_mdm_command
|
546
|
+
#
|
547
|
+
# @return [String] The command uuid
|
548
|
+
#
|
460
549
|
def blank_push
|
461
550
|
self.class.send_mdm_command @id, :blank_push
|
462
|
-
end
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
###
|
471
|
-
### @return [Boolean]
|
472
|
-
###
|
551
|
+
end #
|
552
|
+
|
553
|
+
# Send an update_inventory MDM command
|
554
|
+
#
|
555
|
+
# @see MobileDevice.send_mdm_command
|
556
|
+
#
|
557
|
+
# @return [String] The command uuid
|
558
|
+
#
|
473
559
|
def update_inventory
|
474
560
|
self.class.send_mdm_command @id, :update_inventory
|
475
561
|
end
|
476
562
|
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
563
|
+
# Send a device_lock MDM command
|
564
|
+
#
|
565
|
+
# @param message[String] The message to display on the lock screen.
|
566
|
+
#
|
567
|
+
# @see MobileDevice.send_mdm_command
|
568
|
+
#
|
569
|
+
# @return [String] The command uuid
|
570
|
+
#
|
571
|
+
def device_lock(message)
|
572
|
+
self.class.send_mdm_command @id, :device_lock, message
|
486
573
|
end
|
487
574
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
### @return [Boolean]
|
495
|
-
###
|
575
|
+
# Send an erase_device MDM command
|
576
|
+
#
|
577
|
+
# @see MobileDevice.send_mdm_command
|
578
|
+
#
|
579
|
+
# @return [String] The command uuid
|
580
|
+
#
|
496
581
|
def erase_device
|
497
582
|
self.class.send_mdm_command @id, :erase_device
|
498
583
|
end
|
499
584
|
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
### @return [Boolean]
|
507
|
-
###
|
585
|
+
# Send a clear_passcode MDM command
|
586
|
+
#
|
587
|
+
# @see MobileDevice.send_mdm_command
|
588
|
+
#
|
589
|
+
# @return [String] The command uuid
|
590
|
+
#
|
508
591
|
def clear_passcode
|
509
592
|
self.class.send_mdm_command @id, :clear_passcode
|
510
593
|
end
|
511
594
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
###
|
595
|
+
# Send a unmanage_device MDM command
|
596
|
+
#
|
597
|
+
# @see MobileDevice.send_mdm_command
|
598
|
+
#
|
599
|
+
# @return [String] The command uuid
|
600
|
+
#
|
519
601
|
def unmanage_device
|
520
602
|
@managed = false if self.class.send_mdm_command(@id, :unmanage_device)
|
521
603
|
end
|
522
604
|
|
605
|
+
# Send a ClearRestrictionsPassword MDM command
|
606
|
+
#
|
607
|
+
# @see MobileDevice.send_mdm_command
|
608
|
+
#
|
609
|
+
# @return [String] The command uuid
|
610
|
+
#
|
611
|
+
def clear_restrictions_password
|
612
|
+
self.class.send_mdm_command @id, :clear_restrictions_password
|
613
|
+
end
|
614
|
+
|
615
|
+
# Send a SettingsEnableDataRoaming MDM command
|
616
|
+
#
|
617
|
+
# @see MobileDevice.send_mdm_command
|
618
|
+
#
|
619
|
+
# @return [String] The command uuid
|
620
|
+
#
|
621
|
+
def enable_data_roaming
|
622
|
+
self.class.send_mdm_command @id, :enable_data_roaming
|
623
|
+
end
|
624
|
+
|
625
|
+
# Send a disable_data_roaming MDM command
|
626
|
+
#
|
627
|
+
# @see MobileDevice.send_mdm_command
|
628
|
+
#
|
629
|
+
# @return [String] The command uuid
|
630
|
+
#
|
631
|
+
def disable_data_roaming
|
632
|
+
self.class.send_mdm_command @id, :disable_data_roaming
|
633
|
+
end
|
634
|
+
|
635
|
+
# Send a enable_voice_roaming MDM command
|
636
|
+
#
|
637
|
+
# @see MobileDevice.send_mdm_command
|
638
|
+
#
|
639
|
+
# @return [String] The command uuid
|
640
|
+
#
|
641
|
+
def enable_voice_roaming
|
642
|
+
self.class.send_mdm_command @id, :enable_voice_roaming
|
643
|
+
end
|
644
|
+
|
645
|
+
# Send a disable_voice_roaming MDM command
|
646
|
+
#
|
647
|
+
# @see MobileDevice.send_mdm_command
|
648
|
+
#
|
649
|
+
# @return [String] The command uuid
|
650
|
+
#
|
651
|
+
def disable_voice_roaming
|
652
|
+
self.class.send_mdm_command @id, :disable_voice_roaming
|
653
|
+
end
|
654
|
+
|
655
|
+
# Send a enable_app_analytics MDM command
|
656
|
+
#
|
657
|
+
# @see MobileDevice.send_mdm_command
|
658
|
+
#
|
659
|
+
# @return [String] The command uuid
|
660
|
+
#
|
661
|
+
def enable_app_analytics
|
662
|
+
self.class.send_mdm_command @id, :enable_app_analytics
|
663
|
+
end
|
664
|
+
|
665
|
+
# Send a disable_app_analytics MDM command
|
666
|
+
#
|
667
|
+
# @see MobileDevice.send_mdm_command
|
668
|
+
#
|
669
|
+
# @return [String] The command uuid
|
670
|
+
#
|
671
|
+
def disable_app_analytics
|
672
|
+
self.class.send_mdm_command @id, :disable_app_analytics
|
673
|
+
end
|
674
|
+
|
675
|
+
# Send a enable_diagnostic_submission MDM command
|
676
|
+
#
|
677
|
+
# @see MobileDevice.send_mdm_command
|
678
|
+
#
|
679
|
+
# @return [String] The command uuid
|
680
|
+
#
|
681
|
+
def enable_diagnostic_submission
|
682
|
+
self.class.send_mdm_command @id, :enable_diagnostic_submission
|
683
|
+
end
|
684
|
+
|
685
|
+
# Send a disable_diagnostic_submission MDM command
|
686
|
+
#
|
687
|
+
# @see MobileDevice.send_mdm_command
|
688
|
+
#
|
689
|
+
# @return [String] The command uuid
|
690
|
+
#
|
691
|
+
def disable_diagnostic_submission
|
692
|
+
self.class.send_mdm_command @id, :disable_diagnostic_submission
|
693
|
+
end
|
694
|
+
|
695
|
+
# Send a device_name MDM command
|
696
|
+
#
|
697
|
+
# @param new_name[String] The name for the device
|
698
|
+
#
|
699
|
+
# @see MobileDevice.send_mdm_command
|
700
|
+
#
|
701
|
+
# @return [String] The command uuid
|
702
|
+
#
|
703
|
+
def device_name(new_name)
|
704
|
+
self.class.send_mdm_command @id, :device_name, new_name
|
705
|
+
end
|
706
|
+
|
707
|
+
# Send a shutdown device MDM command
|
708
|
+
#
|
709
|
+
# @see MobileDevice.send_mdm_command
|
710
|
+
#
|
711
|
+
# @return [String] The command uuid
|
712
|
+
#
|
713
|
+
def shutdown
|
714
|
+
self.class.send_mdm_command @id, :shutdown
|
715
|
+
end
|
716
|
+
|
717
|
+
# Send a restart device MDM command
|
718
|
+
#
|
719
|
+
# @see MobileDevice.send_mdm_command
|
720
|
+
#
|
721
|
+
# @return [String] The command uuid
|
722
|
+
#
|
723
|
+
def restart
|
724
|
+
self.class.send_mdm_command @id, :restart
|
725
|
+
end
|
726
|
+
|
727
|
+
|
728
|
+
# The full management History data for this Mobile Device
|
729
|
+
#
|
730
|
+
# @return [Hash] Keys are:
|
731
|
+
# general: Hash of identifiers
|
732
|
+
# user_location: see user_location_history
|
733
|
+
# management_commands: see management_command_history
|
734
|
+
# audits: see audit_history
|
735
|
+
# applications: see managed_app_history
|
736
|
+
# ebooks: see managed
|
737
|
+
#
|
738
|
+
def management_history
|
739
|
+
self.class.management_history @id
|
740
|
+
end
|
741
|
+
|
742
|
+
# The user_location subset of the full history
|
743
|
+
#
|
744
|
+
# @return [Array<Hash>] Each hash contains user and location data
|
745
|
+
# and the timestamp as a JSS epoch value or string.
|
746
|
+
# use JSS.epoch_to_time or JSS.parse_time to convert them to Time
|
747
|
+
# objects
|
748
|
+
#
|
749
|
+
def user_location_history
|
750
|
+
self.class.management_history @id, :user_location
|
751
|
+
end
|
752
|
+
|
753
|
+
# The management_commands subset of the full history
|
754
|
+
#
|
755
|
+
# @return [Hash] A hash of :completed, :pending, and :failed
|
756
|
+
# mdm commands, each being an array of hashes.
|
757
|
+
# see #completed_mdm_commands, #pending_mdm_commands and
|
758
|
+
# #failed_mdm_commands
|
759
|
+
#
|
760
|
+
def management_command_history
|
761
|
+
self.class.management_history @id, :management_commands
|
762
|
+
end
|
763
|
+
alias mdm_command_history management_command_history
|
764
|
+
|
765
|
+
# The history of completed mdm commands.
|
766
|
+
#
|
767
|
+
# @return [Array<Hash>] Each hash contains a command name and
|
768
|
+
# and the timestamp as a JSS epoch value or string.
|
769
|
+
# use JSS.epoch_to_time or JSS.parse_time to convert them to Time
|
770
|
+
# objects
|
771
|
+
#
|
772
|
+
def completed_mdm_commands
|
773
|
+
management_command_history[:completed]
|
774
|
+
end
|
523
775
|
|
524
|
-
|
776
|
+
# The currently pending mdm commands.
|
777
|
+
#
|
778
|
+
# @return [Array<Hash>] Each hash contains a command name and a :status
|
779
|
+
# and a a timestamp as a JSS epoch value or string.
|
780
|
+
# use JSS.epoch_to_time or JSS.parse_time to convert them to Time
|
781
|
+
# objects
|
782
|
+
#
|
783
|
+
def pending_mdm_commands
|
784
|
+
management_command_history[:pending]
|
785
|
+
end
|
786
|
+
|
787
|
+
# The history of failed mdm commands.
|
788
|
+
#
|
789
|
+
# @return [Array<Hash>] Each hash contains a command name and an :error
|
790
|
+
# message and timestamps for issuance and failure as JSS epoch values
|
791
|
+
# or strings. use JSS.epoch_to_time or JSS.parse_time to convert them to
|
792
|
+
# Time objects
|
793
|
+
#
|
794
|
+
def failed_mdm_commands
|
795
|
+
management_command_history[:failed]
|
796
|
+
end
|
797
|
+
|
798
|
+
# The applications subset of the full history
|
799
|
+
#
|
800
|
+
# @return [Hash] Keys are :installed, :pending, and :failed
|
801
|
+
# See #installed_managed_apps, #pending_managed_apps and
|
802
|
+
# #failed_managed_apps
|
803
|
+
#
|
804
|
+
def managed_app_history
|
805
|
+
self.class.management_history @id, :applications
|
806
|
+
end
|
807
|
+
|
808
|
+
# The apps that have been installed via MDM
|
809
|
+
#
|
810
|
+
# @param from[Symbol] :in_house, :app_store, :other, or :all.
|
811
|
+
# Defaults to :all
|
812
|
+
#
|
813
|
+
# @return [Hash{Array<Hash>}] When from = :all, all three sources.
|
814
|
+
#
|
815
|
+
# @return [Array<Hash>] When from = :in_house, :app_store, or :other
|
816
|
+
# the managed apps that have been installed from that source.
|
817
|
+
# Each Hash includes these keys:
|
818
|
+
# name:
|
819
|
+
# version:
|
820
|
+
# short_version:
|
821
|
+
# management_status:
|
822
|
+
# bundle_size:
|
823
|
+
# dynamic_size:
|
824
|
+
#
|
825
|
+
def installed_managed_apps(from = :all)
|
826
|
+
all = managed_app_history[:installed]
|
827
|
+
case from
|
828
|
+
when :all
|
829
|
+
all
|
830
|
+
when :in_house
|
831
|
+
all[:in_house_from_mobile_device_app_catalog]
|
832
|
+
when :app_store
|
833
|
+
all[:app_store_from_mobile_device_app_catalog]
|
834
|
+
when :other
|
835
|
+
all[:other]
|
836
|
+
else
|
837
|
+
raise JSS::InvalidDataError, "Unknown mobiledevice app source: '#{from}'"
|
838
|
+
end
|
839
|
+
end
|
840
|
+
|
841
|
+
# An array of pending managed app installs.
|
842
|
+
#
|
843
|
+
# @return [Array<Hash>] Hashes for each pending app install
|
844
|
+
#
|
845
|
+
def pending_managed_apps
|
846
|
+
managed_app_history[:pending]
|
847
|
+
end
|
848
|
+
|
849
|
+
# An array of data about failed managed app installs
|
850
|
+
#
|
851
|
+
# @return [Array<Hash>] The name: and version: of each failed app install.
|
852
|
+
#
|
853
|
+
def failed_managed_apps
|
854
|
+
managed_app_history[:failed]
|
855
|
+
end
|
856
|
+
|
857
|
+
# The audits subset of the full history
|
858
|
+
# The history of 'auditable' events.
|
859
|
+
#
|
860
|
+
# @return [Array<Hash>] One hash per event
|
861
|
+
#
|
862
|
+
def audit_history
|
863
|
+
self.class.management_history @id, :audits
|
864
|
+
end
|
865
|
+
|
866
|
+
# The ebooks subset of the full history
|
867
|
+
#
|
868
|
+
# @return [Hash] Keys are :installed, :pending, and :failed
|
869
|
+
# See #installed_managed_ebooks, #pending_managed_ebooks and
|
870
|
+
# #failed_managed_ebooks
|
871
|
+
#
|
872
|
+
def managed_ebook_history
|
873
|
+
self.class.management_history @id, :ebooks
|
874
|
+
end
|
875
|
+
|
876
|
+
# The ebooks that have been installed via MDM
|
877
|
+
#
|
878
|
+
# @param from[Symbol] :in_house, :ibookstore, or :all.
|
879
|
+
# Defaults to :all
|
880
|
+
#
|
881
|
+
# @return [Hash{Array<Hash>}] When from = :all, all three sources.
|
882
|
+
#
|
883
|
+
# @return [Array<Hash>] When from = :in_house, :app_store, or :other
|
884
|
+
# the managed apps that have been installed from that source.
|
885
|
+
#
|
886
|
+
def installed_managed_ebooks(from = :all)
|
887
|
+
all = managed_ebook_history[:installed]
|
888
|
+
case from
|
889
|
+
when :all
|
890
|
+
all
|
891
|
+
when :in_house
|
892
|
+
all[:inhouse]
|
893
|
+
when :ibookstore
|
894
|
+
all[:ibookstore]
|
895
|
+
else
|
896
|
+
raise JSS::InvalidDataError, "Unknown ebook source: '#{from}'"
|
897
|
+
end
|
898
|
+
end
|
899
|
+
|
900
|
+
# Mananged ebooks pending installation
|
901
|
+
#
|
902
|
+
# @return [Array<Hash>] The pending ebooks
|
903
|
+
#
|
904
|
+
def pending_managed_ebooks
|
905
|
+
managed_ebook_history[:pending]
|
906
|
+
end
|
907
|
+
|
908
|
+
# Mananged ebooks tha failed installation
|
909
|
+
#
|
910
|
+
# @return [Array<Hash>] The failed ebook installs
|
911
|
+
#
|
912
|
+
def failed_managed_ebooks
|
913
|
+
managed_ebook_history[:failed]
|
914
|
+
end
|
915
|
+
|
916
|
+
|
917
|
+
# Aliases
|
525
918
|
alias battery_percent battery_level
|
526
919
|
alias managed? managed
|
527
920
|
alias sn serial_number
|
@@ -537,10 +930,6 @@ module JSS
|
|
537
930
|
alias unmanage unmanage_device
|
538
931
|
alias make_unmanaged unmanage_device
|
539
932
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
##############################
|
544
933
|
# private methods
|
545
934
|
##############################
|
546
935
|
|
@@ -552,15 +941,12 @@ module JSS
|
|
552
941
|
|
553
942
|
md << ext_attr_xml
|
554
943
|
|
555
|
-
if has_location?
|
556
|
-
|
557
|
-
end
|
558
|
-
if has_purchasing?
|
559
|
-
md << purchasing_xml
|
560
|
-
end
|
944
|
+
md << location_xml if has_location?
|
945
|
+
md << purchasing_xml if has_purchasing?
|
561
946
|
|
562
|
-
|
947
|
+
doc.to_s
|
563
948
|
end
|
564
949
|
|
565
950
|
end # class Mobile Device
|
951
|
+
|
566
952
|
end # module
|