ruby-jss 0.10.2 → 0.11.0a5

Sign up to get free protection for your applications and to get access to all the features.

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'