ruby-jss 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.yardopts +7 -0
- data/CHANGES.md +112 -0
- data/LICENSE.txt +174 -0
- data/README.md +426 -0
- data/THANKS.md +6 -0
- data/bin/cgrouper +485 -0
- data/bin/subnet-update +400 -0
- data/lib/jss-api.rb +2 -0
- data/lib/jss.rb +190 -0
- data/lib/jss/api_connection.rb +410 -0
- data/lib/jss/api_object.rb +616 -0
- data/lib/jss/api_object/advanced_search.rb +389 -0
- data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +95 -0
- data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
- data/lib/jss/api_object/advanced_search/advanced_user_search.rb +95 -0
- data/lib/jss/api_object/building.rb +92 -0
- data/lib/jss/api_object/category.rb +147 -0
- data/lib/jss/api_object/computer.rb +852 -0
- data/lib/jss/api_object/creatable.rb +98 -0
- data/lib/jss/api_object/criteriable.rb +189 -0
- data/lib/jss/api_object/criteriable/criteria.rb +231 -0
- data/lib/jss/api_object/criteriable/criterion.rb +228 -0
- data/lib/jss/api_object/department.rb +93 -0
- data/lib/jss/api_object/distribution_point.rb +560 -0
- data/lib/jss/api_object/extendable.rb +221 -0
- data/lib/jss/api_object/extension_attribute.rb +466 -0
- data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
- data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
- data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +117 -0
- data/lib/jss/api_object/group.rb +380 -0
- data/lib/jss/api_object/group/computer_group.rb +124 -0
- data/lib/jss/api_object/group/mobile_device_group.rb +139 -0
- data/lib/jss/api_object/group/user_group.rb +139 -0
- data/lib/jss/api_object/ldap_server.rb +535 -0
- data/lib/jss/api_object/locatable.rb +286 -0
- data/lib/jss/api_object/matchable.rb +97 -0
- data/lib/jss/api_object/mobile_device.rb +556 -0
- data/lib/jss/api_object/netboot_server.rb +148 -0
- data/lib/jss/api_object/network_segment.rb +414 -0
- data/lib/jss/api_object/osx_configuration_profile.rb +262 -0
- data/lib/jss/api_object/package.rb +839 -0
- data/lib/jss/api_object/peripheral.rb +335 -0
- data/lib/jss/api_object/peripheral_type.rb +295 -0
- data/lib/jss/api_object/policy.rb +898 -0
- data/lib/jss/api_object/purchasable.rb +316 -0
- data/lib/jss/api_object/removable_macaddr.rb +98 -0
- data/lib/jss/api_object/scopable.rb +136 -0
- data/lib/jss/api_object/scopable/scope.rb +621 -0
- data/lib/jss/api_object/script.rb +631 -0
- data/lib/jss/api_object/self_servable.rb +356 -0
- data/lib/jss/api_object/site.rb +93 -0
- data/lib/jss/api_object/software_update_server.rb +109 -0
- data/lib/jss/api_object/updatable.rb +117 -0
- data/lib/jss/api_object/uploadable.rb +138 -0
- data/lib/jss/api_object/user.rb +272 -0
- data/lib/jss/client.rb +504 -0
- data/lib/jss/compatibility.rb +66 -0
- data/lib/jss/composer.rb +185 -0
- data/lib/jss/configuration.rb +306 -0
- data/lib/jss/db_connection.rb +298 -0
- data/lib/jss/exceptions.rb +95 -0
- data/lib/jss/ruby_extensions.rb +35 -0
- data/lib/jss/ruby_extensions/filetest.rb +43 -0
- data/lib/jss/ruby_extensions/hash.rb +79 -0
- data/lib/jss/ruby_extensions/ipaddr.rb +91 -0
- data/lib/jss/ruby_extensions/pathname.rb +77 -0
- data/lib/jss/ruby_extensions/string.rb +59 -0
- data/lib/jss/ruby_extensions/time.rb +63 -0
- data/lib/jss/server.rb +108 -0
- data/lib/jss/utility.rb +478 -0
- data/lib/jss/version.rb +31 -0
- 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
|
+
|