jss-api 0.5.5 → 0.5.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.
- data/.yardopts +7 -0
- data/CHANGES.md +9 -1
- data/README.md +10 -5
- data/bin/cgrouper +485 -0
- data/bin/subnet-update +400 -0
- data/lib/jss-api/api_connection.rb +22 -11
- data/lib/jss-api/api_object.rb +9 -2
- data/lib/jss-api/api_object/locatable.rb +1 -1
- data/lib/jss-api/api_object/osx_configuration_profile.rb +261 -0
- data/lib/jss-api/api_object/self_servable.rb +355 -0
- data/lib/jss-api/configuration.rb +2 -0
- data/lib/jss-api/version.rb +1 -1
- metadata +25 -43
data/.yardopts
ADDED
data/CHANGES.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
# Change History
|
2
2
|
|
3
|
+
v0.5.6 2014-11-04
|
4
|
+
- now requires Ruby >= 1.9.3 and rest-client >= 1.7.0. Needed for Casper >= 9.61's lack of support for SSLv3.
|
5
|
+
- APIConnection now accepts :ssl_version option in the argument hash. Defaults to 'TLSv1'
|
6
|
+
- Configuration now supports the api_ssl_version key, used for the :ssl_version option of the APIConnection.
|
7
|
+
- the example programs have been moved to the bin directory, and are now included in the gem installation.
|
8
|
+
- many documentation updates as we adjust to being live
|
9
|
+
- minor bugfixes
|
10
|
+
|
3
11
|
v0.5.0 2014-10-23
|
4
|
-
- first opensource release
|
12
|
+
- first opensource release
|
data/README.md
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
## DESCRIPTION
|
4
4
|
|
5
|
-
The jss-api gem provides a Ruby module called JSS, which is used for accessing the REST API of the JAMF Software Server (JSS)
|
5
|
+
The jss-api gem provides a Ruby module called JSS, which is used for accessing the REST API of the JAMF Software Server (JSS), the core of the Casper Suite, an enterprise-level management tool for Apple devices from [JAMF Software, LLC](http://www.jamfsoftware.com/).
|
6
|
+
|
7
|
+
The module abstracts API resources as Ruby objects, and provides methods for interacting with those resources. It also provides some features that aren't a part of the API itself, but come with other Casper-related tools, such as uploading .pkg and .dmg {JSS::Package} data to the master distribution point, and the installation of {JSS::Package} objects on client machines. (See BEYOND THE API)
|
6
8
|
|
7
9
|
The module is not a complete implementation of the Casper API. Only some API objects are modeled, some only minimally. Of
|
8
10
|
those, some are read-only, some partially writable, some fully read-write (all implemented objects can be deleted)
|
@@ -11,6 +13,8 @@ See OBJECTS IMPLEMENTED for a list.
|
|
11
13
|
We've implemented the things we need in our environment, and as our needs grow, we'll add more.
|
12
14
|
Hopefully others will find it useful, and add more to it as well.
|
13
15
|
|
16
|
+
[Full technical documentation can be found here.](http://www.rubydoc.info/gems/jss-api/)
|
17
|
+
|
14
18
|
|
15
19
|
## SYNOPSIS
|
16
20
|
|
@@ -334,13 +338,14 @@ the JSS gem was written for:
|
|
334
338
|
|
335
339
|
* Mac OS X 10.8 and higher
|
336
340
|
* Casper Suite version 9.4 or higher
|
337
|
-
* Ruby 1.8.7 and
|
341
|
+
* Casper 9.4 - 9.6 require Ruby 1.8.7 and higher
|
342
|
+
* Casper >= 9.61 require Ruby 1.9.3 and higher
|
338
343
|
|
339
344
|
It also requires these gems, which will be installed automatically if you install JSS with `gem install jss`
|
340
345
|
|
341
|
-
* rest-client >=1.6.7 http://rubygems.org/gems/rest-client
|
346
|
+
* rest-client >=1.6.7 ( >= 1.7.0 with Casper >= 9.6.1) http://rubygems.org/gems/rest-client
|
342
347
|
* json or json\_pure >= 1.6.5 http://rubygems.org/gems/json or http://rubygems.org/gems/json_pure
|
343
|
-
* (only in ruby 1.8.7. Ruby
|
348
|
+
* (only in ruby 1.8.7. Ruby >= 1.9 has json in its standard library)
|
344
349
|
* ruby-mysql >= 2.9.12 http://rubygems.org/gems/ruby-mysql
|
345
350
|
* (only for a few things that still require direct SQL access to the JSS database)
|
346
351
|
* plist =3.1.0 http://rubygems.org/gems/plist
|
@@ -356,7 +361,7 @@ In general, you can install the JSS Gem with this command:
|
|
356
361
|
|
357
362
|
`gem install jss-api`
|
358
363
|
|
359
|
-
If you're using Ruby 1.8.7, install the following gems manually first, since the JSS gem will try to install newer, incompatible versions if they aren't pre-installed.
|
364
|
+
If you're using Ruby 1.8.7 (Casper 9.4 - 9.6 only), install the following gems manually first, since the JSS gem will try to install newer, incompatible versions if they aren't pre-installed.
|
360
365
|
|
361
366
|
`gem install json -v 1.6.5`
|
362
367
|
|
data/bin/cgrouper
ADDED
@@ -0,0 +1,485 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
### Copyright 2014 Pixar
|
4
|
+
###
|
5
|
+
### Licensed under the Apache License, Version 2.0 (the "Apache License")
|
6
|
+
### with the following modification; you may not use this file except in
|
7
|
+
### compliance with the Apache License and the following modification to it:
|
8
|
+
### Section 6. Trademarks. is deleted and replaced with:
|
9
|
+
###
|
10
|
+
### 6. Trademarks. This License does not grant permission to use the trade
|
11
|
+
### names, trademarks, service marks, or product names of the Licensor
|
12
|
+
### and its affiliates, except as required to comply with Section 4(c) of
|
13
|
+
### the License and to reproduce the content of the NOTICE file.
|
14
|
+
###
|
15
|
+
### You may obtain a copy of the Apache License at
|
16
|
+
###
|
17
|
+
### http://www.apache.org/licenses/LICENSE-2.0
|
18
|
+
###
|
19
|
+
### Unless required by applicable law or agreed to in writing, software
|
20
|
+
### distributed under the Apache License with the above modification is
|
21
|
+
### distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
22
|
+
### KIND, either express or implied. See the Apache License for the specific
|
23
|
+
### language governing permissions and limitations under the Apache License.
|
24
|
+
|
25
|
+
|
26
|
+
# Create or change the membership of a computer group in the JSS
|
27
|
+
|
28
|
+
|
29
|
+
# Load in the JSS library
|
30
|
+
require 'jss-api'
|
31
|
+
|
32
|
+
# Load other libs
|
33
|
+
require 'getoptlong'
|
34
|
+
require 'ostruct'
|
35
|
+
|
36
|
+
class App
|
37
|
+
|
38
|
+
#####################################
|
39
|
+
###
|
40
|
+
### Constants
|
41
|
+
###
|
42
|
+
USAGE = "Usage: #{File.basename($0)} [-LsmcdlarRC] [--help] [-n newname]
|
43
|
+
[-S server] [-U user] [-T timeout] [-V] [--debug]
|
44
|
+
group [-f /file/path ] [computer [computer ...]]"
|
45
|
+
|
46
|
+
ACTIONS_NEEDING_GROUP = [ :create_group, :rename_group, :delete_group, :add_members, :remove_members, :remove_all, :list_members]
|
47
|
+
|
48
|
+
ACTIONS_FOR_STATIC_GROUPS_ONLY = [:create_group, :add_members, :remove_members, :remove_all]
|
49
|
+
|
50
|
+
#####################################
|
51
|
+
### Attributes
|
52
|
+
|
53
|
+
attr_reader :debug
|
54
|
+
|
55
|
+
#####################################
|
56
|
+
###
|
57
|
+
### set up
|
58
|
+
###
|
59
|
+
def initialize(args)
|
60
|
+
|
61
|
+
@debug = false
|
62
|
+
|
63
|
+
# define the options
|
64
|
+
cli_opts = GetoptLong.new(
|
65
|
+
[ '--help', '-h', '-H', GetoptLong::NO_ARGUMENT ],
|
66
|
+
[ '--list-groups', '-L', GetoptLong::NO_ARGUMENT ],
|
67
|
+
[ '--list-static', '-s', GetoptLong::NO_ARGUMENT ],
|
68
|
+
[ '--list-smart', '-m', GetoptLong::NO_ARGUMENT ],
|
69
|
+
[ '--create-group', '--create', '-c', GetoptLong::NO_ARGUMENT ],
|
70
|
+
[ '--rename-group', '--rename', '-n', GetoptLong::REQUIRED_ARGUMENT ],
|
71
|
+
[ '--delete-group', '--delete', '-d', GetoptLong::NO_ARGUMENT ],
|
72
|
+
[ '--list-members', '--list-computers', '-l', GetoptLong::NO_ARGUMENT ],
|
73
|
+
[ '--add-members', '--add', '-a', GetoptLong::NO_ARGUMENT ],
|
74
|
+
[ '--remove-members', '--remove', '-r', GetoptLong::NO_ARGUMENT ],
|
75
|
+
[ '--remove-all-members', '-R', GetoptLong::NO_ARGUMENT ],
|
76
|
+
[ '--file', '-f', GetoptLong::REQUIRED_ARGUMENT ],
|
77
|
+
[ '--server', '-S', GetoptLong::OPTIONAL_ARGUMENT],
|
78
|
+
[ '--port', '-P', GetoptLong::OPTIONAL_ARGUMENT],
|
79
|
+
[ '--user', '-U', GetoptLong::OPTIONAL_ARGUMENT],
|
80
|
+
[ '--no-verify-cert', '-V', GetoptLong::NO_ARGUMENT],
|
81
|
+
[ '--timeout', '-T', GetoptLong::OPTIONAL_ARGUMENT],
|
82
|
+
[ '--no-confirm', '-C', GetoptLong::NO_ARGUMENT],
|
83
|
+
[ '--debug', GetoptLong::NO_ARGUMENT]
|
84
|
+
)
|
85
|
+
|
86
|
+
# here's where we hold cmdline args and other user options
|
87
|
+
@options = OpenStruct.new
|
88
|
+
|
89
|
+
# set defaults
|
90
|
+
@options.action = :none
|
91
|
+
|
92
|
+
# if stdin is not a tty, then we must assume
|
93
|
+
# we're being passed a password
|
94
|
+
@options.getpass = $stdin.tty? ? :prompt : :stdin
|
95
|
+
|
96
|
+
# parse the options
|
97
|
+
cli_opts.each do |opt, arg|
|
98
|
+
case opt
|
99
|
+
when '--help'
|
100
|
+
show_help
|
101
|
+
|
102
|
+
when '--list-groups'
|
103
|
+
@options.action = :list_groups
|
104
|
+
|
105
|
+
when '--list-static'
|
106
|
+
@options.action = :list_static
|
107
|
+
|
108
|
+
when '--list-smart'
|
109
|
+
@options.action = :list_smart
|
110
|
+
|
111
|
+
when '--list-members'
|
112
|
+
@options.action = :list_members
|
113
|
+
|
114
|
+
when '--create-group'
|
115
|
+
@options.action = :create_group
|
116
|
+
|
117
|
+
when '--rename-group'
|
118
|
+
@options.action = :rename_group
|
119
|
+
@options.new_name = arg
|
120
|
+
|
121
|
+
when '--delete-group'
|
122
|
+
@options.action = :delete_group
|
123
|
+
|
124
|
+
when '--add-members'
|
125
|
+
@options.action = :add_members
|
126
|
+
|
127
|
+
when '--remove-members'
|
128
|
+
@options.action = :remove_members
|
129
|
+
|
130
|
+
when '--remove-all-members'
|
131
|
+
@options.action = :remove_all
|
132
|
+
|
133
|
+
when '--file'
|
134
|
+
@options.input_file = Pathname.new arg
|
135
|
+
|
136
|
+
when '--server'
|
137
|
+
@options.server = arg
|
138
|
+
|
139
|
+
when '--port'
|
140
|
+
@options.port = arg
|
141
|
+
|
142
|
+
when '--user'
|
143
|
+
@options.user = arg
|
144
|
+
|
145
|
+
when '--no-verify-cert'
|
146
|
+
@options.verify_cert = false
|
147
|
+
|
148
|
+
when '--timeout'
|
149
|
+
@options.timeout = arg
|
150
|
+
|
151
|
+
when '--no-confirm'
|
152
|
+
@options.no_confirm = true
|
153
|
+
|
154
|
+
when '--debug'
|
155
|
+
@debug = true
|
156
|
+
|
157
|
+
end # case
|
158
|
+
end # opts.each
|
159
|
+
|
160
|
+
@options.group = ARGV.shift
|
161
|
+
|
162
|
+
# if we were given a file of computer names, read it in
|
163
|
+
@options.computers = @options.input_file ? get_computers_from_file : []
|
164
|
+
|
165
|
+
# and add any computers on the commandline
|
166
|
+
@options.computers += ARGV
|
167
|
+
|
168
|
+
# will we say anything when finished?
|
169
|
+
@done_msg = nil
|
170
|
+
|
171
|
+
end # init
|
172
|
+
|
173
|
+
|
174
|
+
|
175
|
+
#####################################
|
176
|
+
###
|
177
|
+
### Do It
|
178
|
+
###
|
179
|
+
def run
|
180
|
+
|
181
|
+
if @options.action == :none
|
182
|
+
puts USAGE
|
183
|
+
return
|
184
|
+
end
|
185
|
+
|
186
|
+
# use any config settings defined....
|
187
|
+
@options.user ||= JSS::CONFIG.api_username
|
188
|
+
@options.server ||= JSS::CONFIG.api_server_name
|
189
|
+
|
190
|
+
raise JSS::MissingDataError, "No JSS Username provided or found in the JSS gem config." unless @options.user
|
191
|
+
raise JSS::MissingDataError, "No JSS Server provided or found in the JSS gem config." unless @options.server
|
192
|
+
|
193
|
+
JSS::API.connect( :server => @options.server,
|
194
|
+
:port => @options.port,
|
195
|
+
:verify_cert => @options.verify_cert,
|
196
|
+
:user => @options.user,
|
197
|
+
:pw => @options.getpass,
|
198
|
+
:stdin_line => 1,
|
199
|
+
:timeout => @options.timeout
|
200
|
+
)
|
201
|
+
|
202
|
+
|
203
|
+
if ACTIONS_NEEDING_GROUP.include? @options.action
|
204
|
+
|
205
|
+
raise JSS::MissingDataError, "Please specify a group name" unless @options.group
|
206
|
+
|
207
|
+
# get the group from the API
|
208
|
+
if @options.action == :create_group
|
209
|
+
@group = JSS::ComputerGroup.new :id => :new, :name => @options.group, :type => :static
|
210
|
+
else
|
211
|
+
@group = JSS::ComputerGroup.new :name => @options.group
|
212
|
+
end
|
213
|
+
|
214
|
+
end # if ACTIONS_NEEDING_GROUP
|
215
|
+
|
216
|
+
# smart groups can't have some things done to them
|
217
|
+
raise InvalidTypeError, "You can't do that to a smart group. Use the JSS WebApp if needed." if ACTIONS_FOR_STATIC_GROUPS_ONLY.include? @options.action and @group.smart?
|
218
|
+
|
219
|
+
|
220
|
+
case @options.action
|
221
|
+
|
222
|
+
when :list_groups
|
223
|
+
list_groups
|
224
|
+
|
225
|
+
when :list_static
|
226
|
+
list_groups :static
|
227
|
+
|
228
|
+
when :list_smart
|
229
|
+
list_groups :smart
|
230
|
+
|
231
|
+
when :list_members
|
232
|
+
list_members
|
233
|
+
|
234
|
+
when :create_group
|
235
|
+
create_group
|
236
|
+
|
237
|
+
when :rename_group
|
238
|
+
rename_group
|
239
|
+
|
240
|
+
when :delete_group
|
241
|
+
delete_group
|
242
|
+
|
243
|
+
when :add_members
|
244
|
+
add_members
|
245
|
+
|
246
|
+
when :remove_members
|
247
|
+
remove_members
|
248
|
+
|
249
|
+
when :remove_all
|
250
|
+
remove_all
|
251
|
+
|
252
|
+
end # case @options.action
|
253
|
+
|
254
|
+
puts "Done! #{@done_msg}" if @done_msg
|
255
|
+
|
256
|
+
end # run
|
257
|
+
|
258
|
+
|
259
|
+
#####################################
|
260
|
+
###
|
261
|
+
### Show Help
|
262
|
+
###
|
263
|
+
def show_help
|
264
|
+
puts <<-FULLHELP
|
265
|
+
A tool for working with computer groups in the JSS.
|
266
|
+
|
267
|
+
#{USAGE}
|
268
|
+
|
269
|
+
Options:
|
270
|
+
-L, --list-groups - list all computer groups in the JSS
|
271
|
+
-s, --list-static - list all static computer groups in the JSS
|
272
|
+
-m, --list-smart - list all smart computer groups in the JSS
|
273
|
+
-c, --create-group - create a new static computer group in the JSS
|
274
|
+
-n, --rename newname - rename the specified computer group to newname
|
275
|
+
-d, --delete - delete the specified computer group (static groups only)
|
276
|
+
-l, --list-members - list all the computers in the group specified
|
277
|
+
-a, --add-members - add the specified computer(s) to the specified group
|
278
|
+
-r, --remove-members - remove the specified computer(s) from the specified group
|
279
|
+
-R, --remove-all - remove all computers from the specified group
|
280
|
+
-f, --file /path/... - read computer names/ids from the file at /path/...
|
281
|
+
-S, --server srvr - specify the JSS API server name
|
282
|
+
-P, --port portnum - specify the JSS API port
|
283
|
+
-U, --user username - specify the JSS API user
|
284
|
+
-V, --no-verify-cert - Allow self-signed, unverified SSL certificate
|
285
|
+
-T, --timeout secs - specify the JSS API timeout
|
286
|
+
-C - don't ask for confirmation before acting
|
287
|
+
--debug - show the ruby backtrace when errors occur
|
288
|
+
-H, --help - show this help
|
289
|
+
|
290
|
+
Notes:
|
291
|
+
|
292
|
+
- If no API settings are provided, they will be read from /etc/jss_gem.conf
|
293
|
+
and ~/.jss_gem.conf. See the JSS Gem docs for details.
|
294
|
+
|
295
|
+
- The password for the connection will be read from STDIN or prompted if needed
|
296
|
+
|
297
|
+
- Computers can be specified by name or JSS id number. If a name exists
|
298
|
+
more than once in the JSS, the machine is skipped. Use IDs to avoid this.
|
299
|
+
|
300
|
+
- Only static groups can be modified. Use the JSS WebUI for editing smart groups
|
301
|
+
|
302
|
+
- If a file is used to specify computers, they are combined with any
|
303
|
+
specified on the commandline.
|
304
|
+
|
305
|
+
- Files of computers must be whitespace-separated
|
306
|
+
(spaces, tabs, & returns in any number or combination)
|
307
|
+
|
308
|
+
FULLHELP
|
309
|
+
return
|
310
|
+
end
|
311
|
+
|
312
|
+
#####################################
|
313
|
+
###
|
314
|
+
### Spit out a list of all computer groups
|
315
|
+
###
|
316
|
+
def list_groups(show = :all)
|
317
|
+
case show
|
318
|
+
when :all
|
319
|
+
label = "All"
|
320
|
+
groups_to_show = JSS::ComputerGroup.all
|
321
|
+
when :static
|
322
|
+
label = "Static"
|
323
|
+
groups_to_show = JSS::ComputerGroup.all_static
|
324
|
+
when :smart
|
325
|
+
label = "Smart"
|
326
|
+
groups_to_show = JSS::ComputerGroup.all_smart
|
327
|
+
end #case
|
328
|
+
|
329
|
+
puts "# #{label} computer groups in the JSS"
|
330
|
+
puts "#---------------------------------------------"
|
331
|
+
|
332
|
+
groups_to_show.sort{|a,b| a[:name].downcase <=> b[:name].downcase}.each do |grp|
|
333
|
+
puts grp[:name]
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
#####################################
|
338
|
+
###
|
339
|
+
### Spit out a list of all computers in a group
|
340
|
+
###
|
341
|
+
def list_members
|
342
|
+
puts "# All members of JSS #{@group.smart? ? 'smart' : 'static'} computer group '#{@options.group}'"
|
343
|
+
puts "#--- name (id) ---------------------------------"
|
344
|
+
|
345
|
+
# put them into a tmp array, so that
|
346
|
+
# we can sort by computer name, remembering that
|
347
|
+
# there can be duplicate names.
|
348
|
+
list = []
|
349
|
+
@group.members.each{|mem| list << "#{mem[:name]} (#{mem[:id]})" }
|
350
|
+
puts list.sort #.join("\n")
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
#####################################
|
355
|
+
###
|
356
|
+
### Create a new group
|
357
|
+
###
|
358
|
+
def create_group
|
359
|
+
|
360
|
+
return unless confirm "create a new static group named '#{@options.group}'"
|
361
|
+
@group.create
|
362
|
+
|
363
|
+
unless @options.computers.empty?
|
364
|
+
add_members
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
#####################################
|
370
|
+
###
|
371
|
+
### rename a group
|
372
|
+
###
|
373
|
+
def rename_group
|
374
|
+
return unless confirm "rename group '#{@group.name}' to '#{@options.new_name}'"
|
375
|
+
@group.name = @options.new_name
|
376
|
+
@group.update
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
#####################################
|
381
|
+
###
|
382
|
+
### delete a group
|
383
|
+
###
|
384
|
+
def delete_group
|
385
|
+
return unless confirm "DELETE group '#{@group.name}'"
|
386
|
+
@group.delete
|
387
|
+
end
|
388
|
+
|
389
|
+
|
390
|
+
#####################################
|
391
|
+
###
|
392
|
+
### add members to a group
|
393
|
+
###
|
394
|
+
def add_members
|
395
|
+
raise JSS::MissingDataError, "No computer names provided" if @options.computers.empty?
|
396
|
+
raise JSS::UnsupportedError, "Smart group members can't be changed." if @group.smart?
|
397
|
+
return unless @options.action == :create_group or confirm "add computers to group '#{@group.name}'"
|
398
|
+
|
399
|
+
@options.computers.each do |c|
|
400
|
+
begin
|
401
|
+
@group.add_member c
|
402
|
+
rescue JSS::NoSuchItemError
|
403
|
+
puts "#{$!} - skipping"
|
404
|
+
end # begin
|
405
|
+
end # each
|
406
|
+
|
407
|
+
@group.update
|
408
|
+
end
|
409
|
+
|
410
|
+
#####################################
|
411
|
+
###
|
412
|
+
### remove members from a group
|
413
|
+
###
|
414
|
+
def remove_members
|
415
|
+
raise JSS::MissingDataError, "No computer names provided" if @options.computers.empty?
|
416
|
+
raise JSS::UnsupportedError, "Smart group members can't be changed." if @group.smart?
|
417
|
+
return unless confirm "remove computers from group '#{@group.name}'"
|
418
|
+
@options.computers.each do |c|
|
419
|
+
begin
|
420
|
+
@group.remove_member c
|
421
|
+
rescue JSS::NoSuchItemError
|
422
|
+
puts "#{$!} - skipping"
|
423
|
+
end
|
424
|
+
end
|
425
|
+
@group.update
|
426
|
+
end
|
427
|
+
|
428
|
+
#####################################
|
429
|
+
###
|
430
|
+
### remove all members from a group
|
431
|
+
###
|
432
|
+
def remove_all
|
433
|
+
raise JSS::UnsupportedError, "Smart group members can't be changed." if @group.smart?
|
434
|
+
return unless confirm "remove ALL computers from group '#{@group.name}'"
|
435
|
+
@group.clear
|
436
|
+
@group.update
|
437
|
+
end
|
438
|
+
|
439
|
+
|
440
|
+
#####################################
|
441
|
+
###
|
442
|
+
### Read computer names from a file
|
443
|
+
### Generally the names should be one per line, but
|
444
|
+
### they can be separated by any whitespace.
|
445
|
+
### Returns an array of computer names from the file.
|
446
|
+
###
|
447
|
+
def get_computers_from_file
|
448
|
+
raise JSS::NoSuchItemError "File #{@options.input_file} isn't a file or isn't readable." unless \
|
449
|
+
@options.input_file.file? and @options.input_file.readable?
|
450
|
+
@options.input_file.read.split(/\s+/)
|
451
|
+
end
|
452
|
+
|
453
|
+
#####################################
|
454
|
+
###
|
455
|
+
### Get confirmation before doing something
|
456
|
+
### Returns true or false
|
457
|
+
###
|
458
|
+
def confirm (action)
|
459
|
+
return true if @options.no_confirm
|
460
|
+
|
461
|
+
print "Really #{action}? (y/n): "
|
462
|
+
$stdin.reopen '/dev/tty'
|
463
|
+
reply = $stdin.gets.strip
|
464
|
+
return true if reply =~ /^y/i
|
465
|
+
return false
|
466
|
+
|
467
|
+
end # confirm
|
468
|
+
|
469
|
+
|
470
|
+
end # class App
|
471
|
+
|
472
|
+
#######################################
|
473
|
+
begin
|
474
|
+
app = App.new(ARGV)
|
475
|
+
app.run
|
476
|
+
|
477
|
+
rescue
|
478
|
+
# handle exceptions not handled elsewhere
|
479
|
+
puts "An error occurred: #{$!}"
|
480
|
+
puts "Backtrace:" if app.debug
|
481
|
+
puts $@ if app.debug
|
482
|
+
|
483
|
+
ensure
|
484
|
+
|
485
|
+
end
|