ruby-jss 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-jss might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.yardopts +7 -0
- data/CHANGES.md +112 -0
- data/LICENSE.txt +174 -0
- data/README.md +426 -0
- data/THANKS.md +6 -0
- data/bin/cgrouper +485 -0
- data/bin/subnet-update +400 -0
- data/lib/jss-api.rb +2 -0
- data/lib/jss.rb +190 -0
- data/lib/jss/api_connection.rb +410 -0
- data/lib/jss/api_object.rb +616 -0
- data/lib/jss/api_object/advanced_search.rb +389 -0
- data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +95 -0
- data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
- data/lib/jss/api_object/advanced_search/advanced_user_search.rb +95 -0
- data/lib/jss/api_object/building.rb +92 -0
- data/lib/jss/api_object/category.rb +147 -0
- data/lib/jss/api_object/computer.rb +852 -0
- data/lib/jss/api_object/creatable.rb +98 -0
- data/lib/jss/api_object/criteriable.rb +189 -0
- data/lib/jss/api_object/criteriable/criteria.rb +231 -0
- data/lib/jss/api_object/criteriable/criterion.rb +228 -0
- data/lib/jss/api_object/department.rb +93 -0
- data/lib/jss/api_object/distribution_point.rb +560 -0
- data/lib/jss/api_object/extendable.rb +221 -0
- data/lib/jss/api_object/extension_attribute.rb +466 -0
- data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
- data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
- data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +117 -0
- data/lib/jss/api_object/group.rb +380 -0
- data/lib/jss/api_object/group/computer_group.rb +124 -0
- data/lib/jss/api_object/group/mobile_device_group.rb +139 -0
- data/lib/jss/api_object/group/user_group.rb +139 -0
- data/lib/jss/api_object/ldap_server.rb +535 -0
- data/lib/jss/api_object/locatable.rb +286 -0
- data/lib/jss/api_object/matchable.rb +97 -0
- data/lib/jss/api_object/mobile_device.rb +556 -0
- data/lib/jss/api_object/netboot_server.rb +148 -0
- data/lib/jss/api_object/network_segment.rb +414 -0
- data/lib/jss/api_object/osx_configuration_profile.rb +262 -0
- data/lib/jss/api_object/package.rb +839 -0
- data/lib/jss/api_object/peripheral.rb +335 -0
- data/lib/jss/api_object/peripheral_type.rb +295 -0
- data/lib/jss/api_object/policy.rb +898 -0
- data/lib/jss/api_object/purchasable.rb +316 -0
- data/lib/jss/api_object/removable_macaddr.rb +98 -0
- data/lib/jss/api_object/scopable.rb +136 -0
- data/lib/jss/api_object/scopable/scope.rb +621 -0
- data/lib/jss/api_object/script.rb +631 -0
- data/lib/jss/api_object/self_servable.rb +356 -0
- data/lib/jss/api_object/site.rb +93 -0
- data/lib/jss/api_object/software_update_server.rb +109 -0
- data/lib/jss/api_object/updatable.rb +117 -0
- data/lib/jss/api_object/uploadable.rb +138 -0
- data/lib/jss/api_object/user.rb +272 -0
- data/lib/jss/client.rb +504 -0
- data/lib/jss/compatibility.rb +66 -0
- data/lib/jss/composer.rb +185 -0
- data/lib/jss/configuration.rb +306 -0
- data/lib/jss/db_connection.rb +298 -0
- data/lib/jss/exceptions.rb +95 -0
- data/lib/jss/ruby_extensions.rb +35 -0
- data/lib/jss/ruby_extensions/filetest.rb +43 -0
- data/lib/jss/ruby_extensions/hash.rb +79 -0
- data/lib/jss/ruby_extensions/ipaddr.rb +91 -0
- data/lib/jss/ruby_extensions/pathname.rb +77 -0
- data/lib/jss/ruby_extensions/string.rb +59 -0
- data/lib/jss/ruby_extensions/time.rb +63 -0
- data/lib/jss/server.rb +108 -0
- data/lib/jss/utility.rb +478 -0
- data/lib/jss/version.rb +31 -0
- metadata +187 -0
data/lib/jss/client.rb
ADDED
@@ -0,0 +1,504 @@
|
|
1
|
+
### Copyright 2016 Pixar
|
2
|
+
###
|
3
|
+
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
4
|
+
### with the following modification; you may not use this file except in
|
5
|
+
### compliance with the Apache License and the following modification to it:
|
6
|
+
### Section 6. Trademarks. is deleted and replaced with:
|
7
|
+
###
|
8
|
+
### 6. Trademarks. This License does not grant permission to use the trade
|
9
|
+
### names, trademarks, service marks, or product names of the Licensor
|
10
|
+
### and its affiliates, except as required to comply with Section 4(c) of
|
11
|
+
### the License and to reproduce the content of the NOTICE file.
|
12
|
+
###
|
13
|
+
### You may obtain a copy of the Apache License at
|
14
|
+
###
|
15
|
+
### http://www.apache.org/licenses/LICENSE-2.0
|
16
|
+
###
|
17
|
+
### Unless required by applicable law or agreed to in writing, software
|
18
|
+
### distributed under the Apache License with the above modification is
|
19
|
+
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
20
|
+
### KIND, either express or implied. See the Apache License for the specific
|
21
|
+
### language governing permissions and limitations under the Apache License.
|
22
|
+
###
|
23
|
+
###
|
24
|
+
|
25
|
+
###
|
26
|
+
module JSS
|
27
|
+
|
28
|
+
#####################################
|
29
|
+
### Module Variables
|
30
|
+
#####################################
|
31
|
+
|
32
|
+
#####################################
|
33
|
+
### Module Methods
|
34
|
+
#####################################
|
35
|
+
|
36
|
+
#####################################
|
37
|
+
### Classes
|
38
|
+
#####################################
|
39
|
+
|
40
|
+
###
|
41
|
+
### This class represents a Casper/JSS Client computer, on which
|
42
|
+
### this code is running.
|
43
|
+
###
|
44
|
+
### Since the class represents the current machine, there's no need
|
45
|
+
### to make an instance of it, all methods are class methods.
|
46
|
+
###
|
47
|
+
### At the moment, only Macintosh computers are supported.
|
48
|
+
###
|
49
|
+
###
|
50
|
+
class Client
|
51
|
+
|
52
|
+
#####################################
|
53
|
+
### Class Constants
|
54
|
+
#####################################
|
55
|
+
|
56
|
+
### The Pathname to the jamf binary executable
|
57
|
+
### 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"
|
60
|
+
JAMF_BINARY = ELCAP_JAMF_BINARY.executable? ? ELCAP_JAMF_BINARY : ORIG_JAMF_BINARY
|
61
|
+
|
62
|
+
### The Pathname to the jamfHelper executable
|
63
|
+
JAMF_HELPER = Pathname.new "/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
|
64
|
+
|
65
|
+
### The window_type options for jamfHelper
|
66
|
+
JAMF_HELPER_WINDOW_TYPES = {
|
67
|
+
:hud => 'hud',
|
68
|
+
:utility => 'utility',
|
69
|
+
:util => 'utility',
|
70
|
+
:full_screen => 'fs',
|
71
|
+
:fs => 'fs'
|
72
|
+
}
|
73
|
+
|
74
|
+
### The possible window positions for jamfHelper
|
75
|
+
JAMF_HELPER_WINDOW_POSITIONS = [nil, :ul, :ll, :ur, :lr]
|
76
|
+
|
77
|
+
### The available buttons in jamfHelper
|
78
|
+
JAMF_HELPER_BUTTONS = [1,2]
|
79
|
+
|
80
|
+
### The possible alignment positions in jamfHelper
|
81
|
+
JAMF_HELPER_ALIGNMENTS = [:right, :left, :center, :justified, :natural]
|
82
|
+
|
83
|
+
### The Pathname to the preferences plist used by the jamf binary
|
84
|
+
JAMF_PLIST = Pathname.new "/Library/Preferences/com.jamfsoftware.jamf.plist"
|
85
|
+
|
86
|
+
### The Pathname to the JAMF support folder
|
87
|
+
JAMF_SUPPORT_FOLDER = Pathname.new "/Library/Application Support/JAMF"
|
88
|
+
|
89
|
+
### The JAMF receipts folder, where package installs are tracked.
|
90
|
+
RECEIPTS_FOLDER = JAMF_SUPPORT_FOLDER + "Receipts"
|
91
|
+
|
92
|
+
### The JAMF downloads folder
|
93
|
+
DOWNLOADS_FOLDER = JAMF_SUPPORT_FOLDER + "Downloads"
|
94
|
+
|
95
|
+
### These jamf commands don't need root privs (most do)
|
96
|
+
ROOTLESS_JAMF_COMMANDS = [
|
97
|
+
:about,
|
98
|
+
:checkJSSConnection,
|
99
|
+
:getARDFields,
|
100
|
+
:getComputerName,
|
101
|
+
:help,
|
102
|
+
:listUsers,
|
103
|
+
:version ]
|
104
|
+
|
105
|
+
#####################################
|
106
|
+
### Class Variables
|
107
|
+
#####################################
|
108
|
+
|
109
|
+
#####################################
|
110
|
+
### Class Methods
|
111
|
+
#####################################
|
112
|
+
|
113
|
+
###
|
114
|
+
### Get the current IP address as a String.
|
115
|
+
###
|
116
|
+
### This handy code doesn't acutally make a UDP connection,
|
117
|
+
### it just starts to set up the connection, then uses that to get
|
118
|
+
### the local IP.
|
119
|
+
###
|
120
|
+
### Lifted gratefully from
|
121
|
+
### http://coderrr.wordpress.com/2008/05/28/get-your-local-ip-address/
|
122
|
+
###
|
123
|
+
### @return [String] the current IP address.
|
124
|
+
###
|
125
|
+
def self.my_ip_address
|
126
|
+
### turn off reverse DNS resolution temporarily
|
127
|
+
### @note the 'socket' library has already been required by 'rest-client'
|
128
|
+
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
|
129
|
+
|
130
|
+
UDPSocket.open do |s|
|
131
|
+
s.connect '192.168.0.0', 1
|
132
|
+
s.addr.last
|
133
|
+
end
|
134
|
+
ensure
|
135
|
+
Socket.do_not_reverse_lookup = orig
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
###
|
141
|
+
### @return [Boolean] is the jamf binary installed?
|
142
|
+
###
|
143
|
+
def self.installed?
|
144
|
+
JAMF_BINARY.executable?
|
145
|
+
end
|
146
|
+
|
147
|
+
###
|
148
|
+
### @return [String,nil] the version of the jamf binary installed on this client, nil if not installed
|
149
|
+
###
|
150
|
+
def self.jamf_version
|
151
|
+
self.installed? ? self.run_jamf(:version).chomp.split('=')[1] : nil
|
152
|
+
end
|
153
|
+
|
154
|
+
###
|
155
|
+
### @return [String] the url to the JSS for this client
|
156
|
+
###
|
157
|
+
def self.jss_url
|
158
|
+
@url = self.jamf_plist['jss_url']
|
159
|
+
return nil if @url.nil?
|
160
|
+
@url =~ %r{(https?)://(.+):(\d+)/}
|
161
|
+
@protocol = $1
|
162
|
+
@server = $2
|
163
|
+
@port = $3
|
164
|
+
return @url
|
165
|
+
end
|
166
|
+
|
167
|
+
###
|
168
|
+
### @return [String] the JSS server for this client
|
169
|
+
###
|
170
|
+
def self.jss_server
|
171
|
+
self.jss_url
|
172
|
+
return @server
|
173
|
+
end
|
174
|
+
|
175
|
+
###
|
176
|
+
### @return [String] the protocol to the JSS for this client, "http" or "https"
|
177
|
+
###
|
178
|
+
def self.jss_protocol
|
179
|
+
self.jss_url
|
180
|
+
return @protocol
|
181
|
+
end
|
182
|
+
|
183
|
+
###
|
184
|
+
### @return [Integer] the port to the JSS for this client
|
185
|
+
###
|
186
|
+
def self.jss_port
|
187
|
+
self.jss_url
|
188
|
+
@port ? @port.to_i : 80
|
189
|
+
end
|
190
|
+
|
191
|
+
###
|
192
|
+
### @return [Hash] the parsed contents of the JAMF_PLIST if it exists, an empty hash if not
|
193
|
+
###
|
194
|
+
def self.jamf_plist
|
195
|
+
return {} unless JAMF_PLIST.file?
|
196
|
+
Plist.parse_xml `/usr/libexec/PlistBuddy -x -c print #{Shellwords.escape JSS::Client::JAMF_PLIST.to_s}`
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
###
|
201
|
+
### @return [Array<Pathname>] an array of Pathnames for all regular files in the jamf receipts folder
|
202
|
+
###
|
203
|
+
def self.receipts
|
204
|
+
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?}
|
206
|
+
end
|
207
|
+
|
208
|
+
###
|
209
|
+
### @return [Boolean] is the JSS available now?
|
210
|
+
###
|
211
|
+
def self.jss_available?
|
212
|
+
output = run_jamf :checkJSSConnection, "-retry 1"
|
213
|
+
$?.exitstatus == 0
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
###
|
218
|
+
### @return [JSS::Computer] The JSS record for this computer
|
219
|
+
###
|
220
|
+
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
|
226
|
+
end
|
227
|
+
|
228
|
+
###
|
229
|
+
### @return [String] the UUID/UDID for this computer
|
230
|
+
###
|
231
|
+
def self.udid
|
232
|
+
self.hardware_data["platform_UUID"]
|
233
|
+
end
|
234
|
+
|
235
|
+
###
|
236
|
+
### @return [String] the serial number for this computer
|
237
|
+
###
|
238
|
+
def self.serial_number
|
239
|
+
self.hardware_data["serial_number"]
|
240
|
+
end
|
241
|
+
|
242
|
+
###
|
243
|
+
### @return [Hash] the HardwareDataType data from the system_profiler command
|
244
|
+
###
|
245
|
+
def self.hardware_data
|
246
|
+
raw = `/usr/sbin/system_profiler SPHardwareDataType -xml 2>/dev/null`
|
247
|
+
Plist.parse_xml(raw)[0]["_items"][0]
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
### Run an arbitrary jamf binary command.
|
252
|
+
###
|
253
|
+
### @note Most jamf commands require superuser/root privileges.
|
254
|
+
###
|
255
|
+
### @param command[String,Symbol] the jamf binary command to run
|
256
|
+
### The command is the single jamf command that comes after the/usr/bin/jamf.
|
257
|
+
###
|
258
|
+
### @param args[String,Array] the arguments passed to the jamf command.
|
259
|
+
### This is to be passed to Kernel.` (backtick), after being combined with the
|
260
|
+
### jamf binary and the jamf command
|
261
|
+
###
|
262
|
+
### @param verbose[Boolean] Should the stdout & stderr of the jamf binary be sent to
|
263
|
+
### the current stdout in realtime, as well as returned as a string?
|
264
|
+
###
|
265
|
+
### @return [String] the stdout & stderr of the jamf binary.
|
266
|
+
###
|
267
|
+
### @example
|
268
|
+
### These two are equivalent:
|
269
|
+
###
|
270
|
+
### JSS::Client.run_jamf "recon", "-assetTag 12345 -department 'IT Support'"
|
271
|
+
###
|
272
|
+
### JSS::Client.run_jamf :recon, ['-assetTag', '12345', '-department', 'IT Support'"]
|
273
|
+
###
|
274
|
+
###
|
275
|
+
### The details of the Process::Status for the jamf binary process can be captured from $?
|
276
|
+
### immediately after calling. (See Process::Status)
|
277
|
+
###
|
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?
|
281
|
+
|
282
|
+
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")
|
294
|
+
puts "Running: #{cmd}" if verbose
|
295
|
+
|
296
|
+
output = []
|
297
|
+
IO.popen("#{cmd} 2>&1") do |proc|
|
298
|
+
while line = proc.gets
|
299
|
+
output << line
|
300
|
+
puts line if verbose
|
301
|
+
end
|
302
|
+
end
|
303
|
+
install_out = output.join('')
|
304
|
+
install_out.force_encoding("UTF-8") if install_out.respond_to? :force_encoding
|
305
|
+
return install_out
|
306
|
+
end # run_jamf
|
307
|
+
|
308
|
+
|
309
|
+
### A wrapper for the jamfHelper command, which can display a window on the client machine.
|
310
|
+
###
|
311
|
+
### The first parameter must be a symbol defining what kind of window to display. The options are
|
312
|
+
### - :hud - creates an Apple "Heads Up Display" style window
|
313
|
+
### - :utility or :util - creates an Apple "Utility" style window
|
314
|
+
### - :fs or :full_screen or :fullscreen - creates a full screen window that restricts all user input
|
315
|
+
### WARNING: Remote access must be used to unlock machines in this mode
|
316
|
+
###
|
317
|
+
### The remaining options Hash can contain any of the options listed. See below for descriptions.
|
318
|
+
###
|
319
|
+
### The value returned is the Integer exitstatus/stdout (both are the same) of the jamfHelper command.
|
320
|
+
### The meanings of those integers are:
|
321
|
+
###
|
322
|
+
### - 0 - Button 1 was clicked
|
323
|
+
### - 1 - The Jamf Helper was unable to launch
|
324
|
+
### - 2 - Button 2 was clicked
|
325
|
+
### - 3 - Process was started as a launchd task
|
326
|
+
### - XX1 - Button 1 was clicked with a value of XX seconds selected in the drop-down
|
327
|
+
### - XX2 - Button 2 was clicked with a value of XX seconds selected in the drop-down
|
328
|
+
### - 239 - The exit button was clicked
|
329
|
+
### - 240 - The "ProductVersion" in sw_vers did not return 10.5.X, 10.6.X or 10.7.X
|
330
|
+
### - 243 - The window timed-out with no buttons on the screen
|
331
|
+
### - 250 - Bad "-windowType"
|
332
|
+
### - 254 - Cancel button was select with delay option present
|
333
|
+
### - 255 - No "-windowType"
|
334
|
+
###
|
335
|
+
### See also /Library/Application\ Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper -help
|
336
|
+
###
|
337
|
+
### @note the -startlaunchd and -kill options are not available in this implementation, since
|
338
|
+
### they don't work at the moment (casper 9.4).
|
339
|
+
### -startlaunchd seems to be required to NOT use launchd, and when it's ommited, an error is generated
|
340
|
+
### about the launchd plist permissions being incorrect.
|
341
|
+
###
|
342
|
+
### @param window_type[Symbol] The type of window to display
|
343
|
+
###
|
344
|
+
### @param opts[Hash] the options for the window
|
345
|
+
###
|
346
|
+
### @option opts :window_position [Symbol,nil] one of [ nil, :ul, :ll. :ur, :lr ]
|
347
|
+
### 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
|
349
|
+
###
|
350
|
+
### @option opts :title [String]
|
351
|
+
### Sets the window's title to the specified string
|
352
|
+
###
|
353
|
+
### @option opts :heading [String]
|
354
|
+
### Sets the heading of the window to the specified string
|
355
|
+
###
|
356
|
+
### @option opts :align_heading [Symbol] one of [:right, :left, :center, :justified, :natural]
|
357
|
+
### Aligns the heading to the specified alignment
|
358
|
+
###
|
359
|
+
### @option opts :description [String]
|
360
|
+
### Sets the main contents of the window to the specified string
|
361
|
+
###
|
362
|
+
### @option opts :align_description [Symbol] one of [:right, :left, :center, :justified, :natural]
|
363
|
+
### Aligns the description to the specified alignment
|
364
|
+
###
|
365
|
+
### @option opts :icon [String,Pathname]
|
366
|
+
### Sets the windows image field to the image located at the specified path
|
367
|
+
###
|
368
|
+
### @option opts :icon_size [Integer]
|
369
|
+
### Changes the image frame to the specified pixel size
|
370
|
+
###
|
371
|
+
### @option opts :full_screen_icon [any value]
|
372
|
+
### Scales the "icon" to the full size of the window.
|
373
|
+
### Note: Only available in full screen mode
|
374
|
+
###
|
375
|
+
### @option opts :button1 [String]
|
376
|
+
### Creates a button with the specified label
|
377
|
+
###
|
378
|
+
### @option opts :button2 [String]
|
379
|
+
### Creates a second button with the specified label
|
380
|
+
###
|
381
|
+
### @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"
|
383
|
+
###
|
384
|
+
### @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"
|
386
|
+
###
|
387
|
+
### @option opts :timeout [Integer]
|
388
|
+
### 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)
|
390
|
+
###
|
391
|
+
### @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
|
393
|
+
###
|
394
|
+
### @option opts :countdown [any value]
|
395
|
+
### Displays a string notifying the user when the window will time out
|
396
|
+
###
|
397
|
+
### @option opts :align_countdown [Symbol] one of [:right, :left, :center, :justified, :natural]
|
398
|
+
### Aligns the countdown to the specified alignment
|
399
|
+
###
|
400
|
+
### @option opts :lock_hud [any value]
|
401
|
+
### Removes the ability to exit the HUD by selecting the close button
|
402
|
+
###
|
403
|
+
### @return [Integer] the exit status of the jamfHelper command. See above.
|
404
|
+
###
|
405
|
+
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?
|
408
|
+
|
409
|
+
unless JAMF_HELPER_WINDOW_TYPES.include? window_type
|
410
|
+
raise JSS::InvalidDataError, "The first parameter must be a window type, one of :#{JAMF_HELPER_WINDOW_TYPES.keys.join(', :')}."
|
411
|
+
end
|
412
|
+
|
413
|
+
# start building the arg array
|
414
|
+
|
415
|
+
args = ["-startlaunchd", "-windowType", JAMF_HELPER_WINDOW_TYPES[window_type]]
|
416
|
+
|
417
|
+
opts.keys.each do |opt|
|
418
|
+
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 "
|
493
|
+
end # case opt
|
494
|
+
end # each do opt
|
495
|
+
|
496
|
+
system JAMF_HELPER.to_s, *args
|
497
|
+
return $?.exitstatus
|
498
|
+
|
499
|
+
end # def self.jamf_helper
|
500
|
+
|
501
|
+
|
502
|
+
end # class Client
|
503
|
+
|
504
|
+
end # module
|