ruby-jss 0.14.0 → 1.0.0b2

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.

@@ -0,0 +1,171 @@
1
+ ### Copyright 2018 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
+ #
30
+ class PatchTitle < JSS::APIObject
31
+
32
+ # A Patch Software Title Version in the JSS.
33
+ #
34
+ # This class corresponds to a "version" returned from the
35
+ # 'patchsoftwaretitles' resource of the API
36
+ #
37
+ # Not only does each one have a 'version', e.g. '8.3.2b12', but
38
+ # also knows its parent PatchTitle, the matching JSS::Package,
39
+ # if any, and can report the names and ids of the computers
40
+ # that have it installed.
41
+ #
42
+ # To set or change the JSS::Package associated with a PatchTitle::Version,
43
+ # first fetch the corresponding SoftwareTitle, use the #package= method
44
+ # of the Version object in its #versions attribute, then save the PatchTitle
45
+ # back to the JSS.
46
+ #
47
+ class Version
48
+
49
+ # Attributes
50
+ #####################################
51
+
52
+ # @return [String] the software version number for this PatchVersion.
53
+ # name_id is a unique identfier created from the patch name
54
+ attr_reader :version
55
+
56
+ # @return [Integer] the id of the JSS::Package that installs this PatchVersion,
57
+ # if defined.
58
+ attr_reader :package_id
59
+
60
+ # @return [String] the name of the JSS::Package that installs this PatchVersion,
61
+ # if defined
62
+ attr_reader :package_name
63
+
64
+ # This should only be instantiated by the JSS::PatchTitle that contains
65
+ # this version.
66
+ #
67
+ def initialize(title, data)
68
+ @title = title
69
+ @version = data[:software_version].to_s
70
+
71
+ return if data[:package].to_s.empty?
72
+
73
+ pid = data[:package][:id].to_i
74
+
75
+ @package_id = pid < 1 ? :none : pid
76
+ @package_name = data[:package][:name]
77
+ end
78
+
79
+ # @return [Boolean] Has a package been assigned to this version?
80
+ #
81
+ def package_assigned?
82
+ package_id != :none
83
+ end
84
+
85
+ # get the patch report for this version
86
+ # See PatchTitle.patch_report
87
+ def patch_report
88
+ @title.patch_report version
89
+ end
90
+ alias version_report patch_report
91
+ alias report patch_report
92
+
93
+ # @return [Integer] How many #computers have this version?
94
+ #
95
+ def total_computers
96
+ patch_report[:total_computers]
97
+ end
98
+
99
+ # @return [Array<Hash>] A hash of identifiers for each computer
100
+ # with this version installed.
101
+ def computers
102
+ patch_report[:versions][version]
103
+ end
104
+
105
+ # @return [Array<Integer>] The ids of #computers
106
+ #
107
+ def computer_ids
108
+ computers.map { |c| c[:id] }
109
+ end
110
+
111
+ # @return [Array<Integer>] The names of #computers
112
+ #
113
+ def computer_names
114
+ computers.map { |c| c[:name] }
115
+ end
116
+
117
+ # @return [Array<Integer>] The serial_numbers of #computers
118
+ #
119
+ def computer_serial_numbers
120
+ computers.map { |c| c[:serial_number] }
121
+ end
122
+
123
+ # @return [Array<Integer>] The udids of #computers
124
+ #
125
+ def computer_udids
126
+ computers.map { |c| c[:udid] }
127
+ end
128
+
129
+ # Assign a new JSS::Package to this PatchTitle::Version.
130
+ # The Package must exist in the JSS. Be
131
+ # sure to call #update on the PatchTitle containing
132
+ # this Version.
133
+ #
134
+ # @param new_pkg[String,Integer,Symbol] A name or id of a JSS::Package.
135
+ # use :none to unset a package for this version.
136
+ #
137
+ def package=(new_pkg)
138
+ raise JSS::UnsupportedError, "Packages can't be assigned to the Unkown version." if version == JSS::PatchTitle::UNKNOWN_VERSION_ID
139
+
140
+ pkgid =
141
+ if new_pkg == :none
142
+ :none
143
+ else
144
+ JSS::Package.valid_id new_pkg, :refresh, api: @title.api
145
+ end
146
+ raise JSS::NoSuchItemError, "No JSS::Package matches '#{new_pkg}'" unless pkgid
147
+
148
+ return if @package_id == pkgid
149
+
150
+ @package_id = pkgid
151
+ @package_name = pkgid == :none ? nil : JSS::Package.map_all_ids_to(:name)[pkgid]
152
+ @title.changed_pkg_for_version version
153
+ end
154
+
155
+ # Remove the various cached data
156
+ # from the instance_variables used to create
157
+ # pretty-print (pp) output.
158
+ #
159
+ # @return [Array] the desired instance_variables
160
+ #
161
+ def pretty_print_instance_variables
162
+ vars = super
163
+ vars.delete :@title
164
+ vars
165
+ end
166
+
167
+ end # class Version
168
+
169
+ end # class SoftwareTitle
170
+
171
+ end # module JSS
@@ -1,74 +1,74 @@
1
- ### Copyright 2018 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
- ###
1
+ # Copyright 2018 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
+
27
26
  module JSS
28
27
 
29
- ### Module Constants
28
+ # Module Constants
30
29
  ######################
31
30
 
32
- ### Module Variables
31
+ # Module Variables
33
32
  ######################
34
33
 
35
- ### Module Methods
34
+ # Module Methods
36
35
  ######################
37
36
 
38
- ### Classes
37
+ # Classes
39
38
  #####################################
40
39
 
41
- ### A class implementing a JSS Policy.
42
- ###
43
- ### Like many API objects, the data comes from the API in sections, and
44
- ### the items in the :general section are mapped to direct attributes
45
- ### of this Class.
46
- ###
47
- ###
48
- ### Policy instances are partially read-only:
49
- ### - Due to limitations in the API implementation of policies, as well as the complexity
50
- ### of policy objects, only these attributes can be set and updated via the Policy class:
51
- ### - - name
52
- ### - - frequency
53
- ### - - target_drive
54
- ### - - offline
55
- ### - - enabled
56
- ### - - category
57
- ### - - triggers
58
- ### - - scope, see {JSS::Scopable} and {JSS::Scopable::Scope}
59
- ### - - files and processes
60
- ### - - packages, see {#add_package} and {#remove_package}
61
- ### - - scripts see {#add_script} and {#remove_script}
62
- ### - - self service, see {JSS::SelfServable}
63
- ###
64
- ### All other values and sections must be edited via the Web App.
65
- ###
66
- ### Policies may be deleted via this class
67
- ###
40
+ # A class implementing a JSS Policy.
41
+ #
42
+ # Like many API objects, the data comes from the API in sections, and
43
+ # the items in the :general section are mapped to direct attributes
44
+ # of this Class.
45
+ #
46
+ #
47
+ # Policy instances are partially read-only:
48
+ # - Due to limitations in the API implementation of policies, as well as the complexity
49
+ # of policy objects, only these attributes can be set and updated via the Policy class:
50
+ # - - name
51
+ # - - frequency
52
+ # - - target_drive
53
+ # - - offline
54
+ # - - enabled
55
+ # - - category
56
+ # - - triggers
57
+ # - - client maintenance tasks
58
+ # - - scope, see {JSS::Scopable} and {JSS::Scopable::Scope}
59
+ # - - files and processes
60
+ # - - packages, see {#add_package} and {#remove_package}
61
+ # - - scripts see {#add_script} and {#remove_script}
62
+ # - - self service, see {JSS::SelfServable}
63
+ # - - reboot options
64
+ #
65
+ # All other values and sections must be edited via the Web App.
66
+ #
67
+ # Policies may be deleted via this class
68
+ #
68
69
  class Policy < JSS::APIObject
69
70
 
70
- #####################################
71
- ### Mix-Ins
71
+ # Mix-Ins
72
72
  #####################################
73
73
 
74
74
  include JSS::Creatable
@@ -79,50 +79,45 @@ module JSS
79
79
  include JSS::Categorizable
80
80
  include JSS::Sitable
81
81
 
82
- #####################################
83
- ### Class Methods
84
- #####################################
85
-
86
- #####################################
87
- ### Class Constants
82
+ # Class Constants
88
83
  #####################################
89
84
 
90
- ### The base for REST resources of this class
85
+ # The base for REST resources of this class
91
86
  RSRC_BASE = 'policies'.freeze
92
87
 
93
- ### the hash key used for the JSON list output of all objects in the JSS
88
+ # the hash key used for the JSON list output of all objects in the JSS
94
89
  RSRC_LIST_KEY = :policies
95
90
 
96
- ### The hash key used for the JSON object output.
97
- ### It's also used in various error messages
91
+ # The hash key used for the JSON object output.
92
+ # It's also used in various error messages
98
93
  RSRC_OBJECT_KEY = :policy
99
94
 
100
- ### these keys, as well as :id and :name, are present in valid API JSON data for this class
101
- VALID_DATA_KEYS = [:scope, :user_interaction, :files_processes].freeze
95
+ # these keys, as well as :id and :name, are present in valid API JSON data for this class
96
+ VALID_DATA_KEYS = %i[scope user_interaction files_processes].freeze
102
97
 
103
- ### policies can take uploaded icons
98
+ # policies can take uploaded icons
104
99
  UPLOAD_TYPES = { icon: :policies }.freeze
105
100
 
106
- ### policies are available in macOS self Serviec
101
+ # policies are available in macOS self Serviec
107
102
  SELF_SERVICE_TARGET = :macos
108
103
 
109
- ### policies via self services are still polcies
104
+ # policies via self services are still polcies
110
105
  SELF_SERVICE_PAYLOAD = :policy
111
106
 
112
- SECTIONS = [
113
- :general,
114
- :maintenance,
115
- :account_maintenance,
116
- :scripts,
117
- :self_service,
118
- :package_configuration,
119
- :scope,
120
- :user_interaction,
121
- :reboot,
122
- :files_processes,
123
- :dock_items,
124
- :disk_encryption,
125
- :printers
107
+ SECTIONS = %i[
108
+ general
109
+ maintenance
110
+ account_maintenance
111
+ scripts
112
+ self_service
113
+ package_configuration
114
+ scope
115
+ user_interaction
116
+ reboot
117
+ files_processes
118
+ dock_items
119
+ disk_encryption
120
+ printers
126
121
  ].freeze
127
122
 
128
123
  FREQUENCIES = {
@@ -253,324 +248,338 @@ module JSS
253
248
  # Where is the Site data in the API JSON?
254
249
  SITE_SUBSET = :general
255
250
 
256
- ######################
257
- ### Attributes
251
+ # Where is the Category in the API JSON?
252
+ CATEGORY_SUBSET = :general
253
+
254
+ # How is the category stored in the API data?
255
+ CATEGORY_DATA_TYPE = Hash
256
+
257
+ # Attributes
258
258
  ######################
259
259
 
260
260
  ##### General
261
- ### This data comes from the :general hash in the raw JSON data
262
- ### and correspond to the general section of the Edit Policy window in
263
- ### the JSS WebApp. They are general settings for this policy.
264
- ### We'll map it to direct attributes.
261
+ # This data comes from the :general hash in the raw JSON data
262
+ # and correspond to the general section of the Edit Policy window in
263
+ # the JSS WebApp. They are general settings for this policy.
264
+ # We'll map it to direct attributes.
265
265
 
266
- ### @return [String] how often to run the policy on each computer
266
+ # @return [String] how often to run the policy on each computer
267
267
  attr_reader :frequency
268
268
 
269
- ### @return [String] which drive should the policy target
269
+ # @return [String] which drive should the policy target
270
270
  attr_reader :target_drive
271
271
 
272
- ### @return [Boolean] should be policy be available offline
272
+ # @return [Boolean] should be policy be available offline
273
273
  attr_reader :offline
274
274
 
275
- ### @return [Boolean] is the policy enabled?
275
+ # @return [Boolean] is the policy enabled?
276
276
  attr_reader :enabled
277
+ alias enabled? enabled
277
278
 
278
- ### @return [String] a string with the site name
279
+ # @return [String] a string with the site name
279
280
  attr_reader :site
280
281
 
281
- ### @return [Hash]
282
- ###
283
- ### Overrides for various defaults
284
- ###
285
- ### NOTE: There's an API bug in both XML and JSON with the
286
- ### :distribution_point and :target_drive values.
287
- ### First off, it's not clear what the :target_drive value here
288
- ### is overriding, since there's a :target_drive value in the
289
- ### main General hash.
290
- ### Second off - when you set a non-default dist.point in the
291
- ### packages section of the UI, that value shows up in both
292
- ### this :target_drive and the general one, but the :distribution_point
293
- ### value here stays empty.
294
- ###
295
- ### The hash looks like:
296
- ### :distribution_point => "",
297
- ### :force_afp_smb => false,
298
- ### :netboot_server => "current",
299
- ### :target_drive => "default",
300
- ### :sus => "default"
301
- ###
282
+ # @return [Hash]
283
+ #
284
+ # Overrides for various defaults
285
+ #
286
+ # NOTE: There's an API bug in both XML and JSON with the
287
+ # :distribution_point and :target_drive values.
288
+ # First off, it's not clear what the :target_drive value here
289
+ # is overriding, since there's a :target_drive value in the
290
+ # main General hash.
291
+ # Second off - when you set a non-default dist.point in the
292
+ # packages section of the UI, that value shows up in both
293
+ # this :target_drive and the general one, but the :distribution_point
294
+ # value here stays empty.
295
+ #
296
+ # The hash looks like:
297
+ # :distribution_point => "",
298
+ # :force_afp_smb => false,
299
+ # :netboot_server => "current",
300
+ # :target_drive => "default",
301
+ # :sus => "default"
302
+ #
302
303
  attr_reader :override_default_settings
303
304
 
304
- ### The API has a :network_requirements key in the general section, but
305
- ### in the UI its in a subsection called Client Side Limitiations.
306
- ### so we'll store it in a hash called client_side_limitations,
307
- ### defined below.
308
-
309
- ### the network_limitations hash of the general section seems to be redundant.
310
- ### it contains minimum_network_connection ("Ethernet" or "No Minimum")
311
- ### which is also reflected in the general[:network_requirements] ("Ethernet" or "Any")
312
- ### it contains network_segments, which are also listed
313
- ### in the limitations hash of the scope section
314
- ### it contains any_ip_address, which is true or false based on there being
315
- ### any network_segment limitations.
316
- ### Therefore, we'll ignore it, and use the other places for that data
317
-
318
- ### The API has a general key ":date_time_limitations" which has this
319
- ### this data:
320
- ### :activation - Time
321
- ### :expiration - Time
322
- ### :no_execute_on - An array of short day names as symbols, e.g. [:sun, :mon, :wed, :thu]
323
- ### :no_execute_start - Time
324
- ### :no_execute_end - Time
325
- ### but in the UI, those are set in the Server Side Limitiations and Client Side Limitiations.
326
- ### areas, so we'll store them in matching hashes below.
327
- ### attr_reader :date_time_limitations
328
-
329
- ### @return [Hash]
330
- ###
331
- ### The server-side limitations of this policy.
332
- ###
333
- ### The keys are :activation and :expiration, both are Times.
334
- ###
335
- ### the data comes from the API in the date_time_limitations hash of the general
336
- ### section, but the UI shows them in the Server Side Limitations area.
337
- ### This attribute is just for convience and consistency, and just
338
- ### refers to the data in their API locations
305
+ # The API has a :network_requirements key in the general section, but
306
+ # in the UI its in a subsection called Client Side Limitiations.
307
+ # so we'll store it in a hash called client_side_limitations,
308
+ # defined below.
309
+
310
+ # the network_limitations hash of the general section seems to be redundant.
311
+ # it contains minimum_network_connection ("Ethernet" or "No Minimum")
312
+ # which is also reflected in the general[:network_requirements] ("Ethernet" or "Any")
313
+ # it contains network_segments, which are also listed
314
+ # in the limitations hash of the scope section
315
+ # it contains any_ip_address, which is true or false based on there being
316
+ # any network_segment limitations.
317
+ # Therefore, we'll ignore it, and use the other places for that data
318
+
319
+ # The API has a general key ":date_time_limitations" which has this
320
+ # this data:
321
+ # :activation - Time
322
+ # :expiration - Time
323
+ # :no_execute_on - An array of short day names as symbols, e.g. [:sun, :mon, :wed, :thu]
324
+ # :no_execute_start - Time
325
+ # :no_execute_end - Time
326
+ # but in the UI, those are set in the Server Side Limitiations and Client Side Limitiations.
327
+ # areas, so we'll store them in matching hashes below.
328
+ # attr_reader :date_time_limitations
329
+
330
+ # @return [Hash]
331
+ #
332
+ # The server-side limitations of this policy.
333
+ #
334
+ # The keys are :activation and :expiration, both are Times.
335
+ #
336
+ # the data comes from the API in the date_time_limitations hash of the general
337
+ # section, but the UI shows them in the Server Side Limitations area.
338
+ # This attribute is just for convience and consistency, and just
339
+ # refers to the data in their API locations
339
340
  attr_reader :server_side_limitations
340
341
 
341
- ### @return [Hash]
342
- ###
343
- ### The client-side limitations of this policy.
344
- ###
345
- ### The keys are:
346
- ### - :no_execute_on - An array of short day names as strings, e.g. ["Sun", "Mon", "Tue"]
347
- ### - :no_execute_start - Time
348
- ### - :no_execute_end - Time
349
- ### - :network_connection - String
350
- ### The data for the first three comes from the API in the date_time_limitations
351
- ### hash of the general section.
352
- ### The fourth comes from the network_requirements of the general section of the API,
353
- ### but the UI shows them in the Client Side Limitations area.
354
- ###
355
- ### This attribute is just for convience and consistency, and just
356
- ### refers to the data in their API locations
342
+ # @return [Hash]
343
+ #
344
+ # The client-side limitations of this policy.
345
+ #
346
+ # The keys are:
347
+ # - :no_execute_on - An array of short day names as strings, e.g. ["Sun", "Mon", "Tue"]
348
+ # - :no_execute_start - Time
349
+ # - :no_execute_end - Time
350
+ # - :network_connection - String
351
+ # The data for the first three comes from the API in the date_time_limitations
352
+ # hash of the general section.
353
+ # The fourth comes from the network_requirements of the general section of the API,
354
+ # but the UI shows them in the Client Side Limitations area.
355
+ #
356
+ # This attribute is just for convience and consistency, and just
357
+ # refers to the data in their API locations
357
358
  attr_reader :client_side_limitations
358
359
 
359
- ### @return [String]
360
- ###
361
- ### Either EVENT or USER_INITIATED
362
- ###
363
- ### If it's EVENT, then one or more of the members @trigger_events must true.
360
+ # @return [String]
361
+ #
362
+ # Either EVENT or USER_INITIATED
363
+ #
364
+ # If it's EVENT, then one or more of the members @trigger_events must true.
364
365
  attr_reader :trigger
365
366
 
366
- ### @return [Hash]
367
- ###
368
- ### The triggers that cause this policy to execute on a client when the @trigger is "EVENT"
369
- ###
370
- ### This is a hash with the following keys. Each comes from the API
371
- ### as a key in the :general hash, but they make more sense separated out
372
- ### like this.
373
- ### - :trigger_startup => Bool
374
- ### - :trigger_login => Bool
375
- ### - :trigger_logout => Bool
376
- ### - :trigger_checkin => Bool
377
- ### - :trigger_network_state_changed => Bool
378
- ### - :trigger_enrollment_complete => Bool
379
- ### - :trigger_other => the String that causes a custom trigger
380
- ###
381
- ### To edit a value, call
382
- ### set_trigger_event(type, new_val)
383
- ### where type is one of the keys in TRIGGER_EVENTS and new val is the new value (usually boolean)
384
- ###
367
+ # @return [Hash]
368
+ #
369
+ # The triggers that cause this policy to execute on a client when the @trigger is "EVENT"
370
+ #
371
+ # This is a hash with the following keys. Each comes from the API
372
+ # as a key in the :general hash, but they make more sense separated out
373
+ # like this.
374
+ # - :trigger_startup => Bool
375
+ # - :trigger_login => Bool
376
+ # - :trigger_logout => Bool
377
+ # - :trigger_checkin => Bool
378
+ # - :trigger_network_state_changed => Bool
379
+ # - :trigger_enrollment_complete => Bool
380
+ # - :trigger_other => the String that causes a custom trigger
381
+ #
382
+ # To edit a value, call
383
+ # set_trigger_event(type, new_val)
384
+ # where type is one of the keys in TRIGGER_EVENTS and new val is the new value (usually boolean)
385
+ #
385
386
  attr_reader :trigger_events
386
387
 
387
388
  ###### client machine maintenence
388
- ### These are the computer maint. tasks
389
- ### that might be performed by this policy
390
- ### All are boolean
391
- ### TODO: make individial getters/setters as for @files_processes
389
+ # These are the computer maint. tasks
390
+ # that might be performed by this policy
391
+ # All are boolean
392
392
 
393
- ### @return [Boolean] client maintenance task
393
+ # Should this policy verify the startup disk?
394
+ # @return [Boolean] client maintenance task
394
395
  attr_reader :verify_startup_disk
395
396
 
396
- ### @return [Boolean] client maintenance task
397
+ # Should this policy run a permission repair?
398
+ # @return [Boolean] client maintenance task
397
399
  attr_reader :permissions_repair
398
400
 
399
- ### @return [Boolean] client maintenance task
401
+ # Should this policy run a recon?
402
+ # @return [Boolean] client maintenance task
400
403
  attr_reader :recon
404
+ alias update_inventory recon
401
405
 
402
- ### @return [Boolean] client maintenance task
406
+ # Shouls this policy fix the ByHost prefs?
407
+ # @return [Boolean] client maintenance task
403
408
  attr_reader :fix_byhost
404
409
 
405
- ### @return [Boolean] client maintenance task
410
+ # Should this policy reset the local hostname?
411
+ # @return [Boolean] client maintenance task
406
412
  attr_reader :reset_name
407
413
 
408
- ### @return [Boolean] client maintenance task
414
+ # Should this policy flush the system cache?
415
+ # @return [Boolean] client maintenance task
409
416
  attr_reader :flush_system_cache
410
417
 
411
- ### @return [Boolean] client maintenance task
418
+ # Should this policy install any cached JSS packages?
419
+ # @return [Boolean] client maintenance task
412
420
  attr_reader :install_cached_pkgs
413
421
 
414
- ### @return [Boolean] client maintenance task
422
+ # Should this policy flush the user cache?
423
+ # @return [Boolean] client maintenance task
415
424
  attr_reader :flush_user_cache
416
425
 
417
- ### @return [Array<Hash>]
418
- ###
419
- ### The directory bindings applied
420
- ###
421
- ### each hash is like: !{:name => "LDAP", :id => 4}
422
- ### TODO: handle as for packages & scripts
426
+ # @return [Array<Hash>]
427
+ #
428
+ # The directory bindings applied
429
+ #
430
+ # each hash is like: !{:name => "LDAP", :id => 4}
431
+ # TODO: handle as for packages & scripts
423
432
  attr_reader :directory_bindings
424
433
 
425
- ### @return [Hash] the open firmware mode and password
434
+ # @return [Hash] the open firmware mode and password
426
435
  attr_reader :open_firmware_efi_password
427
436
 
428
- ### @return [Hash]
429
- ###
430
- ### The management accout changes applied by the policy
431
- ###
432
- ### The keys are:
433
- ### - :action see MGMT_ACCOUNT_ACTIONS
434
- ### - :managed_password
435
- ### - :managed_password_md5
436
- ### - :managed_password_sha256
437
- ### - :managed_password_length # for random generating pws
438
- ###
439
- ### TODO: make individial getters/setters as for @files_processes
437
+ # @return [Hash]
438
+ #
439
+ # The management accout changes applied by the policy
440
+ #
441
+ # The keys are:
442
+ # - :action see MGMT_ACCOUNT_ACTIONS
443
+ # - :managed_password
444
+ # - :managed_password_md5
445
+ # - :managed_password_sha256
446
+ # - :managed_password_length # for random generating pws
447
+ #
448
+ # TODO: make individial getters/setters as for @files_processes
440
449
  attr_reader :management_account
441
450
 
442
- ### @return [Array<Hash>]
443
- ###
444
- ### Local accts acted-upon by this policy
445
- ###
446
- ### Keys are:
447
- ### - :action => "Create",
448
- ### - :hint => "foo bar",
449
- ### - :picture => "/path/to/pic.tif",
450
- ### - :admin => true,
451
- ### - :home => "/Users/chrisltest",
452
- ### - :realname => "ChrisTest Lasell",
453
- ### - :filevault_enabled => true,
454
- ### - :username => "chrisltest",
455
- ### - :password_md5 => "3858f62230ac3c915f300c664312c63f",
456
- ### - :password => "foobar",
457
- ### - :password_sha256=> "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"
458
- ###
459
- ### TODO: make individial getters/setters as for @files_processes
451
+ # @return [Array<Hash>]
452
+ #
453
+ # Local accts acted-upon by this policy
454
+ #
455
+ # Keys are:
456
+ # - :action => "Create",
457
+ # - :hint => "foo bar",
458
+ # - :picture => "/path/to/pic.tif",
459
+ # - :admin => true,
460
+ # - :home => "/Users/chrisltest",
461
+ # - :realname => "ChrisTest Lasell",
462
+ # - :filevault_enabled => true,
463
+ # - :username => "chrisltest",
464
+ # - :password_md5 => "3858f62230ac3c915f300c664312c63f",
465
+ # - :password => "foobar",
466
+ # - :password_sha256=> "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2"
467
+ #
468
+ # TODO: make individial getters/setters as for @files_processes
460
469
  attr_reader :accounts
461
470
 
462
- ### @return [Array<Hash>]
463
- ###
464
- ### The pkgs handled by this policy
465
- ###
466
- ### Hash keys are:
467
- ### - :action => "Install"
468
- ### - :update_autorun => false,
469
- ### - :feu => false,
470
- ### - :name => "rbgem-json-1.6.5-4.pkg",
471
- ### - :id => 1073
472
- ###
471
+ # @return [Array<Hash>]
472
+ #
473
+ # The pkgs handled by this policy
474
+ #
475
+ # Hash keys are:
476
+ # - :action => "Install"
477
+ # - :update_autorun => false,
478
+ # - :feu => false,
479
+ # - :name => "rbgem-json-1.6.5-4.pkg",
480
+ # - :id => 1073
481
+ #
473
482
  attr_reader :packages
483
+ alias pkgs packages
474
484
 
475
- ### @return [Array<Hash>]
476
- ###
477
- ### The scripts run by this policy
478
- ###
479
- ### Hash keys are:
480
- ### - :name => "chromegetter.sh",
481
- ### - :parameter4 => "",
482
- ### - :parameter5 => "",
483
- ### - :parameter6 => "",
484
- ### - :parameter7 => "",
485
- ### - :parameter8 => "",
486
- ### - :parameter9 => "",
487
- ### - :parameter10 => "",
488
- ### - :parameter11 => "",
489
- ### - :id => 1428,
490
- ### - :priority => "After"
491
- ###
485
+ # @return [Array<Hash>]
486
+ #
487
+ # The scripts run by this policy
488
+ #
489
+ # Hash keys are:
490
+ # - :name => "chromegetter.sh",
491
+ # - :parameter4 => "",
492
+ # - :parameter5 => "",
493
+ # - :parameter6 => "",
494
+ # - :parameter7 => "",
495
+ # - :parameter8 => "",
496
+ # - :parameter9 => "",
497
+ # - :parameter10 => "",
498
+ # - :parameter11 => "",
499
+ # - :id => 1428,
500
+ # - :priority => "After"
501
+ #
492
502
  attr_reader :scripts
493
503
 
494
504
  ###### user interaction
495
- ### These are extracted from the :user_interaction hash
496
- ### in the JSON output, which looks like this:
497
- ### :message_start => "",
498
- ### :allow_users_to_defer => false,
499
- ### :allow_deferral_until_utc => "",
500
- ### :message_finish => ""
501
- ###
502
- ### TODO: make individial getters/setters as for @files_processes
503
-
504
- ### @return [Boolean] can the user defer the policy?
505
+ # These are extracted from the :user_interaction hash
506
+ # in the JSON output, which looks like this:
507
+ # :message_start => "",
508
+ # :allow_users_to_defer => false,
509
+ # :allow_deferral_until_utc => "",
510
+ # :message_finish => ""
511
+ #
512
+ # TODO: make individial getters/setters as for @files_processes
513
+
514
+ # @return [Boolean] can the user defer the policy?
505
515
  attr_reader :user_may_defer
506
516
 
507
- ### @return [Time] when is the user no longer allowed to defer?
517
+ # @return [Time] when is the user no longer allowed to defer?
508
518
  attr_reader :user_may_defer_until
509
519
 
510
- ### @return [String] the message shown the user at policy start
520
+ # @return [String] the message shown the user at policy start
511
521
  attr_reader :user_message_start
512
522
 
513
- ### @return [String] the message shown the user at policy end
523
+ # @return [String] the message shown the user at policy end
514
524
  attr_reader :user_message_finish
515
525
 
516
- ### @return [Hash]
517
- ###
518
- ### Reboot options for the policy
519
- ###
520
- ### The hash keys are:
521
- ### - :user_logged_in => "Do not restart",
522
- ### - :minutes_until_reboot => 5,
523
- ### - :message=> "This computer will restart in 5 minutes. yaddayadda.",
524
- ### - :startup_disk => "Current Startup Disk",
525
- ### - :specify_startup => "",
526
- ### - :no_user_logged_in => "Do not restart"
527
- ### - :file_vault_2_reboot => false
528
- ###
529
- ### TODO: make individial getters/setters as for @files_processes
526
+ # @return [Hash]
527
+ #
528
+ # Reboot options for the policy
529
+ #
530
+ # The hash keys are:
531
+ # - :user_logged_in => "Do not restart",
532
+ # - :minutes_until_reboot => 5,
533
+ # - :message=> "This computer will restart in 5 minutes. yaddayadda.",
534
+ # - :startup_disk => "Current Startup Disk",
535
+ # - :specify_startup => "",
536
+ # - :no_user_logged_in => "Do not restart"
537
+ # - :file_vault_2_reboot => false
538
+ #
530
539
  attr_reader :reboot_options
531
540
 
532
541
  ##### files & processes
533
- ### a hash like this:
534
- ### {:spotlight_search => "Spotlight This",
535
- ### :search_for_process => "SafariProcess",
536
- ### :search_by_path => "/this/is/a/path",
537
- ### :kill_process => true,
538
- ### :delete_file => true,
539
- ### :run_command => "/usr/local/pixar/sbin/force-fde-logout --setup",
540
- ### :locate_file => "this-is-a-filename",
541
- ### :update_locate_database => true}
542
- ###
543
- ### NOTE, since these items are editable, they have custom getters/setters
544
- ### so that the hash isn't directly changable without @need_to_update.
545
- ### attr_reader :files_processes
546
-
547
- ### @return [Array<Hash>]
548
- ###
549
- ### The dock items handled by this policy
550
- ###
551
- ### each item hash looks like: !{:name => "Mail", :id => 14, :action => "Add To Beginning"}
542
+ # a hash like this:
543
+ # {:spotlight_search => "Spotlight This",
544
+ # :search_for_process => "SafariProcess",
545
+ # :search_by_path => "/this/is/a/path",
546
+ # :kill_process => true,
547
+ # :delete_file => true,
548
+ # :run_command => "/usr/local/pixar/sbin/force-fde-logout --setup",
549
+ # :locate_file => "this-is-a-filename",
550
+ # :update_locate_database => true}
551
+ #
552
+ # NOTE, since these items are editable, they have custom getters/setters
553
+ # so that the hash isn't directly changable without @need_to_update.
554
+ # attr_reader :files_processes
555
+
556
+ # @return [Array<Hash>]
557
+ #
558
+ # The dock items handled by this policy
559
+ #
560
+ # each item hash looks like: !{:name => "Mail", :id => 14, :action => "Add To Beginning"}
552
561
  attr_reader :dock_items
553
562
 
554
- ### @return [Hash]
555
- ###
556
- ### Disk encryption options for this policy
557
- ###
558
- ### The hash looks like !{:disk_encryption_configuration_id => 3, :action => "apply"}
563
+ # @return [Hash]
564
+ #
565
+ # Disk encryption options for this policy
566
+ #
567
+ # The hash looks like !{:disk_encryption_configuration_id => 3, :action => "apply"}
559
568
  attr_reader :disk_encryption
560
569
 
561
- ### @return [Array<Hash>]
562
- ###
563
- ### The printers handled by this policy
564
- ###
565
- ### Each Hash looks like: !{:make_default => false, :name => "torlan", :id => 3, :action => "install"}
570
+ # @return [Array<Hash>]
571
+ #
572
+ # The printers handled by this policy
573
+ #
574
+ # Each Hash looks like: !{:make_default => false, :name => "torlan", :id => 3, :action => "install"}
566
575
  attr_reader :printers
567
576
 
568
577
  #####################################
569
- ### Public Instance Methods
578
+ # Public Instance Methods
570
579
  #####################################
571
580
 
572
- ### @see APIObject#initialize
573
- ###
581
+ # @see APIObject#initialize
582
+ #
574
583
  def initialize(args = {})
575
584
  super
576
585
 
@@ -643,7 +652,7 @@ module JSS
643
652
 
644
653
  @printers = @init_data[:printers]
645
654
 
646
- ### Not in jss yet
655
+ # Not in jss yet
647
656
  end
648
657
 
649
658
  # set non-nil defaults
@@ -678,75 +687,74 @@ module JSS
678
687
 
679
688
  ###### General
680
689
 
681
- ### Change the enabled state of this item
682
- ###
683
- ### @param new_val[Boolean] the new state.
684
- ###
685
- ### @return [void]
686
- ###
690
+ # Change the enabled state of this item
691
+ #
692
+ # @param new_val[Boolean] the new state.
693
+ #
694
+ # @return [void]
695
+ #
687
696
  def enabled=(new_val)
688
- return nil if @enabled == new_val
689
- raise JSS::InvalidDataError, 'New value must be true or false' unless JSS::TRUE_FALSE.include? new_val
690
- @enabled = new_val
697
+ return if @enabled == new_val
698
+ @enabled = JSS::Validate.boolean new_val
691
699
  @need_to_update = true
692
700
  end
693
701
 
694
- ### Shortcut for enabled = true
702
+ # Shortcut for enabled = true
695
703
  def enable
696
704
  self.enabled = true
697
705
  end
698
706
 
699
- ### Shortcut for endabled = false
707
+ # Shortcut for endabled = false
700
708
  def disable
701
709
  self.enabled = false
702
710
  end
703
711
 
704
- ### Set a new frequency for this policy.
705
- ###
706
- ### @param freq[Symbol] the desired frequency, must be one of the keys of {FREQUENCIES}
707
- ###
708
- ### @return [void]
709
- ###
712
+ # Set a new frequency for this policy.
713
+ #
714
+ # @param freq[Symbol] the desired frequency, must be one of the keys of {FREQUENCIES}
715
+ #
716
+ # @return [void]
717
+ #
710
718
  def frequency=(freq)
711
- raise JSS::InvalidDataError, "New frequency must be one of :#{FREQUENCIES.keys.join ', :'}" unless FREQUENCIES.keys.include? freq
719
+ raise JSS::InvalidDataError, "New frequency must be one of :#{FREQUENCIES.keys.join ', :'}" unless FREQUENCIES.key?(freq)
712
720
  @frequency = FREQUENCIES[freq]
713
721
  @need_to_update = true
714
722
  end
715
723
 
716
- ### Set a new target drive for this policy.
717
- ###
718
- ### @param path_to_drive[String,Pathname] the full path to the target drive, must start with a '/'
719
- ###
720
- ### @return [void]
721
- ###
724
+ # Set a new target drive for this policy.
725
+ #
726
+ # @param path_to_drive[String,Pathname] the full path to the target drive, must start with a '/'
727
+ #
728
+ # @return [void]
729
+ #
722
730
  def target_drive=(path_to_drive)
723
731
  raise JSS::InvalidDataError, 'Path to target drive must be absolute' unless path_to_drive.to_s.start_with? '/'
724
732
  @target_drive = path_to_drive.to_s
725
733
  @need_to_update = true
726
734
  end
727
735
 
728
- ### Set whether this policy is available offline.
729
- ###
730
- ### @param new_val[Boolean]
731
- ###
732
- ### @return [void]
733
- ###
736
+ # Set whether this policy is available offline.
737
+ #
738
+ # @param new_val[Boolean]
739
+ #
740
+ # @return [void]
741
+ #
734
742
  def offline=(new_val)
735
743
  raise JSS::InvalidDataError, 'New value must be boolean true or false' unless JSS::TRUE_FALSE.include? new_val
736
744
  @offline = new_val
737
745
  @need_to_update = true
738
746
  end
739
747
 
740
- ### Change a trigger event
741
- ###
742
- ### @param type[Symbol] the type of trigger, one of the keys of {TRIGGER_EVENTS}
743
- ###
744
- ### @param new_val[Boolean] whether the type of trigger is active or not.
745
- ###
746
- ### @return [void]
747
- ###
748
+ # Change a trigger event
749
+ #
750
+ # @param type[Symbol] the type of trigger, one of the keys of {TRIGGER_EVENTS}
751
+ #
752
+ # @param new_val[Boolean] whether the type of trigger is active or not.
753
+ #
754
+ # @return [void]
755
+ #
748
756
  def set_trigger_event(type, new_val)
749
- raise JSS::InvalidDataError, "Trigger type must be one of #{TRIGGER_EVENTS.keys.join(', ')}" unless TRIGGER_EVENTS.keys.include? type
757
+ raise JSS::InvalidDataError, "Trigger type must be one of #{TRIGGER_EVENTS.keys.join(', ')}" unless TRIGGER_EVENTS.key?(type)
750
758
  if type == :custom
751
759
  raise JSS::InvalidDataError, 'Custom triggers must be Strings' unless new_val.is_a? String
752
760
  else
@@ -756,130 +764,196 @@ module JSS
756
764
  @need_to_update = true
757
765
  end
758
766
 
759
- ### Set Server Side Activation
760
- ###
761
- ### @param activation[Time] Activation date and time
762
- ###
763
- ### @return [void]
764
- ###
767
+ # Set Server Side Activation
768
+ #
769
+ # @param activation[Time] Activation date and time
770
+ #
771
+ # @return [void]
772
+ #
765
773
  def server_side_activation=(activation)
766
774
  raise JSS::InvalidDataError, 'Activation must be a Time' unless activation.is_a? Time
767
775
  @server_side_limitations[:activation] = activation
768
776
  @need_to_update = true
769
777
  end
770
778
 
771
- ### Set Server Side Expiration
772
- ###
773
- ### @param expiration[Time] Expiration date and time
774
- ###
775
- ### @return [void]
776
- ###
779
+ # Set Server Side Expiration
780
+ #
781
+ # @param expiration[Time] Expiration date and time
782
+ #
783
+ # @return [void]
784
+ #
777
785
  def server_side_expiration=(expiration)
778
786
  raise JSS::InvalidDataError, 'Expiration must be a Time' unless expiration.is_a? Time
779
787
  @server_side_limitations[:expiration] = expiration
780
788
  @need_to_update = true
781
789
  end
782
790
 
783
- ### Reboot Options
784
- ### Set Reboot Message
785
- ###
786
- ### @param reboot_message[String] Text of Reboot Message
787
- ###
788
- ### @return [void] description of returned object
789
- ###
790
- def message=(reboot_message)
791
- raise JSS::InvalidDataError, 'Reboot message must be a String' unless reboot_message.is_a? String
792
- @reboot_options[:message] = reboot_message
791
+ # Maintenance tasks
792
+
793
+ # see attr_reader :verify_startup_disk
794
+ #
795
+ def verify_startup_disk=(bool)
796
+ return if @verify_startup_disk == bool
797
+ @verify_startup_disk = JSS::Validate.boolean bool
793
798
  @need_to_update = true
794
799
  end
795
800
 
796
- ### Reboot Options
797
- ### Set Startup Disk
798
- ### Only Supports 'Specify Local Startup Disk' at the moment
799
- ###
800
- ### @param startup_disk_option[String]
801
- ###
802
- ### @return [void]
803
- ###
804
- def startup_disk=(startup_disk_option)
805
- raise JSS::InvalidDataError, "#{startup_disk_option} is not a valid Startup Disk" unless startup_disk_option.is_a? String
806
- @reboot_options[:startup_disk] = 'Specify Local Startup Disk'
807
- self.specify_startup = startup_disk_option
801
+ # see attr_reader :permissions_repair
802
+ #
803
+ def permissions_repair=(bool)
804
+ return if @permissions_repair == bool
805
+ @permissions_repair = JSS::Validate.boolean bool
808
806
  @need_to_update = true
809
807
  end
810
808
 
811
- ### Reboot Options
812
- ### Specify Startup Volume
813
- ### Only Supports "Specify Local Startup Disk"
814
- ###
815
- ### @param startup_volume[String] a Volume to reboot to
816
- ###
817
- ### @return [void]
818
- ###
819
- def specify_startup=(startup_volume)
820
- raise JSS::InvalidDataError, "#{startup_volume} is not a valid Startup Disk" unless startup_volume.is_a? String
821
- @reboot_options[:specify_startup] = startup_volume
809
+ # see attr_reader :recon
810
+ #
811
+ def recon=(bool)
812
+ return if @recon == bool
813
+ @recon = JSS::Validate.boolean bool
814
+ @need_to_update = true
815
+ end
816
+ alias update_inventory= recon=
817
+
818
+ # see attr_reader :fix_byhost
819
+ #
820
+ def fix_byhost=(bool)
821
+ return if @fix_byhost == bool
822
+ @fix_byhost = JSS::Validate.boolean bool
823
+ @need_to_update = true
824
+ end
825
+
826
+ # see attr_reader :reset_name
827
+ #
828
+ def reset_name=(bool)
829
+ return if @reset_name == bool
830
+ @reset_name = JSS::Validate.boolean bool
831
+ @need_to_update = true
832
+ end
833
+
834
+ # see attr_reader :flush_system_cache
835
+ #
836
+ def flush_system_cache=(bool)
837
+ return if @flush_system_cache == bool
838
+ @flush_system_cache = JSS::Validate.boolean bool
839
+ @need_to_update = true
840
+ end # see attr_reader :recon
841
+
842
+ # see attr_reader :install_cached_pkgs
843
+ #
844
+ def install_cached_pkgs=(bool)
845
+ return if @install_cached_pkgs == bool
846
+ @install_cached_pkgs = JSS::Validate.boolean bool
822
847
  @need_to_update = true
823
848
  end
824
849
 
825
- ### Reboot Options
826
- ### No User Logged In
827
- ###
828
- ### @param no_user_option[String] Any one of the Strings from NO_USER_LOGGED_IN
829
- ###
830
- ### @return [void]
831
- ###
850
+ # see attr_reader :flush_user_cache
851
+ #
852
+ def flush_user_cache=(bool)
853
+ return if @flush_user_cache == bool
854
+ @flush_user_cache = JSS::Validate.boolean bool
855
+ @need_to_update = true
856
+ end
857
+
858
+ # Reboot Options
859
+ #######
860
+
861
+ # What to do at reboot when No User Logged In
862
+ #
863
+ # @param no_user_option[String] Any one of the Strings from NO_USER_LOGGED_IN
864
+ #
865
+ # @return [void]
866
+ #
832
867
  def no_user_logged_in=(no_user_option)
833
868
  raise JSS::InvalidDataError, "no_user_logged_in options: #{NO_USER_LOGGED_IN.join(', ')}" unless NO_USER_LOGGED_IN.include? no_user_option
834
869
  @reboot_options[:no_user_logged_in] = no_user_option
835
870
  @need_to_update = true
836
871
  end
837
872
 
838
- ### Reboot Options
839
- ### User Logged In
840
- ###
841
- ### @param logged_in_option[String] Any one of the Strings from USER_LOGGED_IN
842
- ###
843
- ### @return [void]
844
- ###
873
+ # What to do at reboot when there is a User Logged In
874
+ #
875
+ # @param logged_in_option[String] Any one of the Strings from USER_LOGGED_IN
876
+ #
877
+ # @return [void]
878
+ #
845
879
  def user_logged_in=(logged_in_option)
846
880
  raise JSS::InvalidDataError, "user_logged_in options: #{USER_LOGGED_IN.join(', ')}" unless USER_LOGGED_IN.include? logged_in_option
847
881
  @reboot_options[:user_logged_in] = logged_in_option
848
882
  @need_to_update = true
849
883
  end
850
884
 
851
- ### Reboot Options
852
- ### Do Not Reboot
853
- ### Shortcut method to suppress Reboot Options
854
- ###
855
- ### @return [void]
856
- ###
885
+ # Set Reboot Message
886
+ #
887
+ # @param reboot_message[String] Text of Reboot Message
888
+ #
889
+ # @return [void] description of returned object
890
+ #
891
+ def reboot_message=(message)
892
+ raise JSS::InvalidDataError, 'Reboot message must be a String' unless message.is_a? String
893
+ @reboot_options[:message] = message
894
+ @need_to_update = true
895
+ end
896
+ alias message= reboot_message=
897
+
898
+ # Set Startup Disk
899
+ # Only Supports 'Specify Local Startup Disk' at the moment
900
+ #
901
+ # @param startup_disk_option[String]
902
+ #
903
+ # @return [void]
904
+ #
905
+ def startup_disk=(startup_disk_option)
906
+ raise JSS::InvalidDataError, "#{startup_disk_option} is not a valid Startup Disk" unless startup_disk_option.is_a? String
907
+ @reboot_options[:startup_disk] = 'Specify Local Startup Disk'
908
+ self.specify_startup = startup_disk_option
909
+ @need_to_update = true
910
+ end
911
+
912
+ # Specify Startup Volume
913
+ # Only Supports "Specify Local Startup Disk"
914
+ #
915
+ # @param startup_volume[String] a Volume to reboot to
916
+ #
917
+ # @return [void]
918
+ #
919
+ def specify_startup=(startup_volume)
920
+ raise JSS::InvalidDataError, "#{startup_volume} is not a valid Startup Disk" unless startup_volume.is_a? String
921
+ @reboot_options[:specify_startup] = startup_volume
922
+ @need_to_update = true
923
+ end
924
+
925
+ # Reboot Options
926
+ # Do Not Reboot
927
+ # Shortcut method to suppress Reboot Options
928
+ #
929
+ # @return [void]
930
+ #
857
931
  def do_not_reboot
858
932
  @reboot_options[:user_logged_in] = 'Do not restart'
859
933
  @reboot_options[:no_user_logged_in] = 'Do not restart'
860
934
  @need_to_update = true
861
935
  end
862
936
 
863
- ### Reboot Options
864
- ### Minutes Until Reboot
865
- ###
866
- ### @param minutes[String] The number of minutes to delay prior to reboot
867
- ###
868
- ### @return [void]
869
- ###
937
+ # Reboot Options
938
+ # Minutes Until Reboot
939
+ #
940
+ # @param minutes[String] The number of minutes to delay prior to reboot
941
+ #
942
+ # @return [void]
943
+ #
870
944
  def minutes_until_reboot=(minutes)
871
945
  raise JSS::InvalidDataError, 'Minutes until reboot must be an Integer' unless minutes.is_a? Integer
872
946
  @reboot_options[:minutes_until_reboot] = minutes
873
947
  @need_to_update = true
874
948
  end
875
949
 
876
- ### Reboot Options
877
- ### FileVault Authenticated Reboot
878
- ###
879
- ### @param fv_bool[Boolean] true or false
880
- ###
881
- ### @return [void]
882
- ###
950
+ # Reboot Options
951
+ # FileVault Authenticated Reboot
952
+ #
953
+ # @param fv_bool[Boolean] true or false
954
+ #
955
+ # @return [void]
956
+ #
883
957
  def file_vault_2_reboot=(fv_bool)
884
958
  raise JSS::InvalidDataError, 'FileVault 2 Reboot must be a Boolean' unless fv_bool.jss_boolean?
885
959
  @reboot_options[:file_vault_2_reboot] = fv_bool
@@ -888,95 +962,98 @@ module JSS
888
962
 
889
963
  ###### Files & Processes
890
964
 
891
- ### @return [String] The unix shell command to run on ths client.
892
- ###
965
+ # @return [String] The unix shell command to run on ths client.
966
+ #
893
967
  def run_command
894
968
  @files_processes[:run_command]
895
969
  end
970
+ alias command_to_run run_command
896
971
 
897
- ### Set the unix shell command to be run on the client
898
- ###
899
- ### @param command[String] the unix shell command to be run on the client
900
- ###
901
- ### @return [void]
902
- ###
972
+ # Set the unix shell command to be run on the client
973
+ #
974
+ # @param command[String] the unix shell command to be run on the client
975
+ #
976
+ # @return [void]
977
+ #
903
978
  def run_command=(command)
904
979
  raise JSS::InvalidDataError, 'Command to run must be a String' unless command.is_a? String
905
980
  @files_processes[:run_command] = command
906
981
  @need_to_update = true
907
982
  end
983
+ alias command_to_run= run_command=
908
984
 
909
- ### @return [Boolean] Should we update the database used by the locate command?
910
- ###
985
+ # @return [Boolean] Should we update the database used by the locate command?
986
+ #
911
987
  def update_locate_database?
912
988
  @files_processes[:update_locate_database]
913
989
  end
914
990
 
915
- ### Set whether or not to update the database used by the locate command.
916
- ###
917
- ### @param tf[Boolean] whether or not to update the database used by the locate command.
918
- ###
919
- ### @return [void]
920
- ###
921
- def update_locate_database=(tf)
922
- @files_processes[:update_locate_database] = tf ? true : false
991
+ # Set whether or not to update the database used by the locate command.
992
+ #
993
+ # @param bool [Boolean] whether or not to update the database used by the locate command.
994
+ #
995
+ # @return [void]
996
+ #
997
+ def update_locate_database=(bool)
998
+ @files_processes[:update_locate_database] = JSS::Validate.boolean bool
923
999
  @need_to_update = true
924
1000
  end
925
1001
 
926
- ### @return [String] The process name to search for on the client
927
- ###
1002
+ # @return [String] The process name to search for on the client
1003
+ #
928
1004
  def search_for_process
929
1005
  @files_processes[:search_for_process]
930
1006
  end
931
1007
 
932
- ### @return [Boolean] Should the searched-for process be killed if found.
933
- ###
1008
+ # @return [Boolean] Should the searched-for process be killed if found.
1009
+ #
934
1010
  def kill_process?
935
1011
  @files_processes[:kill_process]
936
1012
  end
937
1013
 
938
- ### Set the process name to search for, and if it should be killed if found.
939
- ###
940
- ### Setter methods (which end with =) can't easily take
941
- ### multiple arguments, so we instead name them "set_blah_blah"
942
- ### rather than "blah_blah="
943
- ###
944
- ### @param process[String] the process name to search for
945
- ###
946
- ### @param kill[Boolean] should be process be killed if found
947
- ###
948
- ### @return [void]
949
- ###
1014
+ # Set the process name to search for, and if it should be killed if found.
1015
+ #
1016
+ # Setter methods (which end with =) can't easily take
1017
+ # multiple arguments, so we instead name them "set_blah_blah"
1018
+ # rather than "blah_blah="
1019
+ #
1020
+ # @param process[String] the process name to search for
1021
+ #
1022
+ # @param kill[Boolean] should be process be killed if found
1023
+ #
1024
+ # @return [void]
1025
+ #
950
1026
  def set_search_for_process(process, kill = false)
951
1027
  @files_processes[:search_for_process] = process.to_s
952
1028
  @files_processes[:kill_process] = kill ? true : false
953
1029
  @need_to_update = true
954
1030
  end
955
1031
 
956
- ### @return [Pathname] The path to search for
957
- ###
1032
+ # @return [Pathname] The path to search for
1033
+ #
958
1034
  def search_by_path
959
1035
  Pathname.new @files_processes[:search_by_path]
960
1036
  end
961
1037
 
962
- ### @return [Boolean] Should the searched-for path be deleted if found?
963
- ###
1038
+ # @return [Boolean] Should the searched-for path be deleted if found?
1039
+ #
964
1040
  def delete_file?
965
1041
  @files_processes[:delete_file]
966
1042
  end
1043
+ alias delete_path? delete_file?
967
1044
 
968
- ### Set the path to search for, a String or Pathname, and whether or not to delete it if found.
969
- ###
970
- ### Setter methods (which end with =) can't easily take
971
- ### multiple arguments, so we instead name them "set_blah_blah"
972
- ### rather than "blah_blah="
973
- ###
974
- ### @param path[String,Pathname] the path to search for
975
- ###
976
- ### @param delete[Boolean] should the path be deleted if found
977
- ###
978
- ### @return [void]
979
- ###
1045
+ # Set the path to search for, a String or Pathname, and whether or not to delete it if found.
1046
+ #
1047
+ # Setter methods (which end with =) can't easily take
1048
+ # multiple arguments, so we instead name them "set_blah_blah"
1049
+ # rather than "blah_blah="
1050
+ #
1051
+ # @param path[String,Pathname] the path to search for
1052
+ #
1053
+ # @param delete[Boolean] should the path be deleted if found
1054
+ #
1055
+ # @return [void]
1056
+ #
980
1057
  def set_search_by_path(path, delete = false)
981
1058
  raise JSS::InvalidDataError, 'Path to search for must be a String or a Pathname' unless path.is_a?(String) || path.is_a?(Pathname)
982
1059
  @files_processes[:search_by_path] = path.to_s
@@ -984,36 +1061,36 @@ module JSS
984
1061
  @need_to_update = true
985
1062
  end
986
1063
 
987
- ### @return [String] The term to search for using spotlight
988
- ###
1064
+ # @return [String] The term to search for using spotlight
1065
+ #
989
1066
  def spotlight_search
990
1067
  @files_processes[:spotlight_search]
991
1068
  end
992
1069
 
993
- ### Set the term to seach for using spotlight
994
- ###
995
- ### @param term[String] the term to seach for using spotlight
996
- ###
997
- ### @return [void]
998
- ###
1070
+ # Set the term to seach for using spotlight
1071
+ #
1072
+ # @param term[String] the term to seach for using spotlight
1073
+ #
1074
+ # @return [void]
1075
+ #
999
1076
  def spotlight_search=(term)
1000
1077
  raise JSS::InvalidDataError, 'Spotlight search term must be a String' unless term.is_a? String
1001
1078
  @files_processes[:spotlight_search] = term
1002
1079
  @need_to_update = true
1003
1080
  end
1004
1081
 
1005
- ### @return [String] The term to seach for using the locate command
1006
- ###
1082
+ # @return [String] The term to seach for using the locate command
1083
+ #
1007
1084
  def locate_file
1008
1085
  @files_processes[:locate_file]
1009
1086
  end
1010
1087
 
1011
- ### Set the term to seach for using the locate command
1012
- ###
1013
- ### @param term[String] the term to seach for using the locate command
1014
- ###
1015
- ### @return [void]
1016
- ###
1088
+ # Set the term to seach for using the locate command
1089
+ #
1090
+ # @param term[String] the term to seach for using the locate command
1091
+ #
1092
+ # @return [void]
1093
+ #
1017
1094
  def locate_file=(term)
1018
1095
  raise JSS::InvalidDataError, 'Term to locate must be a String' unless term.is_a? String
1019
1096
  @files_processes[:locate_file] = term
@@ -1022,70 +1099,47 @@ module JSS
1022
1099
 
1023
1100
  ###### Client maintenance
1024
1101
 
1025
- ### Set the
1102
+ # Set the
1026
1103
 
1027
1104
  ###### Packages
1028
1105
 
1029
- ### @return [Array] the id's of the packages handled by the policy
1106
+ # @return [Array] the id's of the packages handled by the policy
1030
1107
  def package_ids
1031
1108
  @packages.map { |p| p[:id] }
1032
1109
  end
1033
1110
 
1034
- ### @return [Array] the names of the packages handled by the policy
1111
+ # @return [Array] the names of the packages handled by the policy
1035
1112
  def package_names
1036
1113
  @packages.map { |p| p[:name] }
1037
1114
  end
1038
1115
 
1039
- ### Add a package to the list of pkgs handled by this policy.
1040
- ### If the pkg already exists in the policy, nil is returned and
1041
- ### no changes are made.
1042
- ###
1043
- ### @param [String,Integer] identifier the name or id of the package to add to this policy
1044
- ###
1045
- ### @param [Hash] opts the options for this pkg
1046
- ###
1047
- ### @option [Symbol, Integer] position: :end where to add this pkg among the list of
1048
- ### pkgs. Zero-based, :start and 0 are the same, as are :end and -1. Defaults to :end
1049
- ###
1050
- ### @option [String] action: 'Install' One of the values of PACKAGE_ACTIONS
1051
- ###
1052
- ### @option [Boolean] feu: false Overrides the setting for the pkg itself
1053
- ###
1054
- ### @option [Boolean] fut: false Overrides the setting for the pkg itself
1055
- ###
1056
- ### @option [Boolean] update_autorun: false
1057
- ###
1058
- ### @return [Array, nil] the new @packages array, nil if pkg was already in the policy
1059
- ###
1060
- def add_package(identifier, opts = {})
1061
- opts[:position] ||= -1
1062
- opts[:action] ||= :install
1063
- opts[:feu] = false if opts[:feu].nil?
1064
- opts[:fut] = false if opts[:fut].nil?
1065
- opts[:update_autorun] = false if opts[:update_autorun].nil?
1066
-
1067
- id = JSS::Package.valid_id identifier, api: @api
1068
- raise JSS::NoSuchItemError, "No package matches '#{identifier}'" unless id
1116
+ # Add a package to the list of pkgs handled by this policy.
1117
+ # If the pkg already exists in the policy, nil is returned and
1118
+ # no changes are made.
1119
+ #
1120
+ # @param [String,Integer] identifier the name or id of the package to add to this policy
1121
+ #
1122
+ # @param position [Symbol, Integer] where to add this pkg among the list of
1123
+ # pkgs. Zero-based, :start and 0 are the same, as are :end and -1.
1124
+ # Defaults to :end
1125
+ #
1126
+ # @param action [String] One of the values of PACKAGE_ACTIONS
1127
+ #
1128
+ # @param feu [Boolean] Overrides the setting for the pkg itself Defaults to false
1129
+ #
1130
+ # @param fut [Boolean] Overrides the setting for the pkg itself Defaults to false
1131
+ #
1132
+ # @param update_autorun [Boolean] Defaults to false
1133
+ #
1134
+ # @return [Array, nil] the new @packages array, nil if pkg was already in the policy
1135
+ #
1136
+ def add_package(identifier, **opts)
1137
+ id = validate_package_opts(identifier, opts)
1069
1138
 
1070
1139
  return nil if @packages.map { |p| p[:id] }.include? id
1071
1140
 
1072
1141
  name = JSS::Package.map_all_ids_to(:name, api: @api)[id]
1073
1142
 
1074
- position = case opts[:position]
1075
- when :start then 0
1076
- when :end then -1
1077
- else opts[:position]
1078
- end
1079
-
1080
- raise JSS::InvalidDataError, "action must be one of: :#{PACKAGE_ACTIONS.keys.join ', :'}" unless \
1081
- PACKAGE_ACTIONS.include? opts[:action]
1082
- raise JSS::InvalidDataError, 'feu must be true or false' unless \
1083
- JSS::TRUE_FALSE.include? opts[:feu]
1084
- raise JSS::InvalidDataError, 'fut must be true or false' unless \
1085
- JSS::TRUE_FALSE.include? opts[:fut]
1086
- raise JSS::InvalidDataError, 'update_autorun must be true or false' unless \
1087
- JSS::TRUE_FALSE.include? opts[:update_autorun]
1088
-
1089
1143
  pkg_data = {
1090
1144
  id: id,
1091
1145
  name: name,
@@ -1095,22 +1149,18 @@ module JSS
1095
1149
  update_autorun: opts[:update_autorun]
1096
1150
  }
1097
1151
 
1098
- @packages.insert position, pkg_data
1099
-
1100
- ### if the user gave a large number for position, it created nil entries in the array, they need
1101
- ### to be removed.
1102
- @packages.compact!
1152
+ @packages.insert opts[:position], pkg_data
1103
1153
 
1104
1154
  @need_to_update = true
1105
1155
  @packages
1106
1156
  end
1107
1157
 
1108
- ### Remove a package from this policy by name or id
1109
- ###
1110
- ### @param identfier [String,Integer] the name or id of the package to remove
1111
- ###
1112
- ### @return [Array, nil] the new packages array or nil if no change
1113
- ###
1158
+ # Remove a package from this policy by name or id
1159
+ #
1160
+ # @param identfier [String,Integer] the name or id of the package to remove
1161
+ #
1162
+ # @return [Array, nil] the new packages array or nil if no change
1163
+ #
1114
1164
  def remove_package(identifier)
1115
1165
  removed = @packages.delete_if { |p| p[:id] == identifier || p[:name] == identifier }
1116
1166
  @need_to_update = true if removed
@@ -1119,74 +1169,62 @@ module JSS
1119
1169
 
1120
1170
  ###### Scripts
1121
1171
 
1122
- ### @return [Array] the id's of the scripts handled by the policy
1172
+ # @return [Array] the id's of the scripts handled by the policy
1123
1173
  def script_ids
1124
1174
  @scripts.map { |p| p[:id] }
1125
1175
  end
1126
1176
 
1127
- ### @return [Array] the names of the scripts handled by the policy
1177
+ # @return [Array] the names of the scripts handled by the policy
1128
1178
  def script_names
1129
1179
  @scripts.map { |p| p[:name] }
1130
1180
  end
1131
1181
 
1132
- ### Add a script to the list of SCRIPT_PRIORITIESipts run by this policy.
1133
- ### If the script already exists in the policy, nil is returned and
1134
- ### no changes are made.
1135
- ###
1136
- ### @param [String,Integer] identifier the name or id of the script to add to this policy
1137
- ###
1138
- ### @param [Hash] opts the options for this script
1139
- ###
1140
- ### @option [Symbol, Integer] position: where to add this script among the list of
1141
- ### scripts. Zero-based, :start and 0 are the same, as are :end and -1. Defaults to :end
1142
- ###
1143
- ### @option [Symbol] priority: either :before or :after
1144
- ###
1145
- ### @option [String] parameter4: the value of the 4th parameter passed to the script. this
1146
- ### overrides the same parameter in the script object itself.
1147
- ###
1148
- ### @option [String] parameter5: the value of the 5th parameter passed to the script. this
1149
- ### overrides the same parameter in the script object itself.
1150
- ###
1151
- ### @option [String] parameter6: the value of the 6th parameter passed to the script. this
1152
- ### overrides the same parameter in the script object itself.
1153
- ###
1154
- ### @option [String] parameter7: the value of the 7th parameter passed to the script. this
1155
- ### overrides the same parameter in the script object itself.
1156
- ###
1157
- ### @option [String] parameter8: the value of the 8th parameter passed to the script. this
1158
- ### overrides the same parameter in the script object itself.
1159
- ###
1160
- ### @option [String] parameter9: the value of the 9th parameter passed to the script. this
1161
- ### overrides the same parameter in the script object itself.
1162
- ###
1163
- ### @option [String] parameter10: the value of the 10th parameter passed to the script. this
1164
- ### overrides the same parameter in the script object itself.
1165
- ###
1166
- ### @option [String] parameter11: the value of the 11th parameter passed to the script. this
1167
- ### overrides the same parameter in the script object itself.
1168
- ###
1169
- ### @return [Array, nil] the new @scripts array, nil if script was already in the policy
1170
- ###
1171
- def add_script(identifier, opts = {})
1172
- opts[:position] ||= -1
1173
- opts[:priority] ||= :after
1174
-
1175
- raise JSS::NoSuchItemError, "No script matches '#{identifier}'" unless (id = JSS::Script.valid_id(identifier, api: @api))
1182
+ # Add a script to the list of SCRIPT_PRIORITIESipts run by this policy.
1183
+ # If the script already exists in the policy, nil is returned and
1184
+ # no changes are made.
1185
+ #
1186
+ # @param [String,Integer] identifier the name or id of the script to add to this policy
1187
+ #
1188
+ # @param [Hash] opts the options for this script
1189
+ #
1190
+ # @option [Symbol, Integer] position: where to add this script among the list of
1191
+ # scripts. Zero-based, :start and 0 are the same, as are :end and -1. Defaults to :end
1192
+ #
1193
+ # @option [Symbol] priority: either :before or :after
1194
+ #
1195
+ # @option [String] parameter4: the value of the 4th parameter passed to the script. this
1196
+ # overrides the same parameter in the script object itself.
1197
+ #
1198
+ # @option [String] parameter5: the value of the 5th parameter passed to the script. this
1199
+ # overrides the same parameter in the script object itself.
1200
+ #
1201
+ # @option [String] parameter6: the value of the 6th parameter passed to the script. this
1202
+ # overrides the same parameter in the script object itself.
1203
+ #
1204
+ # @option [String] parameter7: the value of the 7th parameter passed to the script. this
1205
+ # overrides the same parameter in the script object itself.
1206
+ #
1207
+ # @option [String] parameter8: the value of the 8th parameter passed to the script. this
1208
+ # overrides the same parameter in the script object itself.
1209
+ #
1210
+ # @option [String] parameter9: the value of the 9th parameter passed to the script. this
1211
+ # overrides the same parameter in the script object itself.
1212
+ #
1213
+ # @option [String] parameter10: the value of the 10th parameter passed to the script. this
1214
+ # overrides the same parameter in the script object itself.
1215
+ #
1216
+ # @option [String] parameter11: the value of the 11th parameter passed to the script. this
1217
+ # overrides the same parameter in the script object itself.
1218
+ #
1219
+ # @return [Array, nil] the new @scripts array, nil if script was already in the policy
1220
+ #
1221
+ def add_script(identifier, **opts)
1222
+ id = validate_script_opts(identifier, opts)
1176
1223
 
1177
1224
  return nil if @scripts.map { |s| s[:id] }.include? id
1178
1225
 
1179
1226
  name = JSS::Script.map_all_ids_to(:name, api: @api)[id]
1180
1227
 
1181
- position = case opts[:position]
1182
- when :start then 0
1183
- when :end then -1
1184
- else opts[:position]
1185
- end
1186
-
1187
- raise JSS::InvalidDataError, "priority must be one of: :#{SCRIPT_PRIORITIES.keys.join ', :'}" unless \
1188
- SCRIPT_PRIORITIES.include? opts[:priority]
1189
-
1190
1228
  script_data = {
1191
1229
  id: id,
1192
1230
  name: name,
@@ -1201,22 +1239,18 @@ module JSS
1201
1239
  parameter11: opts[:parameter11]
1202
1240
  }
1203
1241
 
1204
- @scripts.insert position, script_data
1205
-
1206
- ### if the user gave a large number for position, it created nil entries in the array, they need
1207
- ### to be removed.
1208
- @scripts.compact!
1242
+ @scripts.insert opts[:position], script_data
1209
1243
 
1210
1244
  @need_to_update = true
1211
1245
  @scripts
1212
1246
  end
1213
1247
 
1214
- ### Remove a script from this policy by name or id
1215
- ###
1216
- ### @param identfier [String,Integer] the name or id of the script to remove
1217
- ###
1218
- ### @return [Array, nil] the new scripts array or nil if no change
1219
- ###
1248
+ # Remove a script from this policy by name or id
1249
+ #
1250
+ # @param identfier [String,Integer] the name or id of the script to remove
1251
+ #
1252
+ # @return [Array, nil] the new scripts array or nil if no change
1253
+ #
1220
1254
  def remove_script(identifier)
1221
1255
  removed = @scripts.delete_if { |s| s[:id] == identifier || s[:name] == identifier }
1222
1256
  @need_to_update = true if removed
@@ -1225,56 +1259,57 @@ module JSS
1225
1259
 
1226
1260
  ###### Directory Bindings
1227
1261
 
1228
- ### @return [Array] the id's of the directory_bindings handled by the policy
1262
+ # @return [Array] the id's of the directory_bindings handled by the policy
1229
1263
  def directory_binding_ids
1230
1264
  @directory_bindings.map { |p| p[:id] }
1231
1265
  end
1232
1266
 
1233
- ### @return [Array] the names of the directory_bindings handled by the policy
1267
+ # @return [Array] the names of the directory_bindings handled by the policy
1234
1268
  def directory_binding_names
1235
1269
  @directory_bindings.map { |p| p[:name] }
1236
1270
  end
1237
1271
 
1238
1272
  ###### Dock items
1239
1273
 
1240
- ### @return [Array] the id's of the dock_items handled by the policy
1274
+ # @return [Array] the id's of the dock_items handled by the policy
1241
1275
  def dock_item_ids
1242
1276
  @dock_items.map { |p| p[:id] }
1243
1277
  end
1244
1278
 
1245
- ### @return [Array] the names of the dock_items handled by the policy
1279
+ # @return [Array] the names of the dock_items handled by the policy
1246
1280
  def dock_item_names
1247
1281
  @dock_items.map { |p| p[:name] }
1248
1282
  end
1249
1283
 
1250
1284
  ###### Printers
1251
1285
 
1252
- ### @return [Array] the id's of the printers handled by the policy
1286
+ # @return [Array] the id's of the printers handled by the policy
1253
1287
  def printer_ids
1254
1288
  @printers.map { |p| p[:id] }
1255
1289
  end
1256
1290
 
1257
- ### @return [Array] the names of the printers handled by the policy
1291
+ # @return [Array] the names of the printers handled by the policy
1258
1292
  def printer_names
1259
1293
  @printers.map { |p| p[:name] }
1260
1294
  end
1261
1295
 
1262
1296
  ###### Actions
1263
1297
 
1264
- ### Try to execute this policy on this machine.
1265
- ###
1266
- ### @param show_output[Boolean] should the stdout and stderr of the
1267
- ### 'jamf policy' command be sent to stdout in realtime?
1268
- ###
1269
- ### @return [Boolean, nil] The success of the 'jamf policy' command, or nil
1270
- ### if the policy couldn't be executed (out of scope, policy disabled, etc)
1271
- ###
1298
+ # Try to execute this policy on this machine.
1299
+ #
1300
+ # @param show_output[Boolean] should the stdout and stderr of the
1301
+ # 'jamf policy' command be sent to stdout in realtime?
1302
+ #
1303
+ # @return [Boolean, nil] The success of the 'jamf policy' command, or nil
1304
+ # if the policy couldn't be executed (out of scope, policy disabled, etc)
1305
+ #
1272
1306
  def run(show_output = false)
1273
1307
  return nil unless enabled?
1274
1308
  output = JSS::Client.run_jamf('policy', "-id #{id}", show_output)
1275
1309
  return nil if output.include? 'No policies were found for the ID'
1276
1310
  $CHILD_STATUS.exitstatus.zero? ? true : false
1277
1311
  end
1312
+ alias execute run
1278
1313
 
1279
1314
  # Flush all policy logs for this policy older than
1280
1315
  # some number of days, weeks, months or years.
@@ -1291,30 +1326,90 @@ module JSS
1291
1326
  # @return [void]
1292
1327
  #
1293
1328
  def flush_logs(older_than: 0, period: :days)
1294
- raise JSS::NoSuchItemError, "Policy doesn't exist in the JSS. Use #create first." \
1295
- unless @in_jss
1296
- raise JSS::InvalidDataError, "older_than must be one of: #{LOG_FLUSH_INTERVAL_INTEGERS.keys.join ', '}" \
1297
- unless LOG_FLUSH_INTERVAL_INTEGERS.keys.include? older_than
1298
- raise JSS::InvalidDataError, "period must be one of: :#{LOG_FLUSH_INTERVAL_PERIODS.keys.join ', :'}" \
1299
- unless LOG_FLUSH_INTERVAL_PERIODS.keys.include? period
1329
+ raise JSS::NoSuchItemError, "Policy doesn't exist in the JSS. Use #create first." unless @in_jss
1330
+
1331
+ unless LOG_FLUSH_INTERVAL_INTEGERS.key?(older_than)
1332
+ raise JSS::InvalidDataError, "older_than must be one of these integers: #{LOG_FLUSH_INTERVAL_INTEGERS.keys.join ', '}"
1333
+ end
1334
+
1335
+ unless LOG_FLUSH_INTERVAL_PERIODS.key?(period)
1336
+ raise JSS::InvalidDataError, "period must be one of these symbols: :#{LOG_FLUSH_INTERVAL_PERIODS.keys.join ', :'}"
1337
+ end
1300
1338
 
1301
1339
  interval = "#{LOG_FLUSH_INTERVAL_INTEGERS[older_than]}+#{LOG_FLUSH_INTERVAL_PERIODS[period]}"
1302
1340
 
1303
1341
  @api.delete_rsrc "#{LOG_FLUSH_RSRC}/policy/id/#{@id}/interval/#{interval}"
1304
1342
  end
1305
1343
 
1306
- ###### Aliases
1307
-
1308
- alias enabled? enabled
1309
- alias pkgs packages
1310
- alias command_to_run run_command
1311
- alias delete_path? delete_file?
1312
- alias execute run
1313
-
1314
- ### Private Instance Methods
1344
+ # Private Instance Methods
1315
1345
  #####################################
1346
+
1316
1347
  private
1317
1348
 
1349
+ # raise an error if a package being added isn't valid
1350
+ #
1351
+ # @see #add_package
1352
+ #
1353
+ # @return [Integer, nil] the valid id for the package
1354
+ #
1355
+ def validate_package_opts(identifier, opts)
1356
+ opts[:position] ||= -1
1357
+ opts[:action] ||= :install
1358
+ opts[:feu] ||= false
1359
+ opts[:fut] ||= false
1360
+ opts[:update_autorun] ||= false
1361
+
1362
+ opts[:position] =
1363
+ case opts[:position]
1364
+ when :start then 0
1365
+ when :end then -1
1366
+ else JSS::Validate.integer(opts[:position])
1367
+ end
1368
+
1369
+ # if the given position is past the end, set it to -1 (the end)
1370
+ opts[:position] = -1 if opts[:position] > @packages.size
1371
+
1372
+ id = JSS::Package.valid_id identifier, api: @api
1373
+
1374
+ raise JSS::NoSuchItemError, "No package matches '#{identifier}'" unless id
1375
+
1376
+ raise JSS::InvalidDataError, "action must be one of: :#{PACKAGE_ACTIONS.keys.join ', :'}" unless \
1377
+ PACKAGE_ACTIONS.include? opts[:action]
1378
+
1379
+ opts[:feu] = JSS::Validate.boolean opts[:feu]
1380
+ opts[:fut] = JSS::Validate.boolean opts[:fut]
1381
+ opts[:update_autorun] = JSS::Validate.boolean opts[:update_autorun]
1382
+ id
1383
+ end
1384
+
1385
+ # raise an error if a script being added isn't valid
1386
+ #
1387
+ # @see #add_script
1388
+ #
1389
+ # @return [Integer, nil] the valid id for the package
1390
+ #
1391
+ def validate_script_opts(identifier, opts)
1392
+ opts[:position] ||= -1
1393
+ opts[:priority] ||= :after
1394
+
1395
+ raise JSS::InvalidDataError, "priority must be one of: :#{SCRIPT_PRIORITIES.keys.join ', :'}" unless \
1396
+ SCRIPT_PRIORITIES.include? opts[:priority]
1397
+
1398
+ opts[:position] =
1399
+ case opts[:position]
1400
+ when :start then 0
1401
+ when :end then -1
1402
+ else JSS::Validate.integer(opts[:position])
1403
+ end
1404
+
1405
+ # if the given position is past the end, set it to -1 (the end)
1406
+ opts[:position] = -1 if opts[:position] > @packages.size
1407
+
1408
+ id = JSS::Script.valid_id identifier, api: @api
1409
+ raise JSS::NoSuchItemError, "No script matches '#{identifier}'" unless id
1410
+ id
1411
+ end
1412
+
1318
1413
  def rest_xml
1319
1414
  doc = REXML::Document.new APIConnection::XML_HEADER
1320
1415
  obj = doc.add_element RSRC_OBJECT_KEY.to_s
@@ -1331,19 +1426,25 @@ module JSS
1331
1426
  JSS.hash_to_rexml_array(@trigger_events).each { |t| general << t }
1332
1427
 
1333
1428
  date_time_limitations = general.add_element 'date_time_limitations'
1334
- date_time_limitations.add_element('expiration_date_epoch').text = @server_side_limitations[:expiration].to_jss_epoch if @server_side_limitations[:expiration]
1335
- date_time_limitations.add_element('activation_date_epoch').text = @server_side_limitations[:activation].to_jss_epoch if @server_side_limitations[:activation]
1429
+ exp = @server_side_limitations[:expiration]
1430
+ date_time_limitations.add_element('expiration_date_epoch').text = exp.to_jss_epoch if exp
1431
+ activation = @server_side_limitations[:activation]
1432
+ date_time_limitations.add_element('activation_date_epoch').text = activation.to_jss_epoch if activation
1336
1433
 
1337
1434
  obj << @scope.scope_xml
1338
1435
 
1339
1436
  reboot = obj.add_element 'reboot'
1340
- reboot.add_element('message').text = @reboot_options[:message] if @reboot_options[:message]
1341
- reboot.add_element('startup_disk').text = @reboot_options[:startup_disk] if @reboot_options[:startup_disk]
1342
- reboot.add_element('specify_startup').text = @reboot_options[:specify_startup] if @reboot_options[:specify_startup]
1343
- reboot.add_element('no_user_logged_in').text = @reboot_options[:no_user_logged_in] if @reboot_options[:no_user_logged_in]
1344
- reboot.add_element('user_logged_in').text = @reboot_options[:user_logged_in] if @reboot_options[:user_logged_in]
1345
- reboot.add_element('minutes_until_reboot').text = @reboot_options[:minutes_until_reboot] if @reboot_options[:minutes_until_reboot]
1346
- reboot.add_element('file_vault_2_reboot').text = @reboot_options[:file_vault_2_reboot] if @reboot_options[:file_vault_2_reboot]
1437
+ JSS.hash_to_rexml_array(@reboot_options).each { |elem| reboot << elem }
1438
+
1439
+ maint = obj.add_element 'maintenance'
1440
+ maint.add_element('recon').text = @recon.to_s
1441
+ maint.add_element('reset_name').text = @reset_name.to_s
1442
+ maint.add_element('install_all_cached_packages').text = @install_cached_pkgs.to_s
1443
+ maint.add_element('permissions').text = @permissions_repair.to_s
1444
+ maint.add_element('byhost').text = @fix_byhost.to_s
1445
+ maint.add_element('system_cache').text = @flush_system_cache.to_s
1446
+ maint.add_element('user_cache').text = @user_cache.to_s
1447
+ maint.add_element('verify').text = @verify_startup_disk.to_s
1347
1448
 
1348
1449
  files_processes = obj.add_element 'files_processes'
1349
1450
  JSS.hash_to_rexml_array(@files_processes).each { |f| files_processes << f }