ruby-jss 0.6.5 → 0.6.6

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

Potentially problematic release.


This version of ruby-jss might be problematic. Click here for more details.

Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +57 -5
  3. data/lib/jss.rb +78 -94
  4. data/lib/jss/api_connection.rb +8 -0
  5. data/lib/jss/api_object.rb +126 -102
  6. data/lib/jss/api_object/creatable.rb +33 -15
  7. data/lib/jss/api_object/distribution_point.rb +4 -1
  8. data/lib/jss/api_object/extension_attribute.rb +1 -1
  9. data/lib/jss/api_object/package.rb +121 -187
  10. data/lib/jss/api_object/policy.rb +590 -251
  11. data/lib/jss/api_object/script.rb +92 -128
  12. data/lib/jss/api_object/self_servable.rb +93 -117
  13. data/lib/jss/api_object/updatable.rb +12 -27
  14. data/lib/jss/api_object/uploadable.rb +12 -15
  15. data/lib/jss/client.rb +178 -156
  16. data/lib/jss/db_connection.rb +34 -49
  17. data/lib/jss/ruby_extensions/string.rb +25 -21
  18. data/lib/jss/version.rb +1 -1
  19. data/lib/jss/webhooks.rb +52 -0
  20. data/lib/jss/webhooks/README.md +269 -0
  21. data/lib/jss/webhooks/configuration.rb +212 -0
  22. data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation-executable +90 -0
  23. data/lib/jss/webhooks/data/sample_handlers/RestAPIOperation.rb +44 -0
  24. data/lib/jss/webhooks/data/sample_jsons/ComputerAdded.json +27 -0
  25. data/lib/jss/webhooks/data/sample_jsons/ComputerCheckIn.json +27 -0
  26. data/lib/jss/webhooks/data/sample_jsons/ComputerInventoryCompleted.json +27 -0
  27. data/lib/jss/webhooks/data/sample_jsons/ComputerPolicyFinished.json +27 -0
  28. data/lib/jss/webhooks/data/sample_jsons/ComputerPushCapabilityChanged.json +27 -0
  29. data/lib/jss/webhooks/data/sample_jsons/JSSShutdown.json +14 -0
  30. data/lib/jss/webhooks/data/sample_jsons/JSSStartup.json +14 -0
  31. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCheckIn.json +26 -0
  32. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceCommandCompleted.json +26 -0
  33. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceEnrolled.json +26 -0
  34. data/lib/jss/webhooks/data/sample_jsons/MobileDevicePushSent.json +26 -0
  35. data/lib/jss/webhooks/data/sample_jsons/MobileDeviceUnEnrolled.json +26 -0
  36. data/lib/jss/webhooks/data/sample_jsons/PatchSoftwareTitleUpdated.json +14 -0
  37. data/lib/jss/webhooks/data/sample_jsons/PushSent.json +11 -0
  38. data/lib/jss/webhooks/data/sample_jsons/RestAPIOperation.json +15 -0
  39. data/lib/jss/webhooks/data/sample_jsons/SCEPChallenge.json +10 -0
  40. data/lib/jss/webhooks/data/sample_jsons/SmartGroupComputerMembershipChange.json +13 -0
  41. data/lib/jss/webhooks/data/sample_jsons/SmartGroupMobileDeviceMembershipChange.json +13 -0
  42. data/lib/jss/webhooks/event.rb +138 -0
  43. data/lib/jss/webhooks/event/computer_added.rb +37 -0
  44. data/lib/jss/webhooks/event/computer_check_in.rb +37 -0
  45. data/lib/jss/webhooks/event/computer_inventory_completed.rb +37 -0
  46. data/lib/jss/webhooks/event/computer_policy_finished.rb +37 -0
  47. data/lib/jss/webhooks/event/computer_push_capability_changed.rb +37 -0
  48. data/lib/jss/webhooks/event/handlers.rb +191 -0
  49. data/lib/jss/webhooks/event/jss_shutdown.rb +37 -0
  50. data/lib/jss/webhooks/event/jss_startup.rb +37 -0
  51. data/lib/jss/webhooks/event/mobile_device_check_in.rb +37 -0
  52. data/lib/jss/webhooks/event/mobile_device_command_completed.rb +37 -0
  53. data/lib/jss/webhooks/event/mobile_device_enrolled.rb +37 -0
  54. data/lib/jss/webhooks/event/mobile_device_push_sent.rb +37 -0
  55. data/lib/jss/webhooks/event/mobile_device_unenrolled.rb +37 -0
  56. data/lib/jss/webhooks/event/patch_software_title_updated.rb +37 -0
  57. data/lib/jss/webhooks/event/push_sent.rb +37 -0
  58. data/lib/jss/webhooks/event/rest_api_operation.rb +37 -0
  59. data/lib/jss/webhooks/event/scep_challenge.rb +37 -0
  60. data/lib/jss/webhooks/event/smart_group_computer_membership_change.rb +37 -0
  61. data/lib/jss/webhooks/event/smart_group_mobile_device_membership_change.rb +37 -0
  62. data/lib/jss/webhooks/event/webhook.rb +39 -0
  63. data/lib/jss/webhooks/event_objects.rb +111 -0
  64. data/lib/jss/webhooks/event_objects/computer.rb +48 -0
  65. data/lib/jss/webhooks/event_objects/jss.rb +35 -0
  66. data/lib/jss/webhooks/event_objects/mobile_device.rb +47 -0
  67. data/lib/jss/webhooks/event_objects/patch_software_title_update.rb +37 -0
  68. data/lib/jss/webhooks/event_objects/push.rb +32 -0
  69. data/lib/jss/webhooks/event_objects/rest_api_operation.rb +36 -0
  70. data/lib/jss/webhooks/event_objects/scep_challenge.rb +31 -0
  71. data/lib/jss/webhooks/event_objects/smart_group.rb +34 -0
  72. data/lib/jss/webhooks/server_app.rb +36 -0
  73. data/lib/jss/webhooks/server_app/routes.rb +26 -0
  74. data/lib/jss/webhooks/server_app/routes/handle_webhook_event.rb +38 -0
  75. data/lib/jss/webhooks/server_app/routes/home.rb +36 -0
  76. data/lib/jss/webhooks/server_app/self_signed_cert.rb +64 -0
  77. data/lib/jss/webhooks/server_app/server.rb +59 -0
  78. data/lib/jss/webhooks/version.rb +31 -0
  79. metadata +63 -4
@@ -1,25 +1,25 @@
1
1
  ### Copyright 2016 Pixar
2
- ###
2
+ ###
3
3
  ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
4
  ### with the following modification; you may not use this file except in
5
5
  ### compliance with the Apache License and the following modification to it:
6
6
  ### Section 6. Trademarks. is deleted and replaced with:
7
- ###
7
+ ###
8
8
  ### 6. Trademarks. This License does not grant permission to use the trade
9
9
  ### names, trademarks, service marks, or product names of the Licensor
10
10
  ### and its affiliates, except as required to comply with Section 4(c) of
11
11
  ### the License and to reproduce the content of the NOTICE file.
12
- ###
12
+ ###
13
13
  ### You may obtain a copy of the Apache License at
14
- ###
14
+ ###
15
15
  ### http://www.apache.org/licenses/LICENSE-2.0
16
- ###
16
+ ###
17
17
  ### Unless required by applicable law or agreed to in writing, software
18
18
  ### distributed under the Apache License with the above modification is
19
19
  ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
20
  ### KIND, either express or implied. See the Apache License for the specific
21
21
  ### language governing permissions and limitations under the Apache License.
22
- ###
22
+ ###
23
23
  ###
24
24
 
25
25
  ###
@@ -29,7 +29,6 @@ module JSS
29
29
  ### Module Variables
30
30
  #####################################
31
31
 
32
-
33
32
  #####################################
34
33
  ### Module Methods
35
34
  #####################################
@@ -91,13 +90,12 @@ module JSS
91
90
  ### Constants
92
91
  #####################################
93
92
 
94
- UPLOAD_RSRC_PREFIX = "fileuploads"
93
+ UPLOAD_RSRC_PREFIX = 'fileuploads'.freeze
95
94
 
96
95
  #####################################
97
96
  ### Variables
98
97
  #####################################
99
98
 
100
-
101
99
  #####################################
102
100
  ### Methods
103
101
  #####################################
@@ -115,22 +113,21 @@ module JSS
115
113
  ### @return [String] The xml response from the server.
116
114
  ###
117
115
  def upload(type, local_file)
118
-
119
116
  ### the thing's gotta be in the JSS, and have an @id
120
- raise JSS::NoSuchItemError, 'Create this #{self.class::RSRC_OBJECT_KEY} in the JSS before uploading files to it.' unless @id and @in_jss
117
+ raise JSS::NoSuchItemError, 'Create this #{self.class::RSRC_OBJECT_KEY} in the JSS before uploading files to it.' unless @id && @in_jss
121
118
 
122
119
  ### the type has to be defined in the class of self.
123
- raise JSS::InvalidDataError, "#{self.class::RSRC_LIST_KEY} only take uploads of type: :#{self.class::UPLOAD_TYPES.keys.join(', :')}." unless self.class::UPLOAD_TYPES.keys.include? type
120
+ raise JSS::InvalidDataError, "#{self.class::RSRC_LIST_KEY} only take uploads of type: :#{self.class::UPLOAD_TYPES.keys.join(', :')}." \
121
+ unless self.class::UPLOAD_TYPES.keys.include? type
124
122
 
125
123
  ### figure out the resource after the UPLOAD_RSRC_PREFIX
126
124
  upload_rsrc = "#{UPLOAD_RSRC_PREFIX}/#{self.class::UPLOAD_TYPES[type]}/id/#{@id}"
127
125
 
128
- ### make a File object to hand to REST.
126
+ ### make a File object to hand to REST. 'rb' = read,binary
129
127
  file = File.new local_file.to_s, 'rb'
130
128
 
131
129
  ### upload it!
132
- JSS::API.cnx[upload_rsrc].post :name => file
133
-
130
+ JSS::API.cnx[upload_rsrc].post name: file
134
131
  end # def upload file
135
132
 
136
133
  end # module FileUpload
@@ -25,19 +25,15 @@
25
25
  ###
26
26
  module JSS
27
27
 
28
- #####################################
29
28
  ### Module Variables
30
29
  #####################################
31
30
 
32
- #####################################
33
31
  ### Module Methods
34
32
  #####################################
35
33
 
36
- #####################################
37
34
  ### Classes
38
35
  #####################################
39
36
 
40
- ###
41
37
  ### This class represents a Casper/JSS Client computer, on which
42
38
  ### this code is running.
43
39
  ###
@@ -55,42 +51,42 @@ module JSS
55
51
 
56
52
  ### The Pathname to the jamf binary executable
57
53
  ### As of El Capitan (OS X 10.11) the location has moved.
58
- ORIG_JAMF_BINARY = Pathname.new "/usr/sbin/jamf"
59
- ELCAP_JAMF_BINARY = Pathname.new "/usr/local/jamf/bin/jamf"
54
+ ORIG_JAMF_BINARY = Pathname.new '/usr/sbin/jamf'
55
+ ELCAP_JAMF_BINARY = Pathname.new '/usr/local/jamf/bin/jamf'
60
56
  JAMF_BINARY = ELCAP_JAMF_BINARY.executable? ? ELCAP_JAMF_BINARY : ORIG_JAMF_BINARY
61
57
 
62
58
  ### The Pathname to the jamfHelper executable
63
- JAMF_HELPER = Pathname.new "/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
59
+ JAMF_HELPER = Pathname.new '/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper'
64
60
 
65
61
  ### The window_type options for jamfHelper
66
62
  JAMF_HELPER_WINDOW_TYPES = {
67
- :hud => 'hud',
68
- :utility => 'utility',
69
- :util => 'utility',
70
- :full_screen => 'fs',
71
- :fs => 'fs'
72
- }
63
+ hud: 'hud',
64
+ utility: 'utility',
65
+ util: 'utility',
66
+ full_screen: 'fs',
67
+ fs: 'fs'
68
+ }.freeze
73
69
 
74
70
  ### The possible window positions for jamfHelper
75
- JAMF_HELPER_WINDOW_POSITIONS = [nil, :ul, :ll, :ur, :lr]
71
+ JAMF_HELPER_WINDOW_POSITIONS = [nil, :ul, :ll, :ur, :lr].freeze
76
72
 
77
73
  ### The available buttons in jamfHelper
78
- JAMF_HELPER_BUTTONS = [1,2]
74
+ JAMF_HELPER_BUTTONS = [1, 2].freeze
79
75
 
80
76
  ### The possible alignment positions in jamfHelper
81
- JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural]
77
+ JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural].freeze
82
78
 
83
79
  ### The Pathname to the preferences plist used by the jamf binary
84
- JAMF_PLIST = Pathname.new "/Library/Preferences/com.jamfsoftware.jamf.plist"
80
+ JAMF_PLIST = Pathname.new '/Library/Preferences/com.jamfsoftware.jamf.plist'
85
81
 
86
82
  ### The Pathname to the JAMF support folder
87
- JAMF_SUPPORT_FOLDER = Pathname.new "/Library/Application Support/JAMF"
83
+ JAMF_SUPPORT_FOLDER = Pathname.new '/Library/Application Support/JAMF'
88
84
 
89
85
  ### The JAMF receipts folder, where package installs are tracked.
90
- RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER + "Receipts"
86
+ RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER + 'Receipts'
91
87
 
92
88
  ### The JAMF downloads folder
93
- DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER + "Downloads"
89
+ DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER + 'Downloads'
94
90
 
95
91
  ### These jamf commands don't need root privs (most do)
96
92
  ROOTLESS_JAMF_COMMANDS = [
@@ -100,7 +96,8 @@ module JSS
100
96
  :getComputerName,
101
97
  :help,
102
98
  :listUsers,
103
- :version ]
99
+ :version
100
+ ].freeze
104
101
 
105
102
  #####################################
106
103
  ### Class Variables
@@ -110,7 +107,6 @@ module JSS
110
107
  ### Class Methods
111
108
  #####################################
112
109
 
113
- ###
114
110
  ### Get the current IP address as a String.
115
111
  ###
116
112
  ### This handy code doesn't acutally make a UDP connection,
@@ -125,7 +121,8 @@ module JSS
125
121
  def self.my_ip_address
126
122
  ### turn off reverse DNS resolution temporarily
127
123
  ### @note the 'socket' library has already been required by 'rest-client'
128
- orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
124
+ orig = Socket.do_not_reverse_lookup
125
+ Socket.do_not_reverse_lookup = true
129
126
 
130
127
  UDPSocket.open do |s|
131
128
  s.connect '192.168.0.0', 1
@@ -135,8 +132,23 @@ module JSS
135
132
  Socket.do_not_reverse_lookup = orig
136
133
  end
137
134
 
135
+ ### Who's logged in to the console right now?
136
+ ###
137
+ ### @return [String, nil] the username of the current console user, or nil if none.
138
+ ###
139
+ def self.console_user
140
+ cmd = '/usr/sbin/scutil'
141
+ qry = 'show State:/Users/ConsoleUser'
142
+ Open3.popen2e(cmd) do |cmdin, cmdouterr, _wait_thr|
143
+ cmdin.puts qry
144
+ cmdin.close
145
+ out = cmdouterr.read
146
+ user = out.lines.select { |l| l =~ /^\s+Name\s*:/ }.first.to_s.split(/\s*:\s*/).last
147
+ return user.nil? ? user : user.chomp
148
+ end # do
149
+ end
138
150
 
139
-
151
+ ### Is the jamf binary installed?
140
152
  ###
141
153
  ### @return [Boolean] is the jamf binary installed?
142
154
  ###
@@ -144,50 +156,56 @@ module JSS
144
156
  JAMF_BINARY.executable?
145
157
  end
146
158
 
159
+ ### What version of the jamf binary is installed?
147
160
  ###
148
161
  ### @return [String,nil] the version of the jamf binary installed on this client, nil if not installed
149
162
  ###
150
163
  def self.jamf_version
151
- self.installed? ? self.run_jamf(:version).chomp.split('=')[1] : nil
164
+ installed? ? run_jamf(:version).chomp.split('=')[1] : nil
152
165
  end
153
166
 
167
+ ### the URL to the jss for this client
154
168
  ###
155
169
  ### @return [String] the url to the JSS for this client
156
170
  ###
157
171
  def self.jss_url
158
- @url = self.jamf_plist['jss_url']
172
+ @url = jamf_plist['jss_url']
159
173
  return nil if @url.nil?
160
174
  @url =~ %r{(https?)://(.+):(\d+)/}
161
- @protocol = $1
162
- @server = $2
163
- @port = $3
164
- return @url
175
+ @protocol = Regexp.last_match(1)
176
+ @server = Regexp.last_match(2)
177
+ @port = Regexp.last_match(3)
178
+ @url
165
179
  end
166
180
 
181
+ ### The JSS server hostname for this client
167
182
  ###
168
183
  ### @return [String] the JSS server for this client
169
184
  ###
170
185
  def self.jss_server
171
- self.jss_url
172
- return @server
186
+ jss_url
187
+ @server
173
188
  end
174
189
 
190
+ ### The protocol for JSS connections for this client
175
191
  ###
176
192
  ### @return [String] the protocol to the JSS for this client, "http" or "https"
177
193
  ###
178
194
  def self.jss_protocol
179
- self.jss_url
180
- return @protocol
195
+ jss_url
196
+ @protocol
181
197
  end
182
198
 
199
+ ### The port number for JSS connections for this client
183
200
  ###
184
201
  ### @return [Integer] the port to the JSS for this client
185
202
  ###
186
203
  def self.jss_port
187
- self.jss_url
188
- @port ? @port.to_i : 80
204
+ jss_url
205
+ @port ? @port.to_i : 80
189
206
  end
190
207
 
208
+ ### The contents of the JAMF plist
191
209
  ###
192
210
  ### @return [Hash] the parsed contents of the JAMF_PLIST if it exists, an empty hash if not
193
211
  ###
@@ -196,58 +214,59 @@ module JSS
196
214
  Plist.parse_xml `/usr/libexec/PlistBuddy -x -c print #{Shellwords.escape JSS::Client::JAMF_PLIST.to_s}`
197
215
  end
198
216
 
199
-
217
+ ### All the JAMF receipts on this client
200
218
  ###
201
219
  ### @return [Array<Pathname>] an array of Pathnames for all regular files in the jamf receipts folder
202
220
  ###
203
221
  def self.receipts
204
222
  raise JSS::NoSuchItemError, "The JAMF Receipts folder doesn't exist on this computer." unless RECEIPTS_FOLDER.exist?
205
- RECEIPTS_FOLDER.children.select{|c| c.file?}
223
+ RECEIPTS_FOLDER.children.select(&:file?)
206
224
  end
207
225
 
226
+ ### Is the JSS available right now?
208
227
  ###
209
228
  ### @return [Boolean] is the JSS available now?
210
229
  ###
211
230
  def self.jss_available?
212
- output = run_jamf :checkJSSConnection, "-retry 1"
213
- $?.exitstatus == 0
231
+ run_jamf :checkJSSConnection, '-retry 1'
232
+ $CHILD_STATUS.exitstatus.zero?
214
233
  end
215
234
 
216
-
235
+ ### The JSS::Computer object for this computer
217
236
  ###
218
- ### @return [JSS::Computer] The JSS record for this computer
237
+ ### @return [JSS::Computer,nil] The JSS record for this computer, nil if not in the JSS
219
238
  ###
220
239
  def self.jss_record
221
- begin
222
- JSS::Computer.new :udid => self.udid
223
- rescue JSS::NoSuchItemError
224
- JSS::Computer.new :serial_number => self.serial_number
225
- end
240
+ JSS::Computer.new udid: udid
241
+ rescue JSS::NoSuchItemError
242
+ nil
226
243
  end
227
244
 
245
+ ### The UUID for this computer via system_profiler
228
246
  ###
229
247
  ### @return [String] the UUID/UDID for this computer
230
248
  ###
231
249
  def self.udid
232
- self.hardware_data["platform_UUID"]
250
+ hardware_data['platform_UUID']
233
251
  end
234
252
 
253
+ ### The serial number for this computer via system_profiler
235
254
  ###
236
255
  ### @return [String] the serial number for this computer
237
256
  ###
238
257
  def self.serial_number
239
- self.hardware_data["serial_number"]
258
+ hardware_data['serial_number']
240
259
  end
241
260
 
261
+ ### The parsed HardwareDataType output from system_profiler
242
262
  ###
243
263
  ### @return [Hash] the HardwareDataType data from the system_profiler command
244
264
  ###
245
265
  def self.hardware_data
246
266
  raw = `/usr/sbin/system_profiler SPHardwareDataType -xml 2>/dev/null`
247
- Plist.parse_xml(raw)[0]["_items"][0]
267
+ Plist.parse_xml(raw)[0]['_items'][0]
248
268
  end
249
269
 
250
-
251
270
  ### Run an arbitrary jamf binary command.
252
271
  ###
253
272
  ### @note Most jamf commands require superuser/root privileges.
@@ -275,22 +294,23 @@ module JSS
275
294
  ### The details of the Process::Status for the jamf binary process can be captured from $?
276
295
  ### immediately after calling. (See Process::Status)
277
296
  ###
278
- def self.run_jamf(command, args = nil, verbose = false)
279
- raise JSS::UnmanagedError, "The jamf binary is not installed on this computer." unless self.installed?
280
- raise JSS::UnsupportedError, "You must have root privileges to run that jamf binary command" unless ROOTLESS_JAMF_COMMANDS.include? command.to_sym or JSS.superuser?
297
+ def self.run_jamf(command, args = nil, verbose = false)
298
+ raise JSS::UnmanagedError, 'The jamf binary is not installed on this computer.' unless installed?
299
+ raise JSS::UnsupportedError, 'You must have root privileges to run that jamf binary command' unless \
300
+ ROOTLESS_JAMF_COMMANDS.include?(command.to_sym) || JSS.superuser?
281
301
 
282
302
  cmd = case args
283
- when nil
284
- "#{JAMF_BINARY} #{command}"
285
- when String
286
- "#{JAMF_BINARY} #{command} #{args}"
287
- when Array
288
- "#{([JAMF_BINARY.to_s, command] + args).join(' ')}"
289
- else
290
- raise JSS::InvalidDataError, "args must be a String or Array of Strings"
291
- end # case
292
-
293
- cmd += " -verbose" if verbose and (not cmd.include? " -verbose")
303
+ when nil
304
+ "#{JAMF_BINARY} #{command}"
305
+ when String
306
+ "#{JAMF_BINARY} #{command} #{args}"
307
+ when Array
308
+ ([JAMF_BINARY.to_s, command] + args).join(' ').to_s
309
+ else
310
+ raise JSS::InvalidDataError, 'args must be a String or Array of Strings'
311
+ end # case
312
+
313
+ cmd += ' -verbose' if verbose && (!cmd.include? ' -verbose')
294
314
  puts "Running: #{cmd}" if verbose
295
315
 
296
316
  output = []
@@ -301,11 +321,10 @@ module JSS
301
321
  end
302
322
  end
303
323
  install_out = output.join('')
304
- install_out.force_encoding("UTF-8") if install_out.respond_to? :force_encoding
305
- return install_out
324
+ install_out.force_encoding('UTF-8') if install_out.respond_to? :force_encoding
325
+ install_out
306
326
  end # run_jamf
307
327
 
308
-
309
328
  ### A wrapper for the jamfHelper command, which can display a window on the client machine.
310
329
  ###
311
330
  ### The first parameter must be a symbol defining what kind of window to display. The options are
@@ -345,7 +364,7 @@ module JSS
345
364
  ###
346
365
  ### @option opts :window_position [Symbol,nil] one of [ nil, :ul, :ll. :ur, :lr ]
347
366
  ### Positions window in the upper right, upper left, lower right or lower left of the user's screen
348
- ### If no input is given, the window defaults to the center of the screen
367
+ ### If no input is given, the window defaults to the center of the screen
349
368
  ###
350
369
  ### @option opts :title [String]
351
370
  ### Sets the window's title to the specified string
@@ -354,13 +373,13 @@ module JSS
354
373
  ### Sets the heading of the window to the specified string
355
374
  ###
356
375
  ### @option opts :align_heading [Symbol] one of [:right, :left, :center, :justified, :natural]
357
- ### Aligns the heading to the specified alignment
376
+ ### Aligns the heading to the specified alignment
358
377
  ###
359
378
  ### @option opts :description [String]
360
379
  ### Sets the main contents of the window to the specified string
361
380
  ###
362
381
  ### @option opts :align_description [Symbol] one of [:right, :left, :center, :justified, :natural]
363
- ### Aligns the description to the specified alignment
382
+ ### Aligns the description to the specified alignment
364
383
  ###
365
384
  ### @option opts :icon [String,Pathname]
366
385
  ### Sets the windows image field to the image located at the specified path
@@ -370,7 +389,7 @@ module JSS
370
389
  ###
371
390
  ### @option opts :full_screen_icon [any value]
372
391
  ### Scales the "icon" to the full size of the window.
373
- ### Note: Only available in full screen mode
392
+ ### Note: Only available in full screen mode
374
393
  ###
375
394
  ### @option opts :button1 [String]
376
395
  ### Creates a button with the specified label
@@ -379,17 +398,17 @@ module JSS
379
398
  ### Creates a second button with the specified label
380
399
  ###
381
400
  ### @option opts :default_button [Integer] either 1 or 2
382
- ### Sets the default button of the window to the specified button. The Default Button will respond to "return"
401
+ ### Sets the default button of the window to the specified button. The Default Button will respond to "return"
383
402
  ###
384
403
  ### @option opts :cancel_button [Integer] either 1 or 2
385
- ### Sets the cancel button of the window to the specified button. The Cancel Button will respond to "escape"
404
+ ### Sets the cancel button of the window to the specified button. The Cancel Button will respond to "escape"
386
405
  ###
387
406
  ### @option opts :timeout [Integer]
388
407
  ### Causes the window to timeout after the specified amount of seconds
389
- ### Note: The timeout will cause the default button, button 1 or button 2 to be selected (in that order)
408
+ ### Note: The timeout will cause the default button, button 1 or button 2 to be selected (in that order)
390
409
  ###
391
410
  ### @option opts :show_delay_options [String,Array<Integer>] A String of comma-separated Integers, or an Array of Integers.
392
- ### Enables the "Delay Options Mode". The window will display a dropdown with the values passed through the string
411
+ ### Enables the "Delay Options Mode". The window will display a dropdown with the values passed through the string
393
412
  ###
394
413
  ### @option opts :countdown [any value]
395
414
  ### Displays a string notifying the user when the window will time out
@@ -403,8 +422,7 @@ module JSS
403
422
  ### @return [Integer] the exit status of the jamfHelper command. See above.
404
423
  ###
405
424
  def self.jamf_helper(window_type = :hud, opts = {})
406
-
407
- raise JSS::UnmanagedError, "The jamfHelper app is not installed properly on this computer." unless JAMF_HELPER.executable?
425
+ raise JSS::UnmanagedError, 'The jamfHelper app is not installed properly on this computer.' unless JAMF_HELPER.executable?
408
426
 
409
427
  unless JAMF_HELPER_WINDOW_TYPES.include? window_type
410
428
  raise JSS::InvalidDataError, "The first parameter must be a window type, one of :#{JAMF_HELPER_WINDOW_TYPES.keys.join(', :')}."
@@ -412,93 +430,97 @@ module JSS
412
430
 
413
431
  # start building the arg array
414
432
 
415
- args = ["-startlaunchd", "-windowType", JAMF_HELPER_WINDOW_TYPES[window_type]]
433
+ args = ['-startlaunchd', '-windowType', JAMF_HELPER_WINDOW_TYPES[window_type]]
416
434
 
417
435
  opts.keys.each do |opt|
418
436
  case opt
419
- when :window_position
420
- raise JSS::InvalidDataError, ":window_position must be one of :#{JAMF_HELPER_WINDOW_POSITIONS.join(', :')}." unless JAMF_HELPER_WINDOW_POSITIONS.include? opts[opt].to_sym
421
- args << "-windowPosition"
422
- args << opts[opt].to_s
423
-
424
- when :title
425
- args << "-title"
426
- args << opts[opt].to_s
427
-
428
- when :heading
429
- args << "-heading"
430
- args << opts[opt].to_s
431
-
432
- when :align_heading
433
- raise JSS::InvalidDataError, ":align_heading must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
434
- args << "-alignHeading"
435
- args << opts[opt].to_s
436
-
437
- when :description
438
- args << "-description"
439
- args << opts[opt].to_s
440
-
441
- when :align_description
442
- raise JSS::InvalidDataError, ":align_description must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
443
- args << "-alignDescription"
444
- args << opts[opt].to_s
445
-
446
- when :icon
447
- args << "-icon"
448
- args << opts[opt].to_s
449
-
450
- when :icon_size
451
- args << "-iconSize"
452
- args << opts[opt].to_s
453
-
454
- when :full_screen_icon
455
- args << "-fullScreenIcon"
456
-
457
- when :button1
458
- args << "-button1"
459
- args << opts[opt].to_s
460
-
461
- when :button2
462
- args << "-button2"
463
- args << opts[opt].to_s
464
-
465
- when :default_button
466
- raise JSS::InvalidDataError, ":default_button must be one of #{JAMF_HELPER_BUTTONS.join(', ')}." unless JAMF_HELPER_BUTTONS.include? opts[opt]
467
- args << "-defaultButton"
468
- args << opts[opt].to_s
469
-
470
- when :cancel_button
471
- raise JSS::InvalidDataError, ":cancel_button must be one of #{JAMF_HELPER_BUTTONS.join(', ')}." unless JAMF_HELPER_BUTTONS.include? opts[opt]
472
- args << "-cancelButton"
473
- args << opts[opt].to_s
474
-
475
- when :timeout
476
- args << "-timeout"
477
- args << opts[opt].to_s
478
-
479
- when :show_delay_options
480
- args << "-showDelayOptions"
481
- args << JSS.to_s_and_a(opts[opt])[:arrayform].join(', ')
482
-
483
- when :countdown
484
- args << "-countdown"
485
-
486
- when :align_countdown
487
- raise JSS::InvalidDataError, ":align_countdown must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
488
- args << "-alignCountdown"
489
- args << opts[opt].to_s
490
-
491
- when :lock_hud
492
- args << "-lockHUD"
437
+ when :window_position
438
+ raise JSS::InvalidDataError, ":window_position must be one of :#{JAMF_HELPER_WINDOW_POSITIONS.join(', :')}." unless \
439
+ JAMF_HELPER_WINDOW_POSITIONS.include? opts[opt].to_sym
440
+ args << '-windowPosition'
441
+ args << opts[opt].to_s
442
+
443
+ when :title
444
+ args << '-title'
445
+ args << opts[opt].to_s
446
+
447
+ when :heading
448
+ args << '-heading'
449
+ args << opts[opt].to_s
450
+
451
+ when :align_heading
452
+ raise JSS::InvalidDataError, ":align_heading must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
453
+ JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
454
+ args << '-alignHeading'
455
+ args << opts[opt].to_s
456
+
457
+ when :description
458
+ args << '-description'
459
+ args << opts[opt].to_s
460
+
461
+ when :align_description
462
+ raise JSS::InvalidDataError, ":align_description must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
463
+ JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
464
+ args << '-alignDescription'
465
+ args << opts[opt].to_s
466
+
467
+ when :icon
468
+ args << '-icon'
469
+ args << opts[opt].to_s
470
+
471
+ when :icon_size
472
+ args << '-iconSize'
473
+ args << opts[opt].to_s
474
+
475
+ when :full_screen_icon
476
+ args << '-fullScreenIcon'
477
+
478
+ when :button1
479
+ args << '-button1'
480
+ args << opts[opt].to_s
481
+
482
+ when :button2
483
+ args << '-button2'
484
+ args << opts[opt].to_s
485
+
486
+ when :default_button
487
+ raise JSS::InvalidDataError, ":default_button must be one of #{JAMF_HELPER_BUTTONS.join(', ')}." unless \
488
+ JAMF_HELPER_BUTTONS.include? opts[opt]
489
+ args << '-defaultButton'
490
+ args << opts[opt].to_s
491
+
492
+ when :cancel_button
493
+ raise JSS::InvalidDataError, ":cancel_button must be one of #{JAMF_HELPER_BUTTONS.join(', ')}." unless \
494
+ JAMF_HELPER_BUTTONS.include? opts[opt]
495
+ args << '-cancelButton'
496
+ args << opts[opt].to_s
497
+
498
+ when :timeout
499
+ args << '-timeout'
500
+ args << opts[opt].to_s
501
+
502
+ when :show_delay_options
503
+ args << '-showDelayOptions'
504
+ args << JSS.to_s_and_a(opts[opt])[:arrayform].join(', ')
505
+
506
+ when :countdown
507
+ args << '-countdown'
508
+
509
+ when :align_countdown
510
+ raise JSS::InvalidDataError, ":align_countdown must be one of :#{JAMF_HELPER_ALIGNMENTS.join(', :')}." unless \
511
+ JAMF_HELPER_ALIGNMENTS.include? opts[opt].to_sym
512
+ args << '-alignCountdown'
513
+ args << opts[opt].to_s
514
+
515
+ when :lock_hud
516
+ args << '-lockHUD'
493
517
  end # case opt
494
518
  end # each do opt
495
519
 
496
520
  system JAMF_HELPER.to_s, *args
497
- return $?.exitstatus
498
-
521
+ $CHILD_STATUS.exitstatus
499
522
  end # def self.jamf_helper
500
523
 
501
-
502
524
  end # class Client
503
525
 
504
526
  end # module