ruby-jss 0.6.5 → 0.6.6

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.
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