ruby-jss 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +7 -0
  3. data/CHANGES.md +112 -0
  4. data/LICENSE.txt +174 -0
  5. data/README.md +426 -0
  6. data/THANKS.md +6 -0
  7. data/bin/cgrouper +485 -0
  8. data/bin/subnet-update +400 -0
  9. data/lib/jss-api.rb +2 -0
  10. data/lib/jss.rb +190 -0
  11. data/lib/jss/api_connection.rb +410 -0
  12. data/lib/jss/api_object.rb +616 -0
  13. data/lib/jss/api_object/advanced_search.rb +389 -0
  14. data/lib/jss/api_object/advanced_search/advanced_computer_search.rb +95 -0
  15. data/lib/jss/api_object/advanced_search/advanced_mobile_device_search.rb +96 -0
  16. data/lib/jss/api_object/advanced_search/advanced_user_search.rb +95 -0
  17. data/lib/jss/api_object/building.rb +92 -0
  18. data/lib/jss/api_object/category.rb +147 -0
  19. data/lib/jss/api_object/computer.rb +852 -0
  20. data/lib/jss/api_object/creatable.rb +98 -0
  21. data/lib/jss/api_object/criteriable.rb +189 -0
  22. data/lib/jss/api_object/criteriable/criteria.rb +231 -0
  23. data/lib/jss/api_object/criteriable/criterion.rb +228 -0
  24. data/lib/jss/api_object/department.rb +93 -0
  25. data/lib/jss/api_object/distribution_point.rb +560 -0
  26. data/lib/jss/api_object/extendable.rb +221 -0
  27. data/lib/jss/api_object/extension_attribute.rb +466 -0
  28. data/lib/jss/api_object/extension_attribute/computer_extension_attribute.rb +362 -0
  29. data/lib/jss/api_object/extension_attribute/mobile_device_extension_attribute.rb +189 -0
  30. data/lib/jss/api_object/extension_attribute/user_extension_attribute.rb +117 -0
  31. data/lib/jss/api_object/group.rb +380 -0
  32. data/lib/jss/api_object/group/computer_group.rb +124 -0
  33. data/lib/jss/api_object/group/mobile_device_group.rb +139 -0
  34. data/lib/jss/api_object/group/user_group.rb +139 -0
  35. data/lib/jss/api_object/ldap_server.rb +535 -0
  36. data/lib/jss/api_object/locatable.rb +286 -0
  37. data/lib/jss/api_object/matchable.rb +97 -0
  38. data/lib/jss/api_object/mobile_device.rb +556 -0
  39. data/lib/jss/api_object/netboot_server.rb +148 -0
  40. data/lib/jss/api_object/network_segment.rb +414 -0
  41. data/lib/jss/api_object/osx_configuration_profile.rb +262 -0
  42. data/lib/jss/api_object/package.rb +839 -0
  43. data/lib/jss/api_object/peripheral.rb +335 -0
  44. data/lib/jss/api_object/peripheral_type.rb +295 -0
  45. data/lib/jss/api_object/policy.rb +898 -0
  46. data/lib/jss/api_object/purchasable.rb +316 -0
  47. data/lib/jss/api_object/removable_macaddr.rb +98 -0
  48. data/lib/jss/api_object/scopable.rb +136 -0
  49. data/lib/jss/api_object/scopable/scope.rb +621 -0
  50. data/lib/jss/api_object/script.rb +631 -0
  51. data/lib/jss/api_object/self_servable.rb +356 -0
  52. data/lib/jss/api_object/site.rb +93 -0
  53. data/lib/jss/api_object/software_update_server.rb +109 -0
  54. data/lib/jss/api_object/updatable.rb +117 -0
  55. data/lib/jss/api_object/uploadable.rb +138 -0
  56. data/lib/jss/api_object/user.rb +272 -0
  57. data/lib/jss/client.rb +504 -0
  58. data/lib/jss/compatibility.rb +66 -0
  59. data/lib/jss/composer.rb +185 -0
  60. data/lib/jss/configuration.rb +306 -0
  61. data/lib/jss/db_connection.rb +298 -0
  62. data/lib/jss/exceptions.rb +95 -0
  63. data/lib/jss/ruby_extensions.rb +35 -0
  64. data/lib/jss/ruby_extensions/filetest.rb +43 -0
  65. data/lib/jss/ruby_extensions/hash.rb +79 -0
  66. data/lib/jss/ruby_extensions/ipaddr.rb +91 -0
  67. data/lib/jss/ruby_extensions/pathname.rb +77 -0
  68. data/lib/jss/ruby_extensions/string.rb +59 -0
  69. data/lib/jss/ruby_extensions/time.rb +63 -0
  70. data/lib/jss/server.rb +108 -0
  71. data/lib/jss/utility.rb +478 -0
  72. data/lib/jss/version.rb +31 -0
  73. metadata +187 -0
@@ -0,0 +1,631 @@
1
+ ### Copyright 2016 Pixar
2
+ ###
3
+ ### Licensed under the Apache License, Version 2.0 (the "Apache License")
4
+ ### with the following modification; you may not use this file except in
5
+ ### compliance with the Apache License and the following modification to it:
6
+ ### Section 6. Trademarks. is deleted and replaced with:
7
+ ###
8
+ ### 6. Trademarks. This License does not grant permission to use the trade
9
+ ### names, trademarks, service marks, or product names of the Licensor
10
+ ### and its affiliates, except as required to comply with Section 4(c) of
11
+ ### the License and to reproduce the content of the NOTICE file.
12
+ ###
13
+ ### You may obtain a copy of the Apache License at
14
+ ###
15
+ ### http://www.apache.org/licenses/LICENSE-2.0
16
+ ###
17
+ ### Unless required by applicable law or agreed to in writing, software
18
+ ### distributed under the Apache License with the above modification is
19
+ ### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
+ ### KIND, either express or implied. See the Apache License for the specific
21
+ ### language governing permissions and limitations under the Apache License.
22
+ ###
23
+ ###
24
+
25
+ ###
26
+ module JSS
27
+
28
+ #####################################
29
+ ### Module Constants
30
+ #####################################
31
+
32
+ #####################################
33
+ ### Module Variables
34
+ #####################################
35
+
36
+ #####################################
37
+ ### Module Methods
38
+ #####################################
39
+
40
+ #####################################
41
+ ### Classes
42
+ #####################################
43
+
44
+ ###
45
+ ### A Script in the JSS.
46
+ ###
47
+ ### As of Casper 9.4, the script contents as stored in the database are
48
+ ### accessible via the API
49
+ ###
50
+ ### This class will save the script contents back to the database with
51
+ ### the {#create} or {#update} methods
52
+ ###
53
+ ### If your scripts are stored on the master distribution point instead of
54
+ ### the database, you can use {#upload_master_file} to save it to the server,
55
+ ### and {#delete_master_file} to delete it from the server.
56
+ ###
57
+ ### Use the {#run} method to run the script on the local machine via the 'jamf runScript' command
58
+ ###
59
+ ### @see JSS::APIObject
60
+ ###
61
+ class Script < JSS::APIObject
62
+
63
+ #####################################
64
+ ### Mix-Ins
65
+ #####################################
66
+
67
+ include JSS::Creatable
68
+ include JSS::Updatable
69
+
70
+ #####################################
71
+ ### Class Methods
72
+ #####################################
73
+
74
+ #####################################
75
+ ### Class Constants
76
+ #####################################
77
+
78
+ ### The base for REST resources of this class
79
+ RSRC_BASE = "scripts"
80
+
81
+ ### the hash key used for the JSON list output of all objects in the JSS
82
+ RSRC_LIST_KEY = :scripts
83
+
84
+ ### The hash key used for the JSON object output.
85
+ ### It's also used in various error messages
86
+ RSRC_OBJECT_KEY = :script
87
+
88
+ ### these keys, as well as :id and :name, are present in valid API JSON data for this class
89
+ VALID_DATA_KEYS = [:parameters, :filename, :os_requirements ]
90
+
91
+ ### The script storage folder on the distribution point, if used
92
+ DIST_POINT_SCRIPTS_FOLDER = "Scripts"
93
+
94
+ ### Priority to use for running the script in relation to other actions during imaging
95
+ PRIORITIES = [ 'Before', 'After','At Reboot']
96
+
97
+ ### which is default?
98
+ DEFAULT_PRIORITY = "After"
99
+
100
+ ### The keys used in the @parameters Hash
101
+ PARAMETER_KEYS = [:parameter4, :parameter5, :parameter6,:parameter7, :parameter8, :parameter9, :parameter10, :parameter11]
102
+
103
+ #####################################
104
+ ### Attributes
105
+ #####################################
106
+
107
+ ### @return [String] the file name of the script, if stored in a dist. point
108
+ attr_reader :filename
109
+
110
+ ### @return [Array<String>] the OS versions this can be installed onto. For all minor versions, the format is 10.5.x
111
+ attr_reader :os_requirements
112
+
113
+ ### @return [String] either 'Before' or 'After' or "At Reboot".
114
+ attr_reader :priority
115
+
116
+ ### @return [String] the info field for this script
117
+ attr_reader :info
118
+
119
+ ### @return [String] the notes field for this script
120
+ attr_reader :notes
121
+
122
+ ### @return [String] the category of this script, stored in the JSS as the id number from the categories table
123
+ attr_reader :category
124
+
125
+ ### @return [Hash] script parameters 4-11. Parameters 1-3 are predefined as target drive, computer name, and username
126
+ attr_reader :parameters
127
+
128
+ ### @return {String] the actual code for this script, if it's stored in the database.
129
+ attr_reader :script_contents
130
+
131
+
132
+ #####################################
133
+ ### Constructor
134
+ #####################################
135
+
136
+ ###
137
+ ###
138
+ ###
139
+ def initialize (args = {})
140
+ super
141
+
142
+ @category = JSS::APIObject.get_name(@init_data[:category])
143
+ @filename = @init_data[:filename] || @name
144
+ @info = @init_data[:info]
145
+ @notes = @init_data[:notes]
146
+ @os_requirements = @init_data[:os_requirements] ? JSS.to_s_and_a(@init_data[:os_requirements] )[:arrayform] : []
147
+ @parameters = @init_data[:parameters] ? @init_data[:parameters] : {}
148
+ @priority = @init_data[:priority] || DEFAULT_PRIORITY
149
+ @script_contents = @init_data[:script_contents]
150
+
151
+ end # initialize
152
+
153
+ ###
154
+ ### Change the script filename
155
+ ###
156
+ ### Setting it to nil will make it match the script name
157
+ ###
158
+ ### @param new_val[String,Nil] the new filename
159
+ ###
160
+ ### @return [void]
161
+ ###
162
+ ### @note This method does NOT change the filename on the distribution point
163
+ ### if that's where you store your scripts.
164
+ ###
165
+ def filename= (new_val)
166
+
167
+ new_val = nil if new_val == ''
168
+ new_val = @name unless new_val
169
+
170
+ return nil if new_val == @filename
171
+
172
+ @filename = new_val
173
+ @need_to_update = true
174
+ end #filename=
175
+
176
+ ###
177
+ ### Change the script's display name
178
+ ###
179
+ ### If the filename is the same as the name, the filename will be changed also
180
+ ###
181
+ ### @param new_val[String] the new display name
182
+ ###
183
+ ### @return [void]
184
+ ###
185
+ def name= (new_val)
186
+ return nil if new_val == @name
187
+ new_val = nil if new_val == ''
188
+ raise JSS::MissingDataError, "Name can't be empty" unless new_val
189
+ raise JSS::AlreadyExistsError, "A #{RSRC_OBJECT_KEY} already exists with the name '#{args[:name]}'" if JSS.send(LIST_METHOD).values.include?
190
+
191
+ ### if the filename is the same, keep it the same
192
+ @filename = new_val if @filename == @name
193
+ @name = new_val
194
+
195
+ ### if our REST resource is based on the name, update that too
196
+ @rest_rsrc = "#{RSRC_BASE}/name/#{URI.escape @name}" if @rest_rsrc.include? '/name/'
197
+ @need_to_update = true
198
+ end #name=
199
+
200
+ ###
201
+ ### Change the os_requirements
202
+ ###
203
+ ### Minumum OS's can be specified as a string using the notation ">=10.6.7"
204
+ ### See the {JSS.expand_min_os} method for details.
205
+ ###
206
+ ### @param new_val[String, Array<String>] the new os requirements as a comma-separted String or an Array of Strings
207
+ ###
208
+ ### @return [void]
209
+ ###
210
+ ### @example String value
211
+ ### myscript.os_requirements "10.5, 10.5.3, 10.6.x"
212
+ ###
213
+ ### @example Array value
214
+ ### ok_oses = ['10.5', '10.5.3', '10.6.x']
215
+ ### myscript.os_requirements ok_oses
216
+ ###
217
+ ### @example Minimum OS
218
+ ### myscript.os_requirements ">=10.7.5"
219
+ ###
220
+ def os_requirements= (new_val)
221
+ ### nil should be an empty array
222
+ new_val = [] if new_val.to_s.empty?
223
+
224
+ ### if any value starts with >=, expand it
225
+ case new_val
226
+ when String
227
+ new_val = JSS.expand_min_os(new_val) if new_val =~ /^>=/
228
+ when Array
229
+ new_val.map!{|a| a =~ /^>=/ ? JSS.expand_min_os(a) : a }
230
+ new_val.flatten!
231
+ new_val.uniq!
232
+ else
233
+ raise JSS::InvalidDataError, "os_requirements must be a String or an Array of strings"
234
+ end # case
235
+
236
+ ### get the array version
237
+ @os_requirements = JSS.to_s_and_a(new_val)[:arrayform]
238
+ @need_to_update = true
239
+
240
+ end #os_requirements=
241
+
242
+ ###
243
+ ### Change the priority of this script
244
+ ###
245
+ ### @param new_val[Integer] the new priority, which must be one of {PRIORITIES}
246
+ ###
247
+ ### @return [void]
248
+ ###
249
+ def priority= (new_val)
250
+ return nil if new_val == @priority
251
+ new_val = DEFAULT_PRIORITY if new_val.nil? or new_val == ""
252
+ raise JSS::InvalidDataError, ":priority must be one of: #{PRIORITIES.join ', '}" unless PRIORITIES.include? new_val
253
+ @priority = new_val
254
+ @need_to_update = true
255
+ end #priority=
256
+
257
+ ###
258
+ ### Change the info field
259
+ ###
260
+ ### @param new_val[String] the new info
261
+ ###
262
+ ### @return [void]
263
+ ###
264
+ def info= (new_val)
265
+ return nil if new_val == @info
266
+ ### line breaks should be \r
267
+ new_val = new_val.to_s.gsub(/\n/, "\r")
268
+ @info = new_val
269
+ @need_to_update = true
270
+ end #info=
271
+
272
+ ###
273
+ ### Change the notes field
274
+ ###
275
+ ### @param new_val[String] the new notes
276
+ ###
277
+ ### @return [void]
278
+ ###
279
+ def notes= (new_val)
280
+ return nil if new_val == @notes
281
+ ### line breaks should be \r
282
+ new_val = new_val.to_s.gsub(/\n/, "\r")
283
+ @notes = new_val
284
+ @need_to_update = true
285
+ end #notes=
286
+
287
+ ###
288
+ ### Change the category
289
+ ###
290
+ ### @param new_val[String] the name of the new category, which must be in {JSS::Category.all_names}
291
+ ###
292
+ ### @return [void]
293
+ ###
294
+ def category= (new_val)
295
+ return nil if new_val == @category
296
+ new_val = nil if new_val == ''
297
+ new_val ||= JSS::Category::DEFAULT_CATEGORY
298
+ raise JSS::InvalidDataError, "Category #{new_val} is not known to the JSS" unless JSS::Category.all_names.include? new_val
299
+ @need_to_update = true
300
+ @category = new_val
301
+ end #category=
302
+
303
+ ###
304
+ ### Replace all the script parameters at once.
305
+ ###
306
+ ### This will replace the entire set with the hash provided.
307
+ ###
308
+ ### @param new_val[Hash] the Hash keys must exist in {PARAMETER_KEYS}
309
+ ###
310
+ ### @return [void]
311
+ ###
312
+ def parameters= (new_val)
313
+ return nil if new_val == @parameters
314
+ new_val = {} if new_val.nil? or new_val== ''
315
+
316
+ ### check the values
317
+ raise JSS::InvalidDataError, ":parameters must be a Hash with keys :parameter4 thru :parameter11" unless new_val.kind_of? Hash and (new_val.keys & PARAMETER_KEYS) == new_val.keys
318
+ new_val.each do |k,v|
319
+ raise JSS::InvalidDataError, ":parameter values must be strings or nil" unless v.nil? or v.kind_of? String
320
+ end
321
+
322
+ @parameters = new_val
323
+ @need_to_update = true
324
+ end # parameters=
325
+
326
+ ###
327
+ ### Change one of the stored parameters
328
+ ###
329
+ ### @param param_num[Integer] which param are we setting? must be 4..11
330
+ ###
331
+ ### @param new_val[String] the new value for the parameter
332
+ ###
333
+ ### @return [void]
334
+ ###
335
+ def set_parameter (param_num, new_val)
336
+ raise JSS::NoSuchItemError, "Parameter numbers must be from 4-11" unless (4..11).include? param_num
337
+ pkey = "parameter#{param_num}".to_sym
338
+ raise JSS::InvalidDataError, "parameter values must be strings or nil" unless new_val.nil? or new_val.kind_of? String
339
+ return nil if new_val == @parameters[pkey]
340
+ @parameters[pkey] = new_val
341
+ @need_to_update = true
342
+ end
343
+
344
+ ###
345
+ ### Change the executable code of this script.
346
+ ###
347
+ ### If the arg is a Pathname instance, or a String starting with "/"
348
+ ### Then the arg is assumed to be a file from which to read the code.
349
+ ###
350
+ ### Otherwise it should be a String with the code itself, and it must start with '#!"
351
+ ###
352
+ ### After doing this, use {#create} or {#update} to write it to the database or
353
+ ### use {#upload_master_file} to save it to the master dist. point.
354
+ ###
355
+ ### @param new_val[String,Pathname] the new script contents or a path to a file containing it.
356
+ ###
357
+ ### @return [void]
358
+ ###
359
+ def script_contents= (new_val)
360
+
361
+ new_code = case new_val
362
+ when String
363
+ if new_val.start_with? '/'
364
+ Pathname.new(new_val).read
365
+ else
366
+ new_val
367
+ end #if
368
+ when Pathname
369
+ new_val.read
370
+ else
371
+ raise JSS::InvalidDataError, "New code must be a String (path or code) or Pathname instance"
372
+ end # case
373
+
374
+ raise JSS::InvalidDataError, "Script contents must start with '#!'" unless new_code.start_with? '#!'
375
+
376
+ @script_contents = new_code
377
+ @need_to_update = true
378
+ end
379
+
380
+ ###
381
+ ### Save the @script_contents for this script to a file on the Master Distribution point.
382
+ ###
383
+ ### If you'll be uploading several files you can specify unmount as false, and do it manually when all
384
+ ### are finished.
385
+ ###
386
+ ### use {#script_contents=} to set the script_contents from a String or Pathname
387
+ ###
388
+ ### @param rw_pw[String] the password for the read/write account on the master Distribution Point
389
+ ###
390
+ ### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
391
+ ###
392
+ ### @return [void]
393
+ ###
394
+ def upload_master_file( rw_pw, unmount = true)
395
+ raise JSS::MissingDataError, "No code specified. Use #code= first." if @script_contents.nil? or @script_contents.empty?
396
+
397
+ mdp = JSS::DistributionPoint.master_distribution_point
398
+ raise JSS::InvaldDatatError, "Incorrect password for read-write access to master distribution point." unless mdp.check_pw :rw, rw_pw
399
+
400
+ destination = mdp.mount(rw_pw, :rw) + "#{DIST_POINT_SCRIPTS_FOLDER}/#{@filename}"
401
+ destination.save @script_contents
402
+ mdp.unmount if unmount
403
+ end # upload
404
+
405
+ ###
406
+ ### Delete the filename from the master distribution point, if it exists.
407
+ ###
408
+ ### If you'll be uploading several files you can specify unmount as false, and do it manually when all
409
+ ### are finished.
410
+ ###
411
+ ### @param rw_pw[String] the password for the read/write account on the master Distribution Point
412
+ ###
413
+ ### @param unmount[Boolean] whether or not ot unount the distribution point when finished.
414
+ ###
415
+ ### @return [Boolean] was the file deleted?
416
+ ###
417
+ def delete_master_file(rw_pw, unmount = true)
418
+ file = JSS::DistributionPoint.master_distribution_point.mount(rw_pw, :rw) + "#{DIST_POINT_SCRIPTS_FOLDER}/#{@filename}"
419
+ if file.exist?
420
+ file.delete
421
+ did_it = true
422
+ else
423
+ did_it = false
424
+ end # if exists
425
+ JSS::DistributionPoint.master_distribution_point.unmount if unmount
426
+ return did_it
427
+ end
428
+
429
+
430
+ ###
431
+ ### Run this script on the current machine using the "jamf runScript" command.
432
+ ###
433
+ ### If the script code is available in the {#script_contents} attribute, then that
434
+ ### code is saved to a tmp file, and executed. Otherwise, the script is assumed
435
+ ### to be stored on the distribution point.
436
+ ###
437
+ ### If the dist. point has http downloads enabled, then the URL is used as the path with the
438
+ ### 'jamf runScript' command.
439
+ ###
440
+ ### If http is not an option, the dist.point is mounted, and the script copied locally before running.
441
+ ### In this case the options must include :ro_pw => 'somepass'
442
+ ### to provide the read-only password for mounting the distribution point. If :unmount => true
443
+ ### is provided, the dist. point will be unmounted immediately after copying
444
+ ### the script locally. Otherwise it will remain mounted, in case there's further need of it.
445
+ ###
446
+ ### Any local on-disk copies of the script are removed after running.
447
+ ###
448
+ ### After the script runs, this method returns a two-item Array.
449
+ ### - the first item is an Integer, the exit status of the script itself (0 means success)
450
+ ### - the second item is a String, the output (stdout + stderr) of the jamf binary, which will include
451
+ ### the script output.
452
+ ### The exit status of the jamf binary process will be available as a Process::Status object
453
+ ### in $? immediately after running.
454
+ ###
455
+ ### @param opts[Hash] the options for running the script
456
+ ###
457
+ ### @option opts :target[String,Pathname] the 'target drive', passed to the script as the first commandline option.
458
+ ### Defaults to '/'
459
+ ###
460
+ ### @option opts :computer_name[String] the name of the computer, passed to the script as the second commandline
461
+ ### option. Defaults to the name of the current machine
462
+ ###
463
+ ### @option opts :username[String] the username to be passed to the script as the third commandline option.
464
+ ###
465
+ ### @option opts :p1..:p8[String] the values to be passed as the 4th - 11th commandline options, overriding
466
+ ### those defined with the script in the JSS
467
+ ###
468
+ ### @option opts :ro_pw[String] the read-only password for mounting the distribution point, if needed
469
+ ###
470
+ ### @option opts :unmount[Boolean} should the dist. point be unmounted when finished, if we mounted it?
471
+ ###
472
+ ### @option opts :verbose[Boolean] should the 'jamf runScript' command be verbose?
473
+ ###
474
+ ### @option opts :show_output[Boolean] should the output (stdout + stderr) of 'jamf runScript' be copied to
475
+ ### stdout in realtime, as well as returned?
476
+ ###
477
+ ### @return [Array<(Integer,String)>] the exit status of the *script* and stdout+stderr of 'jamf runScript'.
478
+ ### The exit status of the jamf binary will be available in $? immediately after running.
479
+ ###
480
+ ### *NOTE* In the WEB UI and API, the definable parameters are numbered 4-11, since 1, 2, & 3 are the
481
+ ### target drive, computer name, and user name respectively. However, the jamf binary refers to them as
482
+ ### p1-p8, and that's how they are expected as options to #run. So if :p1=> "new param" is given as an
483
+ ### aption to #run, it will override any value that the API provided in @parameters[:parameter4]
484
+ ###
485
+ def run( opts = {} )
486
+
487
+ opts[:target] ||= "/"
488
+ opts[:p1] ||= @parameters[:parameter4]
489
+ opts[:p2] ||= @parameters[:parameter5]
490
+ opts[:p3] ||= @parameters[:parameter6]
491
+ opts[:p4] ||= @parameters[:parameter7]
492
+ opts[:p5] ||= @parameters[:parameter8]
493
+ opts[:p6] ||= @parameters[:parameter9]
494
+ opts[:p7] ||= @parameters[:parameter10]
495
+ opts[:p8] ||= @parameters[:parameter11]
496
+
497
+ dp_mount_pt = nil
498
+ delete_exec = false
499
+
500
+ begin
501
+
502
+ # do we have the code already? if so, save it out and make it executable
503
+ if @script_contents and (not @script_contents.empty?)
504
+
505
+ script_path = JSS::Client::DOWNLOADS_FOLDER
506
+
507
+ executable = script_path + @filename
508
+
509
+ executable.jss_touch
510
+ executable.chmod 0700
511
+ executable.jss_save @script_contents
512
+ delete_exec = true
513
+
514
+ # otherwise, get it from the dist. point
515
+ else
516
+ dist_point = JSS::DistributionPoint.my_distribution_point
517
+
518
+ ### how do we access our dist. point?
519
+ if dist_point.http_downloads_enabled
520
+ script_path = dist_point.http_url + "/#{DIST_POINT_SCRIPTS_FOLDER}/"
521
+
522
+ else
523
+ dp_mount_pt = dist_point.mount opts[:ro_pw]
524
+
525
+ script_path = (dp_mount_pt + DIST_POINT_SCRIPTS_FOLDER)
526
+
527
+ end # if http enabled
528
+
529
+ end # if @script_contents and (not @script_contents.empty?)
530
+
531
+
532
+ # build the command as an array.
533
+ command_arry = ["-script", @filename, '-path', script_path.to_s]
534
+
535
+ command_arry << "-target"
536
+ command_arry << opts[:target].to_s
537
+
538
+ command_arry << "-computerName" if opts[:computer_name]
539
+ command_arry << opts[:computer_name] if opts[:computer_name]
540
+
541
+ command_arry << "-username" if opts[:username]
542
+ command_arry << opts[:username] if opts[:username]
543
+
544
+ command_arry << "-p1" if opts[:p1]
545
+ command_arry << opts[:p1] if opts[:p1]
546
+
547
+ command_arry << "-p2" if opts[:p2]
548
+ command_arry << opts[:p2] if opts[:p2]
549
+
550
+ command_arry << "-p3" if opts[:p3]
551
+ command_arry << opts[:p3] if opts[:p3]
552
+
553
+ command_arry << "-p4" if opts[:p4]
554
+ command_arry << opts[:p4] if opts[:p4]
555
+
556
+ command_arry << "-p5" if opts[:p5]
557
+ command_arry << opts[:p5] if opts[:p5]
558
+
559
+ command_arry << "-p6" if opts[:p6]
560
+ command_arry << opts[:p6] if opts[:p6]
561
+
562
+ command_arry << "-p7" if opts[:p7]
563
+ command_arry << opts[:p7] if opts[:p7]
564
+
565
+ command_arry << "-p8" if opts[:p8]
566
+ command_arry << opts[:p8] if opts[:p8]
567
+
568
+ command_arry << "-verbose" if opts[:verbose]
569
+
570
+ command = command_arry.shelljoin
571
+
572
+ jamf_output = JSS::Client.run_jamf "runScript", command, opts[:show_output]
573
+
574
+ jamf_output =~ /^.*Script exit code: (\d+)(\D|$)/
575
+
576
+ script_exitstatus = $1.to_i
577
+
578
+ ensure
579
+ executable.delete if delete_exec and executable.exist?
580
+ dist_point.unmount if (dp_mount_pt and dp_mount_pt.mountpoint? and opts[:unmount])
581
+ end # begin/ensure
582
+
583
+ return [script_exitstatus, jamf_output]
584
+
585
+ end # def run
586
+
587
+
588
+ # aliases under their methods seem to confuse the YARD documenter, so I'm putting them all here.
589
+ alias oses os_requirements
590
+ alias oses= os_requirements=
591
+ alias code script_contents
592
+ alias code= script_contents=
593
+ alias contents script_contents
594
+ alias contents= script_contents=
595
+
596
+
597
+ #####################################
598
+ ### Private Instance Methods
599
+ #####################################
600
+
601
+ private
602
+
603
+ ###
604
+ ### Return the xml for creating or updating this script in the JSS
605
+ ###
606
+ def rest_xml
607
+ doc = REXML::Document.new
608
+ scpt = doc.add_element "script"
609
+ scpt.add_element('category').text = @category
610
+ scpt.add_element('filename').text = @filename
611
+ scpt.add_element('id').text = @id
612
+ scpt.add_element('info').text = @info
613
+ scpt.add_element('name').text = @name
614
+ scpt.add_element('notes').text = @notes
615
+ scpt.add_element('os_requirements').text = JSS.to_s_and_a(@os_requirements)[:stringform]
616
+ scpt.add_element('priority').text = @priority
617
+
618
+ if @parameters.empty?
619
+ scpt.add_element('parameters').text = nil
620
+ else
621
+ pars = scpt.add_element('parameters')
622
+ PARAMETER_KEYS.each {|p| pars.add_element(p.to_s).text = @parameters[p]}
623
+ end
624
+
625
+ scpt.add_element('script_contents_encoded').text = Base64.encode64(@script_contents)
626
+
627
+ return doc.to_s
628
+ end # rest xml
629
+
630
+ end # class Script
631
+ end # midule