ruby-jss 0.6.3

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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +7 -0
  3. data/CHANGES.md +112 -0
  4. data/LICENSE.txt +174 -0
  5. data/README.md +426 -0
  6. data/THANKS.md +6 -0
  7. data/bin/cgrouper +485 -0
  8. data/bin/subnet-update +400 -0
  9. data/lib/jss-api.rb +2 -0
  10. data/lib/jss.rb +190 -0
  11. data/lib/jss/api_connection.rb +410 -0
  12. data/lib/jss/api_object.rb +616 -0
  13. data/lib/jss/api_object/advanced_search.rb +389 -0
  14. data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +95 -0
  15. data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
  16. data/lib/jss/api_object/advanced_search/advanced_user_search.rb +95 -0
  17. data/lib/jss/api_object/building.rb +92 -0
  18. data/lib/jss/api_object/category.rb +147 -0
  19. data/lib/jss/api_object/computer.rb +852 -0
  20. data/lib/jss/api_object/creatable.rb +98 -0
  21. data/lib/jss/api_object/criteriable.rb +189 -0
  22. data/lib/jss/api_object/criteriable/criteria.rb +231 -0
  23. data/lib/jss/api_object/criteriable/criterion.rb +228 -0
  24. data/lib/jss/api_object/department.rb +93 -0
  25. data/lib/jss/api_object/distribution_point.rb +560 -0
  26. data/lib/jss/api_object/extendable.rb +221 -0
  27. data/lib/jss/api_object/extension_attribute.rb +466 -0
  28. data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
  29. data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
  30. data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +117 -0
  31. data/lib/jss/api_object/group.rb +380 -0
  32. data/lib/jss/api_object/group/computer_group.rb +124 -0
  33. data/lib/jss/api_object/group/mobile_device_group.rb +139 -0
  34. data/lib/jss/api_object/group/user_group.rb +139 -0
  35. data/lib/jss/api_object/ldap_server.rb +535 -0
  36. data/lib/jss/api_object/locatable.rb +286 -0
  37. data/lib/jss/api_object/matchable.rb +97 -0
  38. data/lib/jss/api_object/mobile_device.rb +556 -0
  39. data/lib/jss/api_object/netboot_server.rb +148 -0
  40. data/lib/jss/api_object/network_segment.rb +414 -0
  41. data/lib/jss/api_object/osx_configuration_profile.rb +262 -0
  42. data/lib/jss/api_object/package.rb +839 -0
  43. data/lib/jss/api_object/peripheral.rb +335 -0
  44. data/lib/jss/api_object/peripheral_type.rb +295 -0
  45. data/lib/jss/api_object/policy.rb +898 -0
  46. data/lib/jss/api_object/purchasable.rb +316 -0
  47. data/lib/jss/api_object/removable_macaddr.rb +98 -0
  48. data/lib/jss/api_object/scopable.rb +136 -0
  49. data/lib/jss/api_object/scopable/scope.rb +621 -0
  50. data/lib/jss/api_object/script.rb +631 -0
  51. data/lib/jss/api_object/self_servable.rb +356 -0
  52. data/lib/jss/api_object/site.rb +93 -0
  53. data/lib/jss/api_object/software_update_server.rb +109 -0
  54. data/lib/jss/api_object/updatable.rb +117 -0
  55. data/lib/jss/api_object/uploadable.rb +138 -0
  56. data/lib/jss/api_object/user.rb +272 -0
  57. data/lib/jss/client.rb +504 -0
  58. data/lib/jss/compatibility.rb +66 -0
  59. data/lib/jss/composer.rb +185 -0
  60. data/lib/jss/configuration.rb +306 -0
  61. data/lib/jss/db_connection.rb +298 -0
  62. data/lib/jss/exceptions.rb +95 -0
  63. data/lib/jss/ruby_extensions.rb +35 -0
  64. data/lib/jss/ruby_extensions/filetest.rb +43 -0
  65. data/lib/jss/ruby_extensions/hash.rb +79 -0
  66. data/lib/jss/ruby_extensions/ipaddr.rb +91 -0
  67. data/lib/jss/ruby_extensions/pathname.rb +77 -0
  68. data/lib/jss/ruby_extensions/string.rb +59 -0
  69. data/lib/jss/ruby_extensions/time.rb +63 -0
  70. data/lib/jss/server.rb +108 -0
  71. data/lib/jss/utility.rb +478 -0
  72. data/lib/jss/version.rb +31 -0
  73. metadata +187 -0
@@ -0,0 +1,898 @@
1
+ ### Copyright 2016 Pixar
2
+ ###
3
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
+ ### with the following modification; you may not use this file except in
5
+ ### compliance with the Apache License and the following modification to it:
6
+ ### Section 6. Trademarks. is deleted and replaced with:
7
+ ###
8
+ ### 6. Trademarks. This License does not grant permission to use the trade
9
+ ### names, trademarks, service marks, or product names of the Licensor
10
+ ### and its affiliates, except as required to comply with Section 4(c) of
11
+ ### the License and to reproduce the content of the NOTICE file.
12
+ ###
13
+ ### You may obtain a copy of the Apache License at
14
+ ###
15
+ ### http://www.apache.org/licenses/LICENSE-2.0
16
+ ###
17
+ ### Unless required by applicable law or agreed to in writing, software
18
+ ### distributed under the Apache License with the above modification is
19
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
+ ### KIND, either express or implied. See the Apache License for the specific
21
+ ### language governing permissions and limitations under the Apache License.
22
+ ###
23
+ ###
24
+
25
+ ###
26
+ module JSS
27
+
28
+ ######################
29
+ ### Module Constants
30
+ ######################
31
+
32
+
33
+ ######################
34
+ ### Module Variables
35
+ ######################
36
+
37
+ ######################
38
+ ### Module Methods
39
+ ######################
40
+
41
+
42
+ #####################################
43
+ ### Classes
44
+ #####################################
45
+
46
+ ###
47
+ ### A class implementing a JSS Policy.
48
+ ###
49
+ ### Like many API objects, the data comes from the API in sections, and
50
+ ### the items in the :general section are mapped to direct attributes
51
+ ### of this Class.
52
+ ###
53
+ ###
54
+ ### Policy instances are partially read-only:
55
+ ### - New policies cannot be created via this class, please use the WebApp.
56
+ ### - Only a few attributes can be changed and updated via the Policy class:
57
+ ### - - name
58
+ ### - - frequency
59
+ ### - - target_drive
60
+ ### - - offline
61
+ ### - - enabled
62
+ ### - - category
63
+ ### - - triggers
64
+ ### - - scope, see {JSS::Scopable} and {JSS::Scopable::Scope}
65
+ ### - - files and processes
66
+ ### All other values and sections must be edited via the Web App.
67
+ ###
68
+ ### Policies may be deleted via this class
69
+ ###
70
+ ### @see JSS::APIObject
71
+ ###
72
+ class Policy < JSS::APIObject
73
+
74
+ #####################################
75
+ ### Mix-Ins
76
+ #####################################
77
+
78
+ include JSS::Updatable
79
+ include JSS::Scopable
80
+ include JSS::Uploadable
81
+
82
+ #####################################
83
+ ### Class Methods
84
+ #####################################
85
+
86
+ #####################################
87
+ ### Class Constants
88
+ #####################################
89
+
90
+
91
+ ### The base for REST resources of this class
92
+ RSRC_BASE = "policies"
93
+
94
+ ### the hash key used for the JSON list output of all objects in the JSS
95
+ RSRC_LIST_KEY = :policies
96
+
97
+ ### The hash key used for the JSON object output.
98
+ ### It's also used in various error messages
99
+ RSRC_OBJECT_KEY = :policy
100
+
101
+ ### these keys, as well as :id and :name, are present in valid API JSON data for this class
102
+ VALID_DATA_KEYS = [:scope, :user_interaction, :files_processes ]
103
+
104
+
105
+ SECTIONS = [
106
+ :general,
107
+ :maintenance,
108
+ :account_maintenance,
109
+ :scripts,
110
+ :self_service,
111
+ :package_configuration,
112
+ :scope,
113
+ :user_interaction,
114
+ :reboot,
115
+ :files_processes,
116
+ :dock_items,
117
+ :disk_encryption,
118
+ :printers
119
+ ]
120
+
121
+ FREQUENCIES = {
122
+ :ongoing => "Ongoing",
123
+ :once_per_computer => "Once per computer",
124
+ :once_per_user =>"Once per user",
125
+ :daily => "Once every day",
126
+ :weekly => "Once every week",
127
+ :monthly => "Once every month"
128
+ }
129
+
130
+ RESTART_WHEN = {
131
+ :if_pkg_requires => "Restart if a package or update requires it",
132
+ :now => "Restart immediately",
133
+ :delayed => "Restart",
134
+ :dont => "Do not restart"
135
+ }
136
+
137
+ RESTART_DISKS = {
138
+ :current => "Current Startup Disk",
139
+ :selected => "Currently Selected Startup Disk (No Bless)",
140
+ :netboot => "NetBoot",
141
+ :os_installer => "inPlaceOSUpgradeDirectory"
142
+ } # Note: any other value in :specify_startup is a path to some other drive to boot from, e.g. /Volumes/Foo
143
+
144
+ ACCOUNT_ACTIONS = {
145
+ :create => "Create",
146
+ :change_pw => "Reset",
147
+ :delete => "Delete",
148
+ :disable_fv2 => "DisableFileVault"
149
+ }
150
+
151
+ MGMT_ACCOUNT_ACTIONS = {
152
+ :no_change => "doNotChange",
153
+ :change_pw => "specified",
154
+ :generate_pw => "random",
155
+ :enable_fv2 => "fileVaultEnable",
156
+ :disable_fv2 => "fileVaultDisable"
157
+ }
158
+
159
+ PACKAGE_ACTIONS = {
160
+ :install => "Install",
161
+ :remove => "Uninstall",
162
+ :cache =>"Cache",
163
+ :install_cache => "Install Cached"
164
+ }
165
+
166
+ SCRIPT_PRIORITIES = {:pre => "Before", :post => "After"}
167
+
168
+ PRINTER_ACTIIONS = {:map => "install", :unmap => "uninstall"}
169
+
170
+ DOCK_ITEM_ACTIONS = {:add_start => "Add To Beginning", :add_end => "Add To End", :remove => "Remove"}
171
+
172
+ NETWORK_REQUIREMENTS = {:any => "Any", :ethernet => "EtherNet"}
173
+
174
+ TRIGGER_EVENTS = {
175
+ :startup => :trigger_startup,
176
+ :login => :trigger_login,
177
+ :logout => :trigger_logout,
178
+ :checkin => :trigger_checkin,
179
+ :network_state => :trigger_network_state_changed ,
180
+ :enrollment => :trigger_enrollment_complete ,
181
+ :custom => :trigger_other
182
+ }
183
+
184
+ TRIGGER_TYPES = {:event => "EVENT", :user => "USER_INITIATED"}
185
+
186
+ SCOPE_TARGET_KEY = :computers
187
+
188
+ ######################
189
+ ### Attributes
190
+ ######################
191
+
192
+ ##### General
193
+ ### This data comes from the :general hash in the raw JSON data
194
+ ### and correspond to the general section of the Edit Policy window in
195
+ ### the JSS WebApp. They are general settings for this policy.
196
+ ### We'll map it to direct attributes.
197
+
198
+ ### @return [String] policy category name
199
+ attr_reader :category
200
+
201
+ ### @return [String] how often to run the policy on each computer
202
+ attr_reader :frequency
203
+
204
+ ### @return [String] which drive should the policy target
205
+ attr_reader :target_drive
206
+
207
+ ### @return [Boolean] should be policy be available offline
208
+ attr_reader :offline
209
+
210
+ ### @return [Boolean] is the policy enabled?
211
+ attr_reader :enabled
212
+
213
+ ### @return [String] a string with the site name
214
+ attr_reader :site
215
+
216
+
217
+ ### @return [Hash]
218
+ ###
219
+ ### Overrides for various defaults
220
+ ###
221
+ ### The hash looks like: !{ :distribution_point => "", :force_afp_smb => false, :netboot_server => "current", :target_drive => "default", :sus => "default"}
222
+ attr_reader :override_default_settings
223
+
224
+ ### The API has a :network_requirements key in the general section, but
225
+ ### in the UI its in a subsection called Client Side Limitiations.
226
+ ### so we'll store it in a hash called client_side_limitations,
227
+ ### defined below.
228
+
229
+ ### the network_limitations hash of the general section seems to be redundant.
230
+ ### it contains minimum_network_connection ("Ethernet" or "No Minimum")
231
+ ### which is also reflected in the general[:network_requirements] ("Ethernet" or "Any")
232
+ ### it contains network_segments, which are also listed
233
+ ### in the limitations hash of the scope section
234
+ ### it contains any_ip_address, which is true or false based on there being
235
+ ### any network_segment limitations.
236
+ ### Therefore, we'll ignore it, and use the other places for that data
237
+
238
+ ### The API has a general key ":date_time_limitations" which has this
239
+ ### this data:
240
+ ### :activation - Time
241
+ ### :expiration - Time
242
+ ### :no_execute_on - An array of short day names as symbols, e.g. [:sun, :mon, :wed, :thu]
243
+ ### :no_execute_start - Time
244
+ ### :no_execute_end - Time
245
+ ### but in the UI, those are set in the Server Side Limitiations and Client Side Limitiations.
246
+ ### areas, so we'll store them in matching hashes below.
247
+ ### attr_reader :date_time_limitations
248
+
249
+ ### @return [Hash]
250
+ ###
251
+ ### The server-side limitations of this policy.
252
+ ###
253
+ ### The keys are :activation and :expiration, both are Times.
254
+ ###
255
+ ### the data comes from the API in the date_time_limitations hash of the general
256
+ ### section, but the UI shows them in the Server Side Limitations area.
257
+ ### This attribute is just for convience and consistency, and just
258
+ ### refers to the data in their API locations
259
+ attr_reader :server_side_limitations
260
+
261
+ ### @return [Hash]
262
+ ###
263
+ ### The client-side limitations of this policy.
264
+ ###
265
+ ### The keys are:
266
+ ### - :no_execute_on - An array of short day names as strings, e.g. ["Sun", "Mon", "Tue"]
267
+ ### - :no_execute_start - Time
268
+ ### - :no_execute_end - Time
269
+ ### - :network_connection - String
270
+ ### The data for the first three comes from the API in the date_time_limitations
271
+ ### hash of the general section.
272
+ ### The fourth comes from the network_requirements of the general section of the API,
273
+ ### but the UI shows them in the Client Side Limitations area.
274
+ ###
275
+ ### This attribute is just for convience and consistency, and just
276
+ ### refers to the data in their API locations
277
+ attr_reader :client_side_limitations
278
+
279
+ ### @return [String]
280
+ ###
281
+ ### Either EVENT or USER_INITIATED
282
+ ###
283
+ ### If it's EVENT, then one or more of the members @trigger_events must true.
284
+ attr_reader :trigger
285
+
286
+ ### @return [Hash]
287
+ ###
288
+ ### The triggers that cause this policy to execute on a client when the @trigger is "EVENT"
289
+ ###
290
+ ### This is a hash with the following keys. Each comes from the API
291
+ ### as a key in the :general hash, but they make more sense separated out
292
+ ### like this.
293
+ ### - :trigger_startup => Bool
294
+ ### - :trigger_login => Bool
295
+ ### - :trigger_logout => Bool
296
+ ### - :trigger_checkin => Bool
297
+ ### - :trigger_network_state_changed => Bool
298
+ ### - :trigger_enrollment_complete => Bool
299
+ ### - :trigger_other => the String that causes a custom trigger
300
+ ###
301
+ ### To edit a value, call
302
+ ### set_trigger_event(type, new_val)
303
+ ### where type is one of the keys in TRIGGER_EVENTS and new val is the new value (usually boolean)
304
+ ###
305
+ attr_reader :trigger_events
306
+
307
+ ##### client machine maintenence
308
+ ### These are the computer maint. tasks
309
+ ### that might be performed by this policy
310
+ ### All are boolean
311
+
312
+ ### @return [Boolean] client maintenance task
313
+ attr_reader :verify_startup_disk
314
+
315
+ ### @return [Boolean] client maintenance task
316
+ attr_reader :permissions_repair
317
+
318
+ ### @return [Boolean] client maintenance task
319
+ attr_reader :recon
320
+
321
+ ### @return [Boolean] client maintenance task
322
+ attr_reader :fix_byhost
323
+
324
+ ### @return [Boolean] client maintenance task
325
+ attr_reader :reset_name
326
+
327
+ ### @return [Boolean] client maintenance task
328
+ attr_reader :flush_system_cache
329
+
330
+ ### @return [Boolean] client maintenance task
331
+ attr_reader :install_cached_pkgs
332
+
333
+ ### @return [Boolean] client maintenance task
334
+ attr_reader :flush_user_cache
335
+
336
+ ### attr_reader :heal # deprecated
337
+ ### attr_reader :prebinding # deprecated
338
+
339
+ ##### client account maint
340
+ ### acct related maintenence performed by this policy
341
+
342
+ ### @return [Array<Hash>]
343
+ ###
344
+ ### The directory bindings applied
345
+ ###
346
+ ### each hash is like: !{:name => "LDAP", :id => 4}
347
+ attr_reader :directory_bindings
348
+
349
+
350
+ ### @return [Hash] the open firmware mode and password
351
+ attr_reader :open_firmware_efi_password
352
+
353
+ ### @return [Hash]
354
+ ###
355
+ ### The management accout changes applied by the policy
356
+ ###
357
+ ### The keys are:
358
+ ### - :action see MGMT_ACCOUNT_ACTIONS
359
+ ### - :managed_password
360
+ ### - :managed_password_md5
361
+ ### - :managed_password_sha256
362
+ ### - :managed_password_length # for random generating pws
363
+ ###
364
+ attr_reader :management_account
365
+
366
+ ### @return [Array<Hash>]
367
+ ###
368
+ ### Local accts acted-upon by this policy
369
+ ###
370
+ ### Keys are:
371
+ ### - :action => "Create",
372
+ ### - :hint => "foo bar",
373
+ ### - :picture => "/path/to/pic.tif",
374
+ ### - :admin => true,
375
+ ### - :home => "/Users/chrisltest",
376
+ ### - :realname => "ChrisTest Lasell",
377
+ ### - :filevault_enabled => true,
378
+ ### - :username => "chrisltest",
379
+ ### - :password_md5 => "3858f62230ac3c915f300c664312c63f",
380
+ ### - : password => "foobar",
381
+ ### - :password_sha256=> "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"
382
+ ###
383
+ attr_reader :accounts
384
+
385
+ ### @return [Array<Hash>]
386
+ ###
387
+ ### The pkgs handled by this policy
388
+ ###
389
+ ### Hash keys are:
390
+ ### - :action => "Install"
391
+ ### - :update_autorun => false,
392
+ ### - :feu => false,
393
+ ### - :name => "rbgem-json-1.6.5-4.pkg",
394
+ ### - :id => 1073
395
+ ###
396
+ attr_reader :packages
397
+
398
+ ### @return [Array<Hash>]
399
+ ###
400
+ ### The scripts run by this policy
401
+ ###
402
+ ### Hash keys are:
403
+ ### - :name => "chromegetter.sh",
404
+ ### - :parameter4 => "",
405
+ ### - :parameter5 => "",
406
+ ### - :parameter6 => "",
407
+ ### - :parameter7 => "",
408
+ ### - :parameter8 => "",
409
+ ### - :parameter9 => "",
410
+ ### - :parameter10 => "",
411
+ ### - :parameter11 => "",
412
+ ### - :id => 1428,
413
+ ### - :priority => "After"
414
+ ###
415
+ attr_reader :scripts
416
+
417
+
418
+ ### @return [Hash]
419
+ ###
420
+ ### Self-service-related data for this policy
421
+ ###
422
+ ### The hash keys are:
423
+ ### - :self_service_icon => !{:uri => String,:id => Integer, :filename => String}
424
+ ### - :use_for_self_service => true,
425
+ ### - :install_button_text => "Install",
426
+ ### - :self_service_description => "Descriptive text",
427
+ ### - :force_users_to_view_description => false
428
+ ###
429
+ ### Note: we'll add a ruby-std convenience method below "self_service?"
430
+ ### which returns the :use_for_self_service key.
431
+ attr_reader :self_service
432
+
433
+ #### user interaction
434
+ ### These are extracted from the :user_interaction hash
435
+ ### in the JSON output, which looks like this:
436
+ ### :message_start => "",
437
+ ### :allow_users_to_defer => false,
438
+ ### :allow_deferral_until_utc => "",
439
+ ### :message_finish => ""
440
+ ###
441
+
442
+ ### @return [Boolean] can the user defer the policy?
443
+ attr_reader :user_may_defer
444
+
445
+ ### @return [Time] when is the user no longer allowed to defer?
446
+ attr_reader :user_may_defer_until
447
+
448
+ ### @return [String] the message shown the user at policy start
449
+ attr_reader :user_message_start
450
+
451
+ ### @return [String] the message shown the user at policy end
452
+ attr_reader :user_message_finish
453
+
454
+ ### @return [Hash]
455
+ ###
456
+ ### Reboot options for the policy
457
+ ###
458
+ ### The hash keys are:
459
+ ### - :user_logged_in => "Do not restart",
460
+ ### - :minutes_until_reboot => 5,
461
+ ### - :message=> "This computer will restart in 5 minutes. Please save anything you are working on and log out by choosing Log Out from the bottom of the Apple menu.",
462
+ ### - :startup_disk => "Current Startup Disk",
463
+ ### - :specify_startup => "",
464
+ ### - :no_user_logged_in => "Do not restart"
465
+ ###
466
+ attr_reader :reboot_options
467
+
468
+ ##### files & processes
469
+ ### a hash like this:
470
+ ### {:spotlight_search => "Spotlight This",
471
+ ### :search_for_process => "SafariProcess",
472
+ ### :search_by_path => "/this/is/a/path",
473
+ ### :kill_process => true,
474
+ ### :delete_file => true,
475
+ ### :run_command => "/usr/local/pixar/sbin/force-fde-logout --setup",
476
+ ### :locate_file => "this-is-a-filename",
477
+ ### :update_locate_database => true}
478
+ ###
479
+ ### NOTE, since these items are editable, they have custom getters/setters
480
+ ### so that the hash isn't directly changable without @need_to_update.
481
+ ### attr_reader :files_processes
482
+
483
+
484
+ ### @return [Array<Hash>]
485
+ ###
486
+ ### The dock items handled by this policy
487
+ ###
488
+ ### each item hash looks like: !{:name => "Mail", :id => 14, :action => "Add To Beginning"}
489
+ attr_reader :dock_items
490
+
491
+ ### @return [Hash]
492
+ ###
493
+ ### Disk encryption options for this policy
494
+ ###
495
+ ### The hash looks like !{:disk_encryption_configuration_id => 3, :action => "apply"}
496
+ attr_reader :disk_encryption
497
+
498
+ ### @return [Array<Hash>]
499
+ ###
500
+ ### The printers handled by this policy
501
+ ###
502
+ ### Each Hash looks like: !{:make_default => false, :name => "torlan", :id => 3, :action => "install"}
503
+ attr_reader :printers
504
+
505
+ #####################################
506
+ ### Public Instance Methods
507
+ #####################################
508
+
509
+ ###
510
+ ### @see APIObject#initialize
511
+ ###
512
+ def initialize(args = {})
513
+
514
+ super
515
+
516
+
517
+ gen = @init_data[:general]
518
+ @category = JSS::APIObject.get_name(gen[:category])
519
+ @frequency = gen[:frequency]
520
+ @target_drive = gen[:target_drive]
521
+ @offline = gen[:offline]
522
+ @enabled = gen[:enabled]
523
+ @site = JSS::APIObject.get_name(gen[:site][:name])
524
+ @override_default_settings = gen[:override_default_settings]
525
+ @trigger = gen[:trigger ]
526
+ @trigger_events = {
527
+ :trigger_startup => gen[:trigger_startup ],
528
+ :trigger_login => gen[:trigger_login ],
529
+ :trigger_logout => gen[:trigger_logout ],
530
+ :trigger_checkin => gen[:trigger_checkin ],
531
+ :trigger_network_state_changed => gen[:trigger_network_state_changed ],
532
+ :trigger_enrollment_complete => gen[:trigger_enrollment_complete ],
533
+ :trigger_other => gen[:trigger_other ]
534
+ }
535
+
536
+ dtl = gen[:date_time_limitations]
537
+
538
+ @server_side_limitations = {
539
+ :activation => JSS.epoch_to_time(dtl[:activation_date_epoch]),
540
+ :expiration => JSS.epoch_to_time(dtl[:expiration_date_epoch])
541
+ }
542
+
543
+ @client_side_limitations = {
544
+ :no_execute_on => dtl[:no_execute_on], # NOTE- there's a bug in the JSON output, it's been reported to JAMF.
545
+ :no_execute_start => dtl[:no_execute_start], # String like "1:01 AM"
546
+ :no_execute_end => dtl[:no_execute_end], # String like "2:02 PM"
547
+ :network_requirements => gen[:network_requirements]
548
+ }
549
+
550
+ maint = @init_data[:maintenance]
551
+ @verify_startup_disk = maint[:verify]
552
+ @permissions_repair = maint[:permissions]
553
+ @recon = maint[:recon]
554
+ @fix_byhost = maint[:byhost]
555
+ @reset_name = maint[:reset_name]
556
+ @flush_system_cache = maint[:system_cache]
557
+ @install_cached_pkgs = maint[:install_all_cached_packages]
558
+ @flush_user_cache = maint[:user_cache]
559
+
560
+ amaint = @init_data[:account_maintenance]
561
+ @directory_bindings = amaint[:directory_bindings]
562
+ @open_firmware_efi_password = amaint[:open_firmware_efi_password]
563
+ @management_account = amaint[:management_account]
564
+ @accounts = amaint[:accounts]
565
+
566
+ @packages = @init_data[:package_configuration][:packages] ? @init_data[:package_configuration][:packages] : []
567
+
568
+ @scripts = @init_data[:scripts]
569
+
570
+ @self_service = @init_data[:self_service]
571
+
572
+ uint = @init_data[:user_interaction]
573
+ @user_may_defer = uint[:allow_users_to_defer]
574
+ @user_may_defer_until = JSS.parse_datetime uint[:allow_deferral_until_utc]
575
+ @user_message_start = uint[:message_start]
576
+ @user_message_finish = uint[:message_finish]
577
+
578
+ @reboot_options = @init_data[:reboot]
579
+
580
+ @files_processes = @init_data[:files_processes]
581
+
582
+ @dock_items = @init_data[:dock_items]
583
+
584
+ @disk_encryption = @init_data[:disk_encryption]
585
+
586
+ @printers = @init_data[:printers]
587
+
588
+ parse_scope
589
+
590
+ end # init
591
+
592
+ ###
593
+ ### Change the enabled state of this item
594
+ ###
595
+ ### @param new_val[Boolean] the new state.
596
+ ###
597
+ ### @return [void]
598
+ ###
599
+ def enabled= (new_val)
600
+ return nil if @enabled == new_val
601
+ raise JSS::InvalidDataError, "New value must be true or false" unless JSS::TRUE_FALSE.include? new_val
602
+ @enabled = new_val
603
+ @need_to_update = true
604
+ end
605
+
606
+ ###
607
+ ### Set a new frequency for this policy.
608
+ ###
609
+ ### @param freq[Symbol] the desired frequency, must be one of the keys of {FREQUENCIES}
610
+ ###
611
+ ### @return [void]
612
+ ###
613
+ def frequency= (freq)
614
+ raise JSS::InvalidDataError, "New frequency must be one of :#{FREQUENCIES.keys.join ", :"}" unless FREQUENCIES.keys.include? freq
615
+ @frequency = FREQUENCIES[freq]
616
+ @need_to_update = true
617
+ end
618
+
619
+ ###
620
+ ### Set a new target drive for this policy.
621
+ ###
622
+ ### @param path_to_drive[String,Pathname] the full path to the target drive, must start with a '/'
623
+ ###
624
+ ### @return [void]
625
+ ###
626
+ def target_drive= (path_to_drive)
627
+ raise JSS::InvalidDataError, "Path to target drive must be absolute" unless path_to_drive.to_s.start_with? '/'
628
+ @target_drive = path_to_drive.to_s
629
+ @need_to_update = true
630
+ end
631
+
632
+ ###
633
+ ### Set whether this policy is available offline.
634
+ ###
635
+ ### @param new_val[Boolean]
636
+ ###
637
+ ### @return [void]
638
+ ###
639
+ def offline= (new_val)
640
+ raise JSS::InvalidDataError, "New value must be boolean true or false" unless JSS::TRUE_FALSE.include? new_val
641
+ @offline = new_val
642
+ @need_to_update = true
643
+ end
644
+
645
+ ###
646
+ ### Change the category of this item, arg is a category name
647
+ ###
648
+ ### @param new_val[String] the name of the new category
649
+ ###
650
+ ### @return [void]
651
+ ###
652
+ def category= (new_val = JSS::Category::DEFAULT_CATEGORY)
653
+ return nil if @category == new_val
654
+ new_val = nil if new_val == ''
655
+ new_val ||= JSS::Category::DEFAULT_CATEGORY
656
+ raise JSS::NoSuchItemError, "No category '#{new_val}' in the JSS" unless JSS::Category.all_names(:refresh).include? new_val
657
+ @category = new_val
658
+ @need_to_update = true
659
+ end
660
+
661
+ ###
662
+ ### Change a trigger event
663
+ ###
664
+ ### @param type[Symbol] the type of trigger, one of the keys of {TRIGGER_EVENTS}
665
+ ###
666
+ ### @param new_val[Boolean] whether the type of trigger is active or not.
667
+ ###
668
+ ### @return [void]
669
+ ###
670
+ def set_trigger_event (type, new_val)
671
+ raise JSS::InvalidDataError, "Trigger type must be one of #{TRIGGER_EVENTS.keys.join(', ')}" unless TRIGGER_EVENTS.keys.include? type
672
+ if type == :custom
673
+ raise JSS::InvalidDataError, "Custom triggers must be Strings" unless new_val.kind_of? String
674
+ else
675
+ raise JSS::InvalidDataError, "Non-custom triggers must be true or false" unless JSS::TRUE_FALSE.include? new_val
676
+ end
677
+ @trigger_events[TRIGGER_EVENTS[type]] = new_val
678
+ @need_to_update = true
679
+ end
680
+
681
+ ###
682
+ ### @return [String] The unix shell command to run on ths client.
683
+ ###
684
+ def run_command ; @files_processes[:run_command] ; end
685
+
686
+ ###
687
+ ### Set the unix shell command to be run on the client
688
+ ###
689
+ ### @param command[String] the unix shell command to be run on the client
690
+ ###
691
+ ### @return [void]
692
+ ###
693
+ def run_command= (command)
694
+ raise JSS::InvalidDataError, "Command to run must be a String" unless command.is_a? String
695
+ @files_processes[:run_command] = command
696
+ @need_to_update = true
697
+ end
698
+
699
+ ###
700
+ ### @return [Boolean] Should we update the database used by the locate command?
701
+ ###
702
+ def update_locate_database? ; @files_processes[:update_locate_database] ; end
703
+
704
+ ###
705
+ ### Set whether or not to update the database used by the locate command.
706
+ ###
707
+ ### @param tf[Boolean] whether or not to update the database used by the locate command.
708
+ ###
709
+ ### @return [void]
710
+ ###
711
+ def update_locate_database= (tf)
712
+ @files_processes[:update_locate_database] = tf ? true : false
713
+ @need_to_update = true
714
+ end
715
+
716
+ ###
717
+ ### @return [String] The process name to search for on the client
718
+ ###
719
+ def search_for_process
720
+ @files_processes[:search_for_process]
721
+ end
722
+
723
+ ###
724
+ ### @return [Boolean] Should the searched-for process be killed if found.
725
+ ###
726
+ def kill_process?
727
+ @files_processes[:kill_process]
728
+ end
729
+
730
+ ###
731
+ ### Set the process name to search for, and if it should be killed if found.
732
+ ###
733
+ ### Setter methods (which end with =) can't easily take
734
+ ### multiple arguments, so we instead name them "set_blah_blah"
735
+ ### rather than "blah_blah="
736
+ ###
737
+ ### @param process[String] the process name to search for
738
+ ###
739
+ ### @param kill[Boolean] should be process be killed if found
740
+ ###
741
+ ### @return [void]
742
+ ###
743
+ def set_search_for_process (process, kill = false)
744
+ @files_processes[:search_for_process] = process.to_s
745
+ @files_processes[:kill_process] = kill ? true : false
746
+ @need_to_update = true
747
+ end
748
+
749
+ ###
750
+ ### @return [Pathname] The path to search for
751
+ ###
752
+ def search_by_path ; Pathname.new @files_processes[:search_by_path] ; end
753
+
754
+ ###
755
+ ### @return [Boolean] Should the searched-for path be deleted if found?
756
+ ###
757
+ def delete_file? ; @files_processes[:delete_file] ; end
758
+
759
+ ###
760
+ ### Set the path to search for, a String or Pathname, and whether or not to delete it if found.
761
+ ###
762
+ ### Setter methods (which end with =) can't easily take
763
+ ### multiple arguments, so we instead name them "set_blah_blah"
764
+ ### rather than "blah_blah="
765
+ ###
766
+ ### @param path[String,Pathname] the path to search for
767
+ ###
768
+ ### @param delete[Boolean] should the path be deleted if found
769
+ ###
770
+ ### @return [void]
771
+ ###
772
+ def set_search_by_path (path, delete = false)
773
+ raise JSS::InvalidDataError, "Path to search for must be a String or a Pathname" unless path.is_a? String or path.is_a? Pathname
774
+ @files_processes[:search_by_path] = path.to_s
775
+ @files_processes[:delete_file] = delete ? true : false
776
+ @need_to_update = true
777
+ end
778
+
779
+ ###
780
+ ### @return [String] The term to search for using spotlight
781
+ ###
782
+ def spotlight_search ; @files_processes[:spotlight_search] ; end
783
+
784
+ ### Set the term to seach for using spotlight
785
+ ###
786
+ ### @param term[String] the term to seach for using spotlight
787
+ ###
788
+ ### @return [void]
789
+ ###
790
+ def spotlight_search= (term)
791
+ raise JSS::InvalidDataError, "Spotlight search term must be a String" unless term.is_a? String
792
+ @files_processes[:spotlight_search] = term
793
+ @need_to_update = true
794
+ end
795
+
796
+ ###
797
+ ### @return [String] The term to seach for using the locate command
798
+ ###
799
+ def locate_file ; @files_processes[:locate_file] ; end
800
+
801
+ ### Set the term to seach for using the locate command
802
+ ###
803
+ ### @param term[String] the term to seach for using the locate command
804
+ ###
805
+ ### @return [void]
806
+ ###
807
+ def locate_file= (term)
808
+ raise JSS::InvalidDataError, "Term to locate must be a String" unless term.is_a? String
809
+ @files_processes[:locate_file] = term
810
+ @need_to_update = true
811
+ end
812
+
813
+ ### @return [Array] the id's of the packages handled by the policy
814
+ def package_ids; @packages.map{|p| p[:id]} ; end
815
+
816
+ ### @return [Array] the names of the packages handled by the policy
817
+ def package_names; @packages.map{|p| p[:name]} ; end
818
+
819
+ ### @return [Array] the id's of the scripts handled by the policy
820
+ def script_ids; @scripts.map{|p| p[:id]} ; end
821
+
822
+ ### @return [Array] the names of the scripts handled by the policy
823
+ def script_names; @scripts.map{|p| p[:name]} ; end
824
+
825
+ ### @return [Array] the id's of the directory_bindings handled by the policy
826
+ def directory_binding_ids; @directory_bindings.map{|p| p[:id]} ; end
827
+
828
+ ### @return [Array] the names of the directory_bindings handled by the policy
829
+ def directory_binding_names; @directory_bindings.map{|p| p[:name]} ; end
830
+
831
+ ### @return [Array] the id's of the dock_items handled by the policy
832
+ def dock_item_ids; @dock_items.map{|p| p[:id]} ; end
833
+
834
+ ### @return [Array] the names of the dock_items handled by the policy
835
+ def dock_item_names; @dock_items.map{|p| p[:name]} ; end
836
+
837
+ ### @return [Array] the id's of the printers handled by the policy
838
+ def printer_ids; @printers.map{|p| p[:id]} ; end
839
+
840
+ ### @return [Array] the names of the printers handled by the policy
841
+ def printer_names; @printers.map{|p| p[:name]} ; end
842
+
843
+ ### @return [Boolean] is this policy available in SelfService?
844
+ def self_service?; @self_service[:use_for_self_service] ; end
845
+
846
+ ### Try to execute this policy on this machine.
847
+ ###
848
+ ### @param show_output[Boolean] should the stdout and stderr of the
849
+ ### 'jamf policy' command be sent to stdout in realtime?
850
+ ###
851
+ ### @return [Boolean, nil] The success of the 'jamf policy' command, or nil
852
+ ### if the policy couldn't be executed (out of scope, policy disabled, etc)
853
+ ###
854
+ def run (show_output = false)
855
+ return nil unless enabled?
856
+ output = JSS::Client.run_jamf("policy", "-id #{id}", show_output)
857
+ return nil if output.include? 'No policies were found for the ID'
858
+ return $?.exitstatus == 0 ? true : false
859
+ end
860
+
861
+ ### Aliases
862
+ alias enabled? enabled
863
+ alias pkgs packages
864
+ alias command_to_run run_command
865
+ alias delete_path? delete_file?
866
+ alias execute run
867
+
868
+ #####################################
869
+ ### Private Instance Methods
870
+ #####################################
871
+ private
872
+
873
+ def rest_xml
874
+ doc = REXML::Document.new APIConnection::XML_HEADER
875
+ obj = doc.add_element RSRC_OBJECT_KEY.to_s
876
+
877
+ general = obj.add_element "general"
878
+ general.add_element('name').text = @name
879
+ general.add_element('enabled').text = @enabled
880
+ general.add_element('frequency').text = @frequency
881
+ general.add_element('target_drive').text = @target_drive
882
+ general.add_element('offline').text = @offline
883
+ general.add_element('category').add_element('name').text = @category
884
+
885
+ JSS.hash_to_rexml_array(@trigger_events).each{|t| general << t}
886
+
887
+ obj << @scope.scope_xml
888
+
889
+ files_processes = obj.add_element "files_processes"
890
+ JSS.hash_to_rexml_array(@files_processes).each{|f| files_processes << f}
891
+
892
+ return doc.to_s
893
+ end
894
+
895
+ end # class policy
896
+
897
+ end # module
898
+