ruby-jss 0.10.2 → 0.11.0a5

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.

Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +49 -2
  3. data/README.md +14 -7
  4. data/lib/jss/api_connection.rb +48 -24
  5. data/lib/jss/api_object/advanced_search.rb +5 -1
  6. data/lib/jss/api_object/computer.rb +204 -402
  7. data/lib/jss/api_object/computer_invitation.rb +5 -3
  8. data/lib/jss/api_object/ebook.rb +5 -0
  9. data/lib/jss/api_object/extendable.rb +13 -0
  10. data/lib/jss/api_object/group/computer_group.rb +4 -0
  11. data/lib/jss/api_object/group/mobile_device_group.rb +4 -1
  12. data/lib/jss/api_object/group.rb +6 -1
  13. data/lib/jss/api_object/mac_application.rb +5 -0
  14. data/lib/jss/api_object/management_history/audit_event.rb +45 -0
  15. data/lib/jss/api_object/management_history/casper_imaging_log.rb +37 -0
  16. data/lib/jss/api_object/management_history/casper_remote_log.rb +37 -0
  17. data/lib/jss/api_object/management_history/computer_usage_log.rb +43 -0
  18. data/lib/jss/api_object/management_history/ebook.rb +70 -0
  19. data/lib/jss/api_object/management_history/mac_app_store_app.rb +69 -0
  20. data/lib/jss/api_object/management_history/mdm_command.rb +96 -0
  21. data/lib/jss/api_object/management_history/mobile_device_app.rb +99 -0
  22. data/lib/jss/api_object/management_history/policy_log.rb +60 -0
  23. data/lib/jss/api_object/management_history/screen_sharing_log.rb +41 -0
  24. data/lib/jss/api_object/management_history/user_location_change.rb +66 -0
  25. data/lib/jss/api_object/management_history.rb +865 -0
  26. data/lib/jss/api_object/mdm.rb +1298 -0
  27. data/lib/jss/api_object/mobile_device.rb +241 -644
  28. data/lib/jss/api_object/mobile_device_application.rb +6 -0
  29. data/lib/jss/api_object/mobile_device_configuration_profile.rb +36 -0
  30. data/lib/jss/api_object/osx_configuration_profile.rb +115 -151
  31. data/lib/jss/api_object/patch.rb +38 -0
  32. data/lib/jss/api_object/patch_policy.rb +38 -0
  33. data/lib/jss/api_object/peripheral.rb +5 -7
  34. data/lib/jss/api_object/policy.rb +5 -0
  35. data/lib/jss/api_object/restricted_software.rb +5 -0
  36. data/lib/jss/api_object/scopable/scope.rb +367 -411
  37. data/lib/jss/api_object/self_servable.rb +15 -4
  38. data/lib/jss/api_object/sitable.rb +197 -0
  39. data/lib/jss/api_object/site.rb +45 -76
  40. data/lib/jss/api_object/user.rb +7 -3
  41. data/lib/jss/api_object.rb +75 -4
  42. data/lib/jss/utility.rb +21 -0
  43. data/lib/jss/version.rb +1 -1
  44. data/lib/jss.rb +6 -0
  45. metadata +42 -6
@@ -0,0 +1,865 @@
1
+ ### Copyright 2017 Pixar
2
+
3
+ ###
4
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
5
+ ### with the following modification; you may not use this file except in
6
+ ### compliance with the Apache License and the following modification to it:
7
+ ### Section 6. Trademarks. is deleted and replaced with:
8
+ ###
9
+ ### 6. Trademarks. This License does not grant permission to use the trade
10
+ ### names, trademarks, service marks, or product names of the Licensor
11
+ ### and its affiliates, except as required to comply with Section 4(c) of
12
+ ### the License and to reproduce the content of the NOTICE file.
13
+ ###
14
+ ### You may obtain a copy of the Apache License at
15
+ ###
16
+ ### http://www.apache.org/licenses/LICENSE-2.0
17
+ ###
18
+ ### Unless required by applicable law or agreed to in writing, software
19
+ ### distributed under the Apache License with the above modification is
20
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21
+ ### KIND, either express or implied. See the Apache License for the specific
22
+ ### language governing permissions and limitations under the Apache License.
23
+ ###
24
+ ###
25
+
26
+ ###
27
+ module JSS
28
+
29
+ # Mixin Modules
30
+ #####################################
31
+
32
+ # Objects mixing in this module have 'management history' in the JSS, which at
33
+ # this point is Computers and MobileDevices
34
+ #
35
+ # *Important:* this is 'management history', i.e. the history
36
+ # of mdm commands, locations, apps, and other events that are part of
37
+ # management and inventory collection.
38
+ #
39
+ # When viewing the details page for a computer or mobile device in the
40
+ # Web UI, this is the data visible in the 'History' pane of the page.
41
+ #
42
+ # It is not the same as 'object history' which are the changes made to a
43
+ # JSS object in the database, e.g. edits & notes by admins or automated
44
+ # processes in the JSS web UI or via the API. Object history is visble in
45
+ # the Web UI by clicking the 'History' button at the bottom of a machine's
46
+ # details page.
47
+ #
48
+ # == Class & Instance Methods
49
+ #
50
+ # This module provides both class methods, which can be used to retrieve history
51
+ # data without instantiating a full Computer or MobileDevice, and
52
+ # instance methods that are wrappers around the class methods. The methods
53
+ # have the same names, but of course the class methods require arguments
54
+ # specifying the target for which to retrieve data, and which API connection
55
+ # to use.
56
+ #
57
+ # == Raw data versus processed data & event object classes
58
+ #
59
+ # The primary data-retrieval method for management history data is
60
+ # {JSS::ManagementHistory.management_history}. This method returns the raw
61
+ # JSON data from the API, parsed into a ruby Hash.
62
+ #
63
+ # This data is somewhat inconsistent in it's structure and content across the
64
+ # different types of history events, but you're welcome to use it if needed.
65
+ #
66
+ # To provide a more consistent and ruby-like interface to the history events,
67
+ # the remaining methods, which only return subsets of the full dataset, will
68
+ # return Arrays of instances of the classes defined in this module.
69
+ #
70
+ # For example, the {JSS::ManagementHistory.audit_history} method returns an
71
+ # Array of JSS::ManagementHistory::AuditEvent instances, and the
72
+ # {JSS::ManagementHistory.completed_policies} gives an Array of
73
+ # JSS::ManagementHistory::PolicyLog objects. These objects are read-only
74
+ # and provide access to their values via attribute-style methods.
75
+ #
76
+ # NOTE: History queries from the API are *not* cached in ruby-jss, like the
77
+ # APIObject.all data is - it is queried anew every time. For this reason, you
78
+ # are encouraged to store the results of these methods in variables for later
79
+ # use if needed.
80
+ #
81
+ module ManagementHistory
82
+
83
+ # Constants
84
+ #####################################
85
+
86
+ HIST_RAW_STATUS_COMPLETED = 'Completed'.freeze
87
+ HIST_RAW_STATUS_INSTALLED = 'Installed'.freeze
88
+ HIST_RAW_STATUS_MANAGED = 'Managed'.freeze
89
+ HIST_RAW_STATUS_UNMANAGED = 'Unmanaged'.freeze
90
+ HIST_RAW_STATUS_FAILED = 'Failed'.freeze
91
+ HIST_RAW_STATUS_PENDING = 'Pending'.freeze
92
+
93
+ HIST_STATUS_COMPLETED = :completed
94
+ HIST_STATUS_PENDING = :pending
95
+ HIST_STATUS_FAILED = :failed
96
+ HIST_STATUS_INSTALLED = :installed
97
+
98
+ HIST_RAW_SOURCE_APP_IN_HOUSE = :in_house_from_mobile_device_app_catalog
99
+ HIST_RAW_SOURCE_APP_STORE = :app_store_from_mobile_device_app_catalog
100
+ HIST_RAW_SOURCE_EBOOK_IN_HOUSE = :inhouse
101
+ HIST_RAW_SOURCE_IBOOKSTORE = :ibookstore
102
+ HIST_RAW_SOURCE_OTHER = :other
103
+
104
+ HIST_SOURCE_IN_HOUSE = :in_house
105
+ HIST_SOURCE_APP_STORE = :app_store
106
+ HIST_SOURCE_IBOOKSTORE = :ibookstore
107
+ HIST_SOURCE_OTHER = :other
108
+
109
+ HIST_MDM_STATUSES = [HIST_STATUS_COMPLETED, HIST_STATUS_PENDING, HIST_STATUS_FAILED].freeze
110
+ HIST_APP_STATUSES = [HIST_STATUS_INSTALLED, HIST_STATUS_PENDING, HIST_STATUS_FAILED].freeze
111
+
112
+ # The api resource for each history type
113
+ HIST_COMPUTER_RSRC = 'computerhistory'.freeze
114
+ HIST_DEVICE_RSRC = 'mobiledevicehistory'.freeze
115
+
116
+ # The top-level hash key for the history data of each type
117
+ HIST_COMPUTER_KEY = :computer_history
118
+ HIST_DEVICE_KEY = :mobile_device_history
119
+
120
+ # The keys are both the subset names in the resrouce URLS (when
121
+ # converted to strings) and the second-level hash key of the
122
+ # returned subset data.
123
+ #
124
+ HIST_COMPUTER_SUBSETS = %i[
125
+ computer_usage_logs
126
+ audits
127
+ policy_logs
128
+ casper_remote_logs
129
+ screen_sharing_logs
130
+ casper_imaging_logs
131
+ commands
132
+ user_location
133
+ mac_app_store_applications
134
+ ].freeze
135
+
136
+ # The keys are both the subset names in the resrouce URLS (when
137
+ # converted to strings) and the second-level hash key of the
138
+ # returned subset data.
139
+ #
140
+ HIST_DEVICE_SUBSETS = %i[
141
+ management_commands
142
+ user_location
143
+ audits
144
+ applications
145
+ ebooks
146
+ ].freeze
147
+
148
+ # Mixin Class Methods
149
+ ###########################
150
+
151
+ # See
152
+ # https://codereview.stackexchange.com/questions/23637/mixin-both-instance-and-class-methods-in-ruby
153
+ # for discussion of this technique for mixing in both
154
+ # Class and Instance methods when including a module.
155
+ #
156
+ module ClassMethods
157
+
158
+ # Return the raw management history for a Computer or Mobile Device
159
+ #
160
+ # WARNING: It's huge, better to use a subset.
161
+ #
162
+ # NOTE: This returns the raw JSON data from the API, parsed into
163
+ # a ruby Hash. Use the subset-specific methods to retrieve more consistent
164
+ # arrays of ruby-jss objects for each kind of history event, e.g.
165
+ # JSS::Computer.audits(id) or JSS::MobileDevice.audits(id) to get an array
166
+ # of JSS::ManagementHistory::AuditEvent objects
167
+ #
168
+ # @param ident [Integer,String] An identifier (id, name, serialnumber,
169
+ # macadress or udid) of the computer or device for which to retrieve history
170
+ #
171
+ # @param subset[Symbol] the subset to return, rather than full history.
172
+ #
173
+ # @param api[JSS::APIConnection] an API connection to use for the query.
174
+ # Defaults to the corrently active API. See {JSS::APIConnection}
175
+ #
176
+ # @return [Hash,Array] The raw full history or subset requested
177
+ #
178
+ def management_history(ident, subset = nil, api: JSS.api)
179
+ id = valid_id ident, api: api
180
+ raise JSS::NoSuchItemError, "No #{RSRC_OBJECT_KEY} matches identifier: #{ident}" unless id
181
+
182
+ if self == JSS::Computer
183
+ @hist_subsets ||= HIST_COMPUTER_SUBSETS
184
+ @hist_rsrc ||= HIST_COMPUTER_RSRC
185
+ @hist_key ||= HIST_COMPUTER_KEY
186
+ else
187
+ @hist_subsets ||= HIST_DEVICE_SUBSETS
188
+ @hist_rsrc ||= HIST_DEVICE_RSRC
189
+ @hist_key ||= HIST_DEVICE_KEY
190
+ end
191
+
192
+ if subset
193
+ raise "Subset must be one of :#{@hist_subsets.join ', :'}" unless @hist_subsets.include? subset
194
+ subset_rsrc = @hist_rsrc + "/id/#{id}/subset/#{subset}"
195
+ api.get_rsrc(subset_rsrc)[@hist_key][subset]
196
+ else
197
+ api.get_rsrc(@hist_rsrc + "/id/#{id}")[@hist_key]
198
+ end
199
+ end
200
+ alias history management_history
201
+
202
+ # The history of Audit events for a target
203
+ #
204
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
205
+ #
206
+ # @param api [JSS::APIConnection] The API connection to use for the query
207
+ # defaults to the currently active connection
208
+ #
209
+ # @return [Array<JSS::ManagementHistory::AuditEvent>] An array of audit events
210
+ #
211
+ def audit_history(ident, api: JSS.api)
212
+ hist = management_history(ident, :audits, api: api)
213
+ hist.map! { |aud| JSS::ManagementHistory::AuditEvent.new aud }
214
+ end
215
+ alias audits audit_history
216
+
217
+ # The history of User/Location changes for a target
218
+ #
219
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
220
+ #
221
+ # @param api [JSS::APIConnection] The API connection to use for the query
222
+ # defaults to the currently active connection
223
+ #
224
+ # @return [Array<JSS::ManagementHistory::UserLocationChange>] An array of UserLocation change events
225
+ #
226
+ def user_location_history(ident, api: JSS.api)
227
+ hist = management_history(ident, :user_location, api: api)
228
+ hist.map! { |evt| JSS::ManagementHistory::UserLocationChange.new evt }
229
+ end
230
+
231
+ # The history of mdm commands for a target
232
+ #
233
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
234
+ #
235
+ # @param status [Symbol] Return only the :completed, :pending, or :failed commands
236
+ #
237
+ # @param api [JSS::APIConnection] The API connection to use for the query
238
+ # defaults to the currently active connection
239
+ #
240
+ # @return [Array<JSS::ManagementHistory::MDMCommand>] An array of MDMCommands
241
+ #
242
+ def mdm_command_history(ident, status = nil, api: JSS.api)
243
+ subset = self == JSS::Computer ? :commands : :management_commands
244
+ hist = management_history(ident, subset, api: api)
245
+ if status
246
+ raise JSS::InvalidDataError, 'status must be one of :completed, :pending, or :failed' unless HIST_MDM_STATUSES.include? status
247
+ statuses_to_do = [status]
248
+ else
249
+ statuses_to_do = HIST_MDM_STATUSES
250
+ end # if status
251
+
252
+ result = []
253
+
254
+ statuses_to_do.each do |a_status|
255
+ result += hist[a_status].map! do |cmd|
256
+ # failed computer cmds have the error message in cmd[:status]
257
+ # failed mdm commands have them in cmd[:error], where they should be
258
+ cmd[:error] ||= cmd[:status] if a_status == :failed
259
+
260
+ # but we always set the :status
261
+ cmd[:status] = a_status
262
+
263
+ JSS::ManagementHistory::MDMCommand.new cmd
264
+ end # map do |cmd|
265
+ end # statuses_to_do.each do |a_status|
266
+ result
267
+ end # mdm_command_history
268
+ alias commands mdm_command_history
269
+ alias management_command_history mdm_command_history
270
+
271
+ # The history of completed mdm commands for a target
272
+ #
273
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
274
+ #
275
+ # @param api [JSS::APIConnection] The API connection to use for the query
276
+ # defaults to the currently active connection
277
+ #
278
+ # @return [Array<JSS::ManagementHistory::MDMCommand>] An array of completed MDMCommands
279
+ #
280
+ def completed_mdm_commands(ident, api: JSS.api)
281
+ mdm_command_history(ident, :completed, api: api)
282
+ end # completed_mdm_commands
283
+ alias completed_commands completed_mdm_commands
284
+
285
+ # The history of pending mdm commands for a target
286
+ #
287
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
288
+ #
289
+ # @param api [JSS::APIConnection] The API connection to use for the query
290
+ # defaults to the currently active connection
291
+ #
292
+ # @return [Array<JSS::ManagementHistory::MDMCommand>] An array of pending MDMCommands
293
+ #
294
+ def pending_mdm_commands(ident, api: JSS.api)
295
+ mdm_command_history(ident, :pending, api: api)
296
+ end # completed_mdm_commands
297
+ alias pending_commands pending_mdm_commands
298
+
299
+ # The history of failed mdm commands for a target
300
+ #
301
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
302
+ #
303
+ # @param api [JSS::APIConnection] The API connection to use for the query
304
+ # defaults to the currently active connection
305
+ #
306
+ # @return [Array<JSS::ManagementHistory::MDMCommand>] An array of failed MDMCommands
307
+ #
308
+ def failed_mdm_commands(ident, api: JSS.api)
309
+ mdm_command_history(ident, :failed, api: api)
310
+ end # completed_mdm_commands
311
+ alias failed_commands failed_mdm_commands
312
+
313
+ # The history of app store apps for a computer
314
+ #
315
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
316
+ #
317
+ # @param status [Symbol] Return only the :installed, :pending, or :failed apps
318
+ #
319
+ # @param api [JSS::APIConnection] The API connection to use for the query
320
+ # defaults to the currently active connection
321
+ #
322
+ # @return [Array<JSS::ManagementHistory::MacAppStoreApp>] An array of MacAppStoreApp
323
+ #
324
+ def mac_app_store_app_history(ident, status = nil, api: JSS.api)
325
+ raise JSS::UnsupportedError, 'Only computers have mac app store apps' unless self == JSS::Computer
326
+
327
+ hist = management_history(ident, :mac_app_store_applications, api: api)
328
+ if status
329
+ raise JSS::InvalidDataError, 'status must be one of :installed, :pending, or :failed' unless HIST_APP_STATUSES.include? status
330
+ statuses_to_do = [status]
331
+ else
332
+ statuses_to_do = HIST_APP_STATUSES
333
+ end # if status
334
+
335
+ result = []
336
+
337
+ statuses_to_do.each do |a_status|
338
+ result += hist[a_status].map! do |app|
339
+ # set the :status
340
+ app[:status] = a_status
341
+ JSS::ManagementHistory::MacAppStoreApp.new app
342
+ end # map do |cmd|
343
+ end # statuses_to_do.each do |a_status|
344
+
345
+ result
346
+ end # mac_app_store_app_history
347
+
348
+ # The history of apps for a mobile device
349
+ #
350
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
351
+ #
352
+ # @param status [Symbol] Return only the :installed, :pending, or :failed apps
353
+ #
354
+ # @param api [JSS::APIConnection] The API connection to use for the query
355
+ # defaults to the currently active connection
356
+ #
357
+ # @return [Array<JSS::ManagementHistory::MobileDeviceApp>] An array of MobileDeviceApp
358
+ #
359
+ def mobile_device_app_history(ident, status = nil, api: JSS.api)
360
+ raise JSS::UnsupportedError, 'Only mobile devices have mobile device apps' unless self == JSS::MobileDevice
361
+
362
+ hist = management_history(ident, :applications, api: api)
363
+ if status
364
+ raise JSS::InvalidDataError, 'status must be one of :installed, :pending, or :failed' unless HIST_APP_STATUSES.include? status
365
+ statuses_to_do = [status]
366
+ else
367
+ statuses_to_do = HIST_APP_STATUSES
368
+ end # if status
369
+
370
+ result = []
371
+
372
+ statuses_to_do.each do |a_status|
373
+ # merge the sources of installed apps into their hashes
374
+ apps =
375
+ if a_status == :installed
376
+ instapps = []
377
+ hist[a_status].each do |src, apps_from_src|
378
+ real_src =
379
+ case src
380
+ when HIST_RAW_SOURCE_APP_IN_HOUSE then HIST_SOURCE_IN_HOUSE
381
+ when HIST_RAW_SOURCE_APP_STORE then HIST_SOURCE_APP_STORE
382
+ else HIST_SOURCE_OTHER
383
+ end # case src
384
+ instapps += apps_from_src.map! { |iapp| iapp[:source] = real_src }
385
+ end
386
+ instapps
387
+ else
388
+ hist[a_status]
389
+ end
390
+ # now 'apps' is an array of hashes of apps with the same status
391
+ # and if they are :installed, their source is in the hash
392
+
393
+ # merge the statuses of the apps into their hashes
394
+ result += apps.map! do |app|
395
+ # set the :status in the hash
396
+ app[:status] = a_status
397
+ JSS::ManagementHistory::MobileDeviceApp.new app
398
+ end # map do |cmd|
399
+ end # statuses_to_do.each do |a_status|
400
+
401
+ result
402
+ end # mobile_device_app_history
403
+
404
+ # Wrapper for app store history for both computers and mobile devices
405
+ #
406
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
407
+ #
408
+ # @param status [Symbol] Return only the :installed, :pending, or :failed apps
409
+ #
410
+ # @param api [JSS::APIConnection] The API connection to use for the query
411
+ # defaults to the currently active connection
412
+ #
413
+ # @return [Array] An array of MacAppStoreApp or MobileDeviceApp
414
+ #
415
+ def app_store_app_history(ident, status = nil, api: JSS.api)
416
+ if self == JSS::MobileDevice
417
+ mobile_device_app_history(ident, status, api: api)
418
+ else
419
+ mac_app_store_app_history(ident, status, api: api)
420
+ end
421
+ end
422
+ alias managed_app_history app_store_app_history
423
+
424
+ # shortcut for app_store_app_history where status = :installed
425
+ #
426
+ # @see #app_store_app_history
427
+ #
428
+ def installed_app_store_apps(ident, api: JSS.api)
429
+ app_store_app_history(ident, :installed, api: api)
430
+ end
431
+ alias installed_managed_apps installed_app_store_apps
432
+
433
+ # shortcut for app_store_app_history where status = :pending
434
+ #
435
+ # @see #app_store_app_history
436
+ #
437
+ def pending_app_store_apps(ident, api: JSS.api)
438
+ app_store_app_history(ident, :pending, api: api)
439
+ end
440
+ alias pending_managed_apps pending_app_store_apps
441
+
442
+ # shortcut for app_store_app_history where status = :failed
443
+ #
444
+ # @see #app_store_app_history
445
+ #
446
+ def failed_app_store_apps(ident, api: JSS.api)
447
+ app_store_app_history(ident, :failed, api: api)
448
+ end
449
+ alias failed_managed_apps failed_app_store_apps
450
+
451
+ # The history of Casper Imaging events for a computer
452
+ #
453
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
454
+ #
455
+ # @param api [JSS::APIConnection] The API connection to use for the query
456
+ # defaults to the currently active connection
457
+ #
458
+ # @return [Array<JSS::ManagementHistory::CasperImagingLog>] An array of CasperImagingLog events
459
+ #
460
+ def casper_imaging_logs(ident, api: JSS.api)
461
+ raise JSS::UnsupportedError, 'Only computers have casper imaging logs' unless self == JSS::Computer
462
+ hist = management_history(ident, :casper_imaging_logs, api: api)
463
+ hist.map! { |evt| JSS::ManagementHistory::CasperImagingLog.new evt }
464
+ end
465
+
466
+ # The history of Casper Remote events for a computer
467
+ #
468
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
469
+ #
470
+ # @param api [JSS::APIConnection] The API connection to use for the query
471
+ # defaults to the currently active connection
472
+ #
473
+ # @return [Array<JSS::ManagementHistory::CasperRemoteLog>] An array of CasperRemoteLog events
474
+ #
475
+ def casper_remote_logs(ident, api: JSS.api)
476
+ raise JSS::UnsupportedError, 'Only computers have casper remote logs' unless self == JSS::Computer
477
+ hist = management_history(ident, :casper_remote_logs, api: api)
478
+ hist.map! { |evt| JSS::ManagementHistory::CasperRemoteLog.new evt }
479
+ end
480
+
481
+ # The history of usage events for a computer
482
+ #
483
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
484
+ #
485
+ # @param api [JSS::APIConnection] The API connection to use for the query
486
+ # defaults to the currently active connection
487
+ #
488
+ # @return [Array<JSS::ManagementHistory::ComputerUsageLog>] An array of ComputerUsageLog events
489
+ #
490
+ def computer_usage_logs(ident, api: JSS.api)
491
+ raise JSS::UnsupportedError, 'Only computers have usage logs' unless self == JSS::Computer
492
+ hist = management_history(ident, :computer_usage_logs, api: api)
493
+ hist.map! { |evt| JSS::ManagementHistory::ComputerUsageLog.new evt }
494
+ end
495
+ alias usage_logs computer_usage_logs
496
+
497
+ # The history of screen sharing events for a computer
498
+ #
499
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
500
+ #
501
+ # @param api [JSS::APIConnection] The API connection to use for the query
502
+ # defaults to the currently active connection
503
+ #
504
+ # @return [Array<JSS::ManagementHistory::ScreenSharingLog>] An array of ScreenSharingLog events
505
+ #
506
+ def screen_sharing_logs(ident, api: JSS.api)
507
+ raise JSS::UnsupportedError, 'Only computers have screen sharing logs' unless self == JSS::Computer
508
+ hist = management_history(ident, :screen_sharing_logs, api: api)
509
+ hist.map! { |evt| JSS::ManagementHistory::ScreenSharingLog.new evt }
510
+ end
511
+
512
+ # The history of policy execution for a computer
513
+ #
514
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
515
+ #
516
+ # @param api [JSS::APIConnection] The API connection to use for the query
517
+ # defaults to the currently active connection
518
+ #
519
+ # @return [Array<JSS::ManagementHistory::PolicyLog>] An array of PolicyLog events
520
+ #
521
+ def policy_logs(ident, api: JSS.api)
522
+ raise JSS::UnsupportedError, 'Only computers have policy logs' unless self == JSS::Computer
523
+ hist = management_history(ident, :policy_logs, api: api)
524
+ hist.map! { |evt| JSS::ManagementHistory::PolicyLog.new evt }
525
+ end
526
+
527
+ # The array from .policy_logs, limited to status = :completed
528
+ # @see ManagementHistory::ClassMethods.policy_logs
529
+ #
530
+ def completed_policies(ident, api: JSS.api)
531
+ policy_logs(ident, api: api).select { |pl| pl.status == :completed }
532
+ end
533
+
534
+ # The array from .policy_logs, limited to status = :failed
535
+ # @see ManagementHistory::ClassMethods.policy_logs
536
+ #
537
+ def failed_policies(ident, api: JSS.api)
538
+ policy_logs(ident, api: api).select { |pl| pl.status == :failed }
539
+ end
540
+
541
+ # The history of ebooks for a mobile device
542
+ #
543
+ # @param ident [Type] The identifier for the object - id, name, sn, udid, etc.
544
+ #
545
+ # @param status [Symbol] Return only the :installed, :pending, or :failed apps
546
+ #
547
+ # @param api [JSS::APIConnection] The API connection to use for the query
548
+ # defaults to the currently active connection
549
+ #
550
+ # @return [Array<JSS::ManagementHistory::EBook>] An array of EBook
551
+ #
552
+ def ebook_history(ident, status = nil, api: JSS.api)
553
+ raise JSS::UnsupportedError, 'Only mobile devices have ebooks' unless self == JSS::MobileDevice
554
+
555
+ hist = management_history(ident, :ebooks, api: api)
556
+ if status
557
+ raise JSS::InvalidDataError, 'status must be one of :installed, :pending, or :failed' unless HIST_APP_STATUSES.include? status
558
+ statuses_to_do = [status]
559
+ else
560
+ statuses_to_do = HIST_APP_STATUSES
561
+ end # if status
562
+
563
+ result = []
564
+
565
+ statuses_to_do.each do |a_status|
566
+ # merge the sources of installed apps into their hashes
567
+ books =
568
+ if a_status == :installed
569
+ instbooks = []
570
+ hist[a_status].each do |src, books_from_src|
571
+ real_src =
572
+ case src
573
+ when HIST_RAW_SOURCE_EBOOK_IN_HOUSE then HIST_SOURCE_IN_HOUSE
574
+ when HIST_RAW_SOURCE_IBOOKSTORE then HIST_SOURCE_IBOOKSTORE
575
+ else HIST_SOURCE_OTHER
576
+ end # case src
577
+ instbooks += books_from_src.map! { |book| book[:source] = real_src }
578
+ end
579
+ instbooks
580
+ else
581
+ hist[a_status]
582
+ end
583
+ # now 'books' is an array of hashes of books with the same status
584
+ # and if they are :installed, their source is in the hash
585
+
586
+ # merge the statuses of the books into their hashes
587
+ result += books.map! do |book|
588
+ # set the :status in the hash
589
+ book[:status] = a_status
590
+ JSS::ManagementHistory::EBook.new book
591
+ end # map do |books|
592
+ end # statuses_to_do.each do |a_status|
593
+
594
+ result
595
+ end # mobile_device_app_history
596
+ alias managed_ebook_history ebook_history
597
+
598
+ # shortcut for ebook_history where status = :installed
599
+ #
600
+ # @see #ebook_history
601
+ #
602
+ def installed_ebooks(ident, api: JSS.api)
603
+ ebook_history(ident, :installed, api: api)
604
+ end
605
+ alias installed_managed_ebooks installed_ebooks
606
+
607
+ # shortcut for ebook_history where status = :pending
608
+ #
609
+ # @see #ebook_history
610
+ #
611
+ def pending_ebooks(ident, api: JSS.api)
612
+ ebook_history(ident, :pending, api: api)
613
+ end
614
+ alias pending_managed_ebooks pending_ebooks
615
+
616
+ # shortcut for ebook_history where status = :failed
617
+ #
618
+ # @see #ebook_history
619
+ #
620
+ def failed_ebooks(ident, api: JSS.api)
621
+ ebook_history(ident, :failed, api: api)
622
+ end
623
+ alias failed_managed_ebooks failed_ebooks
624
+
625
+ end # module ClassMethods
626
+
627
+ # Extend ourself when included
628
+ # @see {JSS::ManagementHistory::ClassMethods}
629
+ #
630
+ # See https://codereview.stackexchange.com/questions/23637/mixin-both-instance-and-class-methods-in-ruby
631
+ # for discussion of this technique for mixing in both
632
+ # Class and Instance methods when including a module.
633
+ def self.included(klass)
634
+ klass.extend JSS::ManagementHistory::ClassMethods
635
+ end
636
+
637
+ # Mixin Instance Methods
638
+ ###########################
639
+ # See https://codereview.stackexchange.com/questions/23637/mixin-both-instance-and-class-methods-in-ruby
640
+ # for discussion of this technique for mixing in both
641
+ # Class and Instance methods when including a module.
642
+
643
+ # The raw management history data for this object
644
+ #
645
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
646
+ #
647
+ def management_history(subset = nil)
648
+ self.class.management_history(@id, subset, api: @api)
649
+ end
650
+ alias history management_history
651
+
652
+ # The audit_history for this object
653
+ #
654
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
655
+ #
656
+ def audit_history
657
+ self.class.audit_history(@id, api: @api)
658
+ end
659
+ alias audits audit_history
660
+
661
+ # The user_location_history for this object
662
+ #
663
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
664
+ #
665
+ def user_location_history
666
+ self.class.user_location_history(@id, api: @api)
667
+ end
668
+
669
+ # The mdm_command_history for this object
670
+ #
671
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
672
+ #
673
+ def mdm_command_history(status = nil)
674
+ self.class.mdm_command_history(@id, status, api: @api)
675
+ end
676
+ alias commands mdm_command_history
677
+ alias management_command_history mdm_command_history
678
+
679
+ # The completed_mdm_commands for this object
680
+ #
681
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
682
+ #
683
+ def completed_mdm_commands
684
+ self.class.completed_mdm_commands(@id, api: @api)
685
+ end # completed_mdm_commands
686
+ alias completed_commands completed_mdm_commands
687
+
688
+ # The pending_mdm_commands for this object
689
+ #
690
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
691
+ #
692
+ def pending_mdm_commands
693
+ self.class.pending_mdm_commands(@id, api: @api)
694
+ end # completed_mdm_commands
695
+ alias pending_commands pending_mdm_commands
696
+
697
+ # The failed_mdm_commands for this object
698
+ #
699
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
700
+ #
701
+ def failed_mdm_commands
702
+ self.class.failed_mdm_commands(@id, api: @api)
703
+ end # completed_mdm_commands
704
+ alias failed_commands failed_mdm_commands
705
+
706
+ # The mac_app_store_app_history for this computer
707
+ #
708
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
709
+ #
710
+ def mac_app_store_app_history(status = nil)
711
+ self.class.mac_app_store_app_history(@id, status, api: @api)
712
+ end
713
+
714
+ # The mobile_device_app_history for this mobile device
715
+ #
716
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
717
+ #
718
+ def mobile_device_app_history(status = nil)
719
+ self.class.mobile_device_app_history(@id, status, api: @api)
720
+ end
721
+
722
+ # Wrapper for app store history for both computers and mobile devices
723
+ #
724
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
725
+ #
726
+ def app_store_app_history(status = nil)
727
+ self.class.app_store_app_history(@id, status, api: @api)
728
+ end
729
+ alias managed_app_history app_store_app_history
730
+
731
+ # shortcut for app_store_app_history where status = :installed
732
+ #
733
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
734
+ #
735
+ def installed_app_store_apps
736
+ self.class.installed_app_store_apps(@id, api: @api)
737
+ end
738
+ alias installed_managed_apps installed_app_store_apps
739
+
740
+ # shortcut for app_store_app_history where status = :pending
741
+ #
742
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
743
+ #
744
+ def pending_app_store_apps
745
+ self.class.pending_app_store_apps(@id, api: @api)
746
+ end
747
+ alias pending_managed_apps pending_app_store_apps
748
+
749
+ # shortcut for app_store_app_history where status = :failed
750
+ #
751
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
752
+ #
753
+ def failed_app_store_apps
754
+ self.class.failed_app_store_apps(@id, api: @api)
755
+ end
756
+ alias failed_managed_apps failed_app_store_apps
757
+
758
+ # The casper_imaging_logs for this computer
759
+ #
760
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
761
+ #
762
+ def casper_imaging_logs
763
+ self.class.casper_imaging_logs(@id, api: @api)
764
+ end
765
+
766
+ # The casper_remote_logs for this computer
767
+ #
768
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
769
+ #
770
+ def casper_remote_logs
771
+ self.class.casper_remote_logs(@id, api: @api)
772
+ end
773
+
774
+ # The computer_usage_logs for this computer
775
+ #
776
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
777
+ #
778
+ def computer_usage_logs
779
+ self.class.computer_usage_logs(@id, api: @api)
780
+ end
781
+ alias usage_logs computer_usage_logs
782
+
783
+ # The screen_sharing_logs for this computer
784
+ #
785
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
786
+ #
787
+ def screen_sharing_logs
788
+ self.class.screen_sharing_logs(@id, api: @api)
789
+ end
790
+
791
+ # The policy_logs for this computer
792
+ #
793
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
794
+ #
795
+ def policy_logs
796
+ self.class.policy_logs(@id, api: @api)
797
+ end
798
+
799
+ # The array from .policy_logs, limited to status = :completed
800
+ #
801
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
802
+ #
803
+ def completed_policies
804
+ self.class.completed_policies(@id, api: @api)
805
+ end
806
+
807
+ # The array from .policy_logs, limited to status = :failed
808
+ #
809
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
810
+ #
811
+ def failed_policies
812
+ self.class.failed_policies(@id, api: @api)
813
+ end
814
+
815
+ # The ebook_history for this mobile device
816
+ #
817
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
818
+ #
819
+ def ebook_history(status = nil)
820
+ self.class.ebook_history(@id, status, api: @api)
821
+ end
822
+ alias managed_ebook_history ebook_history
823
+
824
+ # shortcut for ebook_history where status = :installed
825
+ #
826
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
827
+ #
828
+ def installed_ebooks
829
+ self.class.installed_ebooks(@id, api: @api)
830
+ end
831
+ alias installed_managed_ebooks installed_ebooks
832
+
833
+ # shortcut for ebook_history where status = :pending
834
+ #
835
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
836
+ #
837
+ def pending_ebooks
838
+ self.class.pending_ebooks(@id, api: @api)
839
+ end
840
+ alias pending_managed_ebooks pending_ebooks
841
+
842
+ # shortcut for ebook_history where status = :failed
843
+ #
844
+ # @see the matching method in {JSS::ManagementHistory::ClassMethods}
845
+ #
846
+ def failed_ebooks
847
+ self.class.failed_ebooks(@id, api: @api)
848
+ end
849
+ alias failed_managed_ebooks failed_ebooks
850
+
851
+ end # module ManagementHistory
852
+
853
+ end # module JSS
854
+
855
+ require 'jss/api_object/management_history/audit_event'
856
+ require 'jss/api_object/management_history/casper_imaging_log'
857
+ require 'jss/api_object/management_history/casper_remote_log'
858
+ require 'jss/api_object/management_history/computer_usage_log'
859
+ require 'jss/api_object/management_history/ebook'
860
+ require 'jss/api_object/management_history/mac_app_store_app'
861
+ require 'jss/api_object/management_history/mdm_command'
862
+ require 'jss/api_object/management_history/mobile_device_app'
863
+ require 'jss/api_object/management_history/policy_log'
864
+ require 'jss/api_object/management_history/screen_sharing_log'
865
+ require 'jss/api_object/management_history/user_location_change'