zabcon 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +10 -0
- data/libs/argument_processor.rb +768 -0
- data/libs/command_help.rb +106 -0
- data/libs/command_tree.rb +307 -0
- data/libs/defines.rb +46 -0
- data/libs/exceptions.rb +119 -0
- data/libs/help.xml +275 -0
- data/libs/input.rb +55 -0
- data/libs/printer.rb +383 -0
- data/libs/zabcon_core.rb +742 -0
- data/libs/zabcon_exceptions.rb +45 -0
- data/libs/zabcon_globals.rb +210 -0
- data/libs/zbxcliserver.rb +310 -0
- data/libs/zdebug.rb +163 -0
- data/zabcon.conf.default +6 -0
- data/zabcon.rb +236 -0
- metadata +124 -0
data/README
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
To use Zabcon, run 'zabcon' (or zabcon.rb)
|
2
|
+
|
3
|
+
You can log into Zabbix API with:
|
4
|
+
> login <server> <username> <password>
|
5
|
+
|
6
|
+
Make sure that user has API access enabled in Zabbix administration section.
|
7
|
+
|
8
|
+
You can use configuration file to store connection information -
|
9
|
+
copy zabcon.conf.default to zabcon.conf and modify it according
|
10
|
+
to your Zabbix installation.
|
@@ -0,0 +1,768 @@
|
|
1
|
+
#GPL 2.0 http://www.gnu.org/licenses/gpl-2.0.html
|
2
|
+
#Zabbix CLI Tool and associated files
|
3
|
+
#Copyright (C) 2009,2010 Andrew Nelson nelsonab(at)red-tux(dot)net
|
4
|
+
#
|
5
|
+
#This program is free software; you can redistribute it and/or
|
6
|
+
#modify it under the terms of the GNU General Public License
|
7
|
+
#as published by the Free Software Foundation; either version 2
|
8
|
+
#of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
#This program is distributed in the hope that it will be useful,
|
11
|
+
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
#GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
#You should have received a copy of the GNU General Public License
|
16
|
+
#along with this program; if not, write to the Free Software
|
17
|
+
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
18
|
+
|
19
|
+
##########################################
|
20
|
+
# Subversion information
|
21
|
+
# $Id: argument_processor.rb 258 2010-12-28 22:49:21Z nelsonab $
|
22
|
+
# $Revision: 258 $
|
23
|
+
##########################################
|
24
|
+
|
25
|
+
require 'libs/zdebug'
|
26
|
+
require 'libs/exceptions'
|
27
|
+
require 'libs/zabcon_exceptions'
|
28
|
+
require 'libs/zabcon_globals'
|
29
|
+
|
30
|
+
# ArgumentProcessor This class contains the functions for processing the arguments passed to each command
|
31
|
+
# The functions will return two hashes.
|
32
|
+
# :api_params - parameters to pass to the API call
|
33
|
+
# :show_params - parameters to pass to the print routines
|
34
|
+
# The args parameter is a hash of the
|
35
|
+
|
36
|
+
# All functions for argument processing are in alphabetical order except for default functions which are placed first
|
37
|
+
|
38
|
+
class ArgumentProcessor
|
39
|
+
|
40
|
+
include ZDebug
|
41
|
+
|
42
|
+
attr_reader :help, :default, :default_get
|
43
|
+
|
44
|
+
def initialize
|
45
|
+
@help=self.method(:help_processor)
|
46
|
+
@default=self.method(:default_processor)
|
47
|
+
@default_get=self.method(:default_get_processor)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def strip_comments(str)
|
52
|
+
str.lstrip!
|
53
|
+
str.chomp!
|
54
|
+
|
55
|
+
tmp=""
|
56
|
+
escaped=false
|
57
|
+
quoted=false
|
58
|
+
endquote=''
|
59
|
+
|
60
|
+
str.each_char{|char|
|
61
|
+
if quoted
|
62
|
+
if char==endquote
|
63
|
+
quoted=false
|
64
|
+
tmp+=char
|
65
|
+
else
|
66
|
+
tmp+=char
|
67
|
+
end
|
68
|
+
elsif escaped
|
69
|
+
escaped=false
|
70
|
+
tmp+=char
|
71
|
+
elsif char=='\\'
|
72
|
+
escaped=true
|
73
|
+
tmp+=char
|
74
|
+
elsif char=='"' or char=="'"
|
75
|
+
quoted=true
|
76
|
+
case char
|
77
|
+
when "'" # single quote
|
78
|
+
endquote="'"
|
79
|
+
when '"' # double quote
|
80
|
+
endquote='"'
|
81
|
+
end
|
82
|
+
tmp+=char
|
83
|
+
elsif char=='#'
|
84
|
+
break
|
85
|
+
else
|
86
|
+
tmp+=char
|
87
|
+
end
|
88
|
+
}
|
89
|
+
|
90
|
+
tmp.chomp
|
91
|
+
end
|
92
|
+
|
93
|
+
# converts item to the appropriate data type if need be
|
94
|
+
# otherwise it returns item
|
95
|
+
def convert_or_parse(item)
|
96
|
+
return item if item.class==Fixnum
|
97
|
+
if item.to_i.to_s==item
|
98
|
+
return item.to_i
|
99
|
+
elsif item =~ /^"(.*?)"$/
|
100
|
+
text=Regexp.last_match(1)
|
101
|
+
return text
|
102
|
+
elsif item =~ /^\[(.*?)\]$/
|
103
|
+
array_s=Regexp.last_match(1)
|
104
|
+
array=safe_split(array_s,',')
|
105
|
+
results=array.collect do |i|
|
106
|
+
i.lstrip!
|
107
|
+
i.rstrip!
|
108
|
+
convert_or_parse(i)
|
109
|
+
end
|
110
|
+
return results
|
111
|
+
elsif item.class==String && (item.downcase=="true" || item.downcase=="false")
|
112
|
+
return true if item.downcase=="true"
|
113
|
+
return false
|
114
|
+
else
|
115
|
+
array=safe_split(item,',')
|
116
|
+
if !array.nil? && array.length<=1
|
117
|
+
return item
|
118
|
+
else
|
119
|
+
return array
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
#splits a line at boundaries defined by boundary.
|
125
|
+
def safe_split(line,boundary=nil)
|
126
|
+
debug(9,line,"line")
|
127
|
+
debug(9,boundary,"boundary")
|
128
|
+
|
129
|
+
return line if line.class!=String
|
130
|
+
|
131
|
+
items=[]
|
132
|
+
item=""
|
133
|
+
quoted=false
|
134
|
+
qchar=''
|
135
|
+
splitchar= boundary.nil? ? /\s/ : /#{boundary}/
|
136
|
+
escaped=false #used for when the escape character "\" is found
|
137
|
+
line.each_char do |char| # split up incoming line and account for item="stuff n stuff"
|
138
|
+
# p char
|
139
|
+
add_char=true # are we going to add this character?
|
140
|
+
|
141
|
+
if char=="\\" and !escaped
|
142
|
+
escaped=true # We've found an escape character which means add the next char'
|
143
|
+
next
|
144
|
+
end
|
145
|
+
|
146
|
+
# puts "char->#{char}, quoted->#{quoted}, qchar->#{qchar}, item->#{item}"
|
147
|
+
if (char !~ splitchar) && (!escaped || !quoted) # add the space if we're in a quoted string and not escaped
|
148
|
+
if !quoted # This block will group text found inside "" or []
|
149
|
+
if char=='"' # is the character a quote?
|
150
|
+
# puts "quote found"
|
151
|
+
qchar='"' # set our end quote character
|
152
|
+
quoted=true # set our mode to be quoted
|
153
|
+
# add_char=false # do not add this character
|
154
|
+
# elsif char=='('
|
155
|
+
# qchar=')'
|
156
|
+
# quoted=true
|
157
|
+
elsif char=='[' # is the character a open bracket?
|
158
|
+
qchar=']' # set our end quote character
|
159
|
+
quoted=true # enable quoted mode
|
160
|
+
end
|
161
|
+
else #quoted == false
|
162
|
+
if char==qchar # we have found our quote boundary
|
163
|
+
# puts "found quote"
|
164
|
+
quoted=false
|
165
|
+
# add_char=false if char=='"' # do not add the character if it is a quote character
|
166
|
+
end
|
167
|
+
end # end !quoted block
|
168
|
+
|
169
|
+
item<<char if add_char
|
170
|
+
# p item
|
171
|
+
|
172
|
+
elsif escaped || quoted # add the character since we're escaped'
|
173
|
+
item<<char
|
174
|
+
else # we have found our split boundary, add the item
|
175
|
+
items<<item if item.length>0
|
176
|
+
item=""
|
177
|
+
end # end (char!~splitchar or quoted) && !escaped
|
178
|
+
|
179
|
+
escaped=false # when we set escape to true we use next to skip the rest of the block
|
180
|
+
end
|
181
|
+
items<<item if item.length>0 # be sure not to forget the last element from the block
|
182
|
+
|
183
|
+
raise ParseError.new("Closing #{qchar} not found!") if quoted
|
184
|
+
|
185
|
+
items
|
186
|
+
end
|
187
|
+
|
188
|
+
# Params to hash breaks up an incoming line into individual elements.
|
189
|
+
# It's kinda messy, and could probably one day use some cleaning up
|
190
|
+
# The basic concept is it will return a hash based on what it finds.
|
191
|
+
# If it finds an = character it will make a hash out of the left and right
|
192
|
+
# if items are found inside quotes they will be treated as one unit
|
193
|
+
# If items are found individually (not quoted) it will be put in a hash as the
|
194
|
+
# left side with a value of true
|
195
|
+
#
|
196
|
+
# TODO this could use some cleanup.
|
197
|
+
def params_to_hash(line)
|
198
|
+
debug(6,line,"line")
|
199
|
+
params=safe_split(line)
|
200
|
+
debug(6,params,"After safe_split")
|
201
|
+
|
202
|
+
retval = {}
|
203
|
+
params.each do |item|
|
204
|
+
debug(9,item,"parsing")
|
205
|
+
item.lstrip!
|
206
|
+
item.chomp!
|
207
|
+
if item =~ /^(.*?)=(.*?)$/ then
|
208
|
+
lside=Regexp.last_match(1)
|
209
|
+
rside=convert_or_parse(Regexp.last_match(2))
|
210
|
+
if rside.class==Array #check to see if we have hashes inside the array
|
211
|
+
rside.collect! do |i|
|
212
|
+
if i =~ /\{(.*)\}/
|
213
|
+
params_to_hash(Regexp.last_match(1))
|
214
|
+
else
|
215
|
+
convert_or_parse(i)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
if lside =~ /^"(.*?)"$/
|
221
|
+
lside=Regexp.last_match(1)
|
222
|
+
end
|
223
|
+
|
224
|
+
if rside =~ /\{(.*)\}/
|
225
|
+
rside=params_to_hash(Regexp.last_match(1))
|
226
|
+
end
|
227
|
+
|
228
|
+
if rside =~ /\[(.*)\]/
|
229
|
+
Regexp.last_match(1)
|
230
|
+
rside=[params_to_hash(Regexp.last_match(1))]
|
231
|
+
end
|
232
|
+
|
233
|
+
retval.merge!(lside=>rside)
|
234
|
+
else
|
235
|
+
if item =~ /^"(.*?)"$/
|
236
|
+
item=Regexp.last_match(1)
|
237
|
+
end
|
238
|
+
retval.merge!(item=>true)
|
239
|
+
end
|
240
|
+
debug(9,retval,"parsed")
|
241
|
+
end
|
242
|
+
retval
|
243
|
+
end
|
244
|
+
|
245
|
+
#substitute_vars
|
246
|
+
#This function will substitute the variable tokens in the string args for the values in the global object
|
247
|
+
#GlobalVars
|
248
|
+
def substitute_vars(args)
|
249
|
+
|
250
|
+
#split breaks a string into an array of component pieces which makes it easier to perform substitutions
|
251
|
+
#in the present situation the component pieces are variables and non-variables.
|
252
|
+
#whitespace is preserved in this split process
|
253
|
+
def split(str)
|
254
|
+
return [] if str.nil? or str.empty?
|
255
|
+
#The function originally would split out quoted strings which would not be scanned
|
256
|
+
# if result=/\\["']/.match(str) # split out escaped quotes
|
257
|
+
# return split(result.pre_match) + [result[0]] + split(result.post_match)
|
258
|
+
# end
|
259
|
+
# if result=/((["'])[^"']+\2)/.match(str) #split out legitimately quoted strings
|
260
|
+
# return split(result.pre_match) + [result[0]] + split(result.post_match)
|
261
|
+
# end
|
262
|
+
# if result=/["']/.match(str) #split out dangling quotes
|
263
|
+
# return split(result.pre_match) + [result[0]] + split(result.post_match)
|
264
|
+
# end
|
265
|
+
# if result=/\s+/.match(str) #split on whitespace (this way we can preserve it)
|
266
|
+
# return split(result.pre_match) + [result[0]] + split(result.post_match)
|
267
|
+
# end
|
268
|
+
if result=/[\\]?\$[A-Za-z]\w*/.match(str) #split on variables
|
269
|
+
return split(result.pre_match) + [result[0]] + split(result.post_match)
|
270
|
+
end
|
271
|
+
return [str] #return what's left
|
272
|
+
end
|
273
|
+
|
274
|
+
# A variable is something that starts with a $ character followed by a letter then followed zero or more letters or
|
275
|
+
# numbers
|
276
|
+
# Variable substitution comes from the global singleton GlobalVars
|
277
|
+
def substitute(args)
|
278
|
+
args.map { |val|
|
279
|
+
if result=/^\$([A-Za-z]\w*)/.match(val)
|
280
|
+
GlobalVars.instance[result[1]]
|
281
|
+
else
|
282
|
+
val
|
283
|
+
end
|
284
|
+
}
|
285
|
+
end
|
286
|
+
|
287
|
+
#Removes the escaping on the $ character which is used to prevent variable substitution
|
288
|
+
def unescape(args)
|
289
|
+
args.gsub(/\\\$/, '$')
|
290
|
+
end
|
291
|
+
|
292
|
+
debug(2,args,"Pre substitution")
|
293
|
+
args=unescape(substitute(split(args)).join)
|
294
|
+
debug(2,args,"Post Substitution")
|
295
|
+
|
296
|
+
return args
|
297
|
+
end
|
298
|
+
|
299
|
+
def call_help(help_func)
|
300
|
+
help_func.call if !help_func.nil?
|
301
|
+
end
|
302
|
+
|
303
|
+
# The help processor just passes the args back in the api_params key
|
304
|
+
# Note, this is the only processor which does not process for variables.
|
305
|
+
def help_processor(help_func,valid_args,args,user_vars,*options)
|
306
|
+
args=substitute_vars(args)
|
307
|
+
{:api_params=>args, :show_params=>{}}
|
308
|
+
end
|
309
|
+
|
310
|
+
alias raw_processor help_processor
|
311
|
+
|
312
|
+
# The default helper process the "show=*" argument
|
313
|
+
# If there is a show argument "extendoutput" is sent to the API and the show argument is passed to the print routines
|
314
|
+
def default_helper(args)
|
315
|
+
debug(7,args,"default helper")
|
316
|
+
api_params = args
|
317
|
+
show_params = {}
|
318
|
+
if !args["show"].nil?
|
319
|
+
show_params={:show=>args["show"]}
|
320
|
+
api_params.delete("show")
|
321
|
+
api_params.merge({"extendoutput"=>true})
|
322
|
+
end
|
323
|
+
|
324
|
+
{:api_params=>api_params, :show_params=>show_params}
|
325
|
+
end
|
326
|
+
|
327
|
+
# This is the default Parameter processor. This is passed to the Command Tree object when it is instantiated
|
328
|
+
# The default processor also checks the incoming parameters against the a list of valid arguments, and merges
|
329
|
+
# the user variables with the inbound arguments with the inbound arguments taking precedence, raises an
|
330
|
+
# exception if there is an error
|
331
|
+
def default_processor(help_func,valid_args,args,user_vars,*options)
|
332
|
+
debug(7,args,"default argument processor")
|
333
|
+
|
334
|
+
args=substitute_vars(args)
|
335
|
+
args=params_to_hash(args)
|
336
|
+
if !(invalid=check_parameters(args, valid_args)).empty?
|
337
|
+
msg="Invalid parameters:\n"
|
338
|
+
msg+=invalid.join(", ")
|
339
|
+
raise ParameterError_Invalid.new(msg,:retry=>true, :help_func=>help_func)
|
340
|
+
end
|
341
|
+
|
342
|
+
valid_user_vars = {}
|
343
|
+
|
344
|
+
if !valid_args.nil?
|
345
|
+
valid_args.each {|item|
|
346
|
+
valid_user_vars[item]=user_vars[item] if !user_vars[item].nil?
|
347
|
+
}
|
348
|
+
end
|
349
|
+
args = valid_user_vars.merge(args)
|
350
|
+
|
351
|
+
default_helper(args)
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
# This processor does not do anything fancy. All items passed in via args are passed back in api_params
|
356
|
+
def simple_processor(help_func,valid_args,args,user_vars,*options)
|
357
|
+
debug(7,args,"default argument processor")
|
358
|
+
|
359
|
+
args=substitute_vars(args)
|
360
|
+
args=params_to_hash(args)
|
361
|
+
|
362
|
+
{:api_params=>args, :show_params=>{}}
|
363
|
+
end
|
364
|
+
|
365
|
+
# This is the default processor for get commands. It adds "limit" and "extendoutput" as needed
|
366
|
+
def default_get_processor(help_func, valid_args, args, user_vars, *options)
|
367
|
+
debug(7,args,"default get helper")
|
368
|
+
|
369
|
+
# let the default processor set things up
|
370
|
+
retval=default_processor(help_func,valid_args,args,user_vars,options)
|
371
|
+
|
372
|
+
if retval[:api_params]["limit"].nil?
|
373
|
+
retval[:api_params]["limit"]=100
|
374
|
+
end
|
375
|
+
if retval[:api_params]["show"].nil?
|
376
|
+
retval[:api_params]["extendoutput"]=true
|
377
|
+
end
|
378
|
+
|
379
|
+
retval
|
380
|
+
end
|
381
|
+
|
382
|
+
#Helper function to ensure the proper hash is returned
|
383
|
+
def return_helper(parameters,show_parameters=nil)
|
384
|
+
{:api_params=>parameters, :show_params=>show_parameters}
|
385
|
+
end
|
386
|
+
|
387
|
+
# Helper function the check for required parameters.
|
388
|
+
# Parameters is the hash of parameters from the user
|
389
|
+
# required_parameters is an array of parameters which are required
|
390
|
+
# returns an array of missing required items
|
391
|
+
# if the returned array is empty all required items found
|
392
|
+
def check_required(parameters,required_parameters)
|
393
|
+
r_params=required_parameters.clone # Arrays are pass by reference
|
394
|
+
parameters.keys.each{|key| r_params.delete(key)}
|
395
|
+
r_params
|
396
|
+
end
|
397
|
+
|
398
|
+
# Helper function to check the validity of the parameters from the user
|
399
|
+
# Parameters is the hash of parameters from the user
|
400
|
+
# valid_parameters is an array of parameters which are valid
|
401
|
+
# returns an array of invalid parameters
|
402
|
+
# if the returned array is empty all parameters are valid
|
403
|
+
def check_parameters(parameters,valid_parameters)
|
404
|
+
if !valid_parameters.nil?
|
405
|
+
keys=parameters.keys
|
406
|
+
valid_parameters.each {|key| keys.delete(key)}
|
407
|
+
return keys
|
408
|
+
else
|
409
|
+
return []
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
# hash_processor is a helper function which takes the incoming arguments
|
414
|
+
# and chunks them into a hash of pairs
|
415
|
+
# example:
|
416
|
+
# input: one two three four
|
417
|
+
# result: "one"=>"two", "three"=>"four"
|
418
|
+
# Exception will be raised when error found
|
419
|
+
# processor does not do variable substitution
|
420
|
+
# TODO: Consider removing function as it appears not be used
|
421
|
+
def hash_processor(help_func,valid_args,args,user_vars,*options)
|
422
|
+
debug(6,args,"Args")
|
423
|
+
debug(6,options,"Options")
|
424
|
+
items=safe_split(args)
|
425
|
+
if items.count % 2 == 0
|
426
|
+
rethash={}
|
427
|
+
while items.count!=0
|
428
|
+
rethash[items[0]]=items[1]
|
429
|
+
items.delete_at(0)
|
430
|
+
items.delete_at(0) #make sure we delete the first two items
|
431
|
+
end
|
432
|
+
return_helper(rethash)
|
433
|
+
else
|
434
|
+
msg="Invalid input\n"
|
435
|
+
msg+="Odd number of arguments found"
|
436
|
+
raise ParameterError.new(msg,:retry=>true)
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
# array_process is a helper function which takes the incoming arguments
|
441
|
+
# and puts them into an array and returns that result.
|
442
|
+
# empty input results in an empty array
|
443
|
+
# does not perform variable substitution
|
444
|
+
def array_processor(help_func,valid_args,args,user_vars,*options)
|
445
|
+
|
446
|
+
return_helper(safe_split(args))
|
447
|
+
end
|
448
|
+
|
449
|
+
##############################################################################################
|
450
|
+
# End of default and helper functions
|
451
|
+
##############################################################################################
|
452
|
+
|
453
|
+
def add_user(help_func,valid_args,args, user_vars, *options)
|
454
|
+
debug(4,args,"args")
|
455
|
+
|
456
|
+
if args.empty?
|
457
|
+
call_help(help_func)
|
458
|
+
raise ParameterError.new("No arguments",:retry=>true, :help_func=>help_func)
|
459
|
+
end
|
460
|
+
|
461
|
+
valid_parameters=['name', 'surname', 'alias', 'passwd', 'url', 'autologin',
|
462
|
+
'autologout', 'lang', 'theme', 'refresh', 'rows_per_page', 'type']
|
463
|
+
default_processor(help_func,valid_parameters,args,user_vars,options)
|
464
|
+
end
|
465
|
+
|
466
|
+
def add_host(help_func,valid_args,args,user_vars,*options)
|
467
|
+
debug(4,args,"args")
|
468
|
+
debug(4,options,"options")
|
469
|
+
|
470
|
+
if args.empty?
|
471
|
+
call_help(help_func)
|
472
|
+
return nil
|
473
|
+
end
|
474
|
+
|
475
|
+
#TODO, add the ability for both groups and groupids
|
476
|
+
|
477
|
+
valid_parameters=['host', 'groups', 'port', 'status', 'useip', 'dns', 'ip',
|
478
|
+
'proxy_hostid', 'useipmi', 'ipmi_ip', 'ipmi_port', 'ipmi_authtype',
|
479
|
+
'ipmi_privilege', 'ipmi_username', 'ipmi_password', 'templates']
|
480
|
+
|
481
|
+
parameters=default_processor(help_func,valid_parameters,args,user_vars,options)[:api_params]
|
482
|
+
|
483
|
+
required_parameters=[ 'host', 'groups' ]
|
484
|
+
|
485
|
+
# p required_parameters
|
486
|
+
# p parameters
|
487
|
+
|
488
|
+
# if !parameters["dns"].nil? and !required_parameters.find("ip")
|
489
|
+
# required_parameters.delete("ip")
|
490
|
+
# elsif !parameters["ip"].nil? and !required_parameters["dns"]
|
491
|
+
# required_parameters.delete("dns")
|
492
|
+
# end
|
493
|
+
|
494
|
+
if !(missing=check_required(parameters,required_parameters)).empty?
|
495
|
+
# if !required_parameters["ip"].nil? and !required_parameters["dns"].nil?
|
496
|
+
# puts "Missing parameter dns and/or ip"
|
497
|
+
# required_parameters["ip"].delete
|
498
|
+
# required_parameters["dns"].delete
|
499
|
+
# end
|
500
|
+
msg = "Required parameters missing\n"
|
501
|
+
msg += missing.join(", ")
|
502
|
+
|
503
|
+
raise ParameterError_Missing.new(msg,:retry=>true, :help_func=>help_func)
|
504
|
+
end
|
505
|
+
|
506
|
+
groups=convert_or_parse(parameters['groupids'])
|
507
|
+
if groups.class==Fixnum
|
508
|
+
parameters['groups']=[{"groupid"=>groups}]
|
509
|
+
end
|
510
|
+
|
511
|
+
return_helper(parameters)
|
512
|
+
end
|
513
|
+
|
514
|
+
def add_item_active(help_func,parameters,*options)
|
515
|
+
valid_parameters = ['hostid','description','key','delta','history','multiplier','value_type', 'data_type',
|
516
|
+
'units','delay','trends','status','valuemapid','applications']
|
517
|
+
required_parameters = ['hostid','description','key']
|
518
|
+
end
|
519
|
+
|
520
|
+
def add_item(help_func,valid_args,args,user_vars,*options)
|
521
|
+
debug(4,args,"args")
|
522
|
+
debug(4,options,"options")
|
523
|
+
debug(4,user_vars,"User Variables")
|
524
|
+
|
525
|
+
if args.empty?
|
526
|
+
call_help(help_func)
|
527
|
+
return nil
|
528
|
+
end
|
529
|
+
|
530
|
+
# Item types
|
531
|
+
# 0 Zabbix agent - Passive
|
532
|
+
# 1 SNMPv1 agent - SNMP
|
533
|
+
# 2 Zabbix trapper - Trapper
|
534
|
+
# 3 Simple check - Simple
|
535
|
+
# 4 SNMPv2 agent - SNMP2
|
536
|
+
# 5 Zabbix internal - Internal
|
537
|
+
# 6 SNMPv3 agent - SNMP3
|
538
|
+
# 7 Zabbix agent (active) - Active
|
539
|
+
# 8 Zabbix aggregate - Aggregate
|
540
|
+
# 10 External check - External
|
541
|
+
# 11 Database monitor - Database
|
542
|
+
# 12 IPMI agent - IPMI
|
543
|
+
# 13 SSH agent - SSH
|
544
|
+
# 14 TELNET agent - Telnet
|
545
|
+
# 15 Calculated - Calculated
|
546
|
+
|
547
|
+
#value types
|
548
|
+
# 0 Numeric (float)
|
549
|
+
# 1 Character
|
550
|
+
# 2 Log
|
551
|
+
# 3 Numeric (unsigned)
|
552
|
+
# 4 Text
|
553
|
+
|
554
|
+
# Data Types
|
555
|
+
# 0 Decimal
|
556
|
+
# 1 Octal
|
557
|
+
# 2 Hexadecimal
|
558
|
+
|
559
|
+
# Status Types
|
560
|
+
# 0 Active
|
561
|
+
# 1 Disabled
|
562
|
+
# 2 Not Supported
|
563
|
+
|
564
|
+
# Delta Types
|
565
|
+
# 0 As is
|
566
|
+
# 1 Delta (Speed per second)
|
567
|
+
# 2 Delta (simple change)
|
568
|
+
|
569
|
+
|
570
|
+
valid_parameters= ['hostid', 'snmpv3_securitylevel','snmp_community', 'publickey', 'delta', 'history', 'key_',
|
571
|
+
'key', 'snmp_oid', 'delay_flex', 'multiplier', 'delay', 'mtime', 'username', 'authtype',
|
572
|
+
'data_type', 'ipmi_sensor','snmpv3_authpassphrase', 'prevorgvalue', 'units', 'trends',
|
573
|
+
'snmp_port', 'formula', 'type', 'params', 'logtimefmt', 'snmpv3_securityname',
|
574
|
+
'trapper_hosts', 'description', 'password', 'snmpv3_privpassphrase',
|
575
|
+
'status', 'privatekey', 'valuemapid', 'templateid', 'value_type', 'groups']
|
576
|
+
|
577
|
+
parameters=default_processor(help_func,valid_parameters,args,user_vars,options)[:api_params]
|
578
|
+
|
579
|
+
# valid_user_vars = {}
|
580
|
+
#
|
581
|
+
# valid_parameters.each {|item|
|
582
|
+
# valid_user_vars[item]=user_vars[item] if !user_vars[item].nil?
|
583
|
+
# }
|
584
|
+
# p parameters
|
585
|
+
# p valid_user_vars
|
586
|
+
# parameters = valid_user_vars.merge(parameters)
|
587
|
+
# p parameters
|
588
|
+
|
589
|
+
required_parameters=[ 'type' ]
|
590
|
+
|
591
|
+
if parameters["type"].nil?
|
592
|
+
puts "Missing required parameter 'type'"
|
593
|
+
return nil
|
594
|
+
end
|
595
|
+
|
596
|
+
if !(invalid=check_parameters(parameters,valid_parameters)).empty?
|
597
|
+
puts "Invalid items"
|
598
|
+
puts invalid.join(", ")
|
599
|
+
return nil
|
600
|
+
end
|
601
|
+
|
602
|
+
case parameters["type"].downcase
|
603
|
+
when "passive"
|
604
|
+
parameters["type"]=0
|
605
|
+
required_parameters = ['hostid','description','key']
|
606
|
+
when "active"
|
607
|
+
parameters["type"]=7
|
608
|
+
required_parameters = ['hostid','description','key']
|
609
|
+
when "trapper"
|
610
|
+
parameters["type"]=2
|
611
|
+
required_parameters = ['hostid','description','key']
|
612
|
+
end
|
613
|
+
|
614
|
+
if !(missing=check_required(parameters,required_parameters)).empty?
|
615
|
+
puts "Required parameters missing"
|
616
|
+
|
617
|
+
puts missing.join(", ")
|
618
|
+
|
619
|
+
return nil
|
620
|
+
end
|
621
|
+
|
622
|
+
# perform some translations
|
623
|
+
|
624
|
+
parameters["key_"]=parameters["key"]
|
625
|
+
parameters.delete("key")
|
626
|
+
|
627
|
+
return_helper(parameters)
|
628
|
+
end
|
629
|
+
|
630
|
+
|
631
|
+
def delete_host(help_func,valid_args,args,user_vars,*options)
|
632
|
+
debug(6,args,"args")
|
633
|
+
|
634
|
+
args=default_processor(help_func,valid_args,args,user_vars,options)[:api_params]
|
635
|
+
|
636
|
+
if args["id"].nil?
|
637
|
+
puts "Missing parameter \"id\""
|
638
|
+
call_help(help_func)
|
639
|
+
return nil
|
640
|
+
end
|
641
|
+
|
642
|
+
return_helper(args["id"])
|
643
|
+
end
|
644
|
+
|
645
|
+
def delete_user(help_func,valid_args,args,user_vars,*options)
|
646
|
+
debug(6,args,"args")
|
647
|
+
if (args.split(" ").length>1) or (args.length==0)
|
648
|
+
raise ParameterError("Incorrect number of parameters",:retry=>true, :help_func=>help_func)
|
649
|
+
end
|
650
|
+
|
651
|
+
args=default_processor(help_func,valid_args,args,user_vars)[:api_params]
|
652
|
+
|
653
|
+
if !args["id"].nil?
|
654
|
+
return return_helper(args) if args["id"].class==Fixnum
|
655
|
+
puts "\"id\" must be a number"
|
656
|
+
call_help(help_func)
|
657
|
+
return nil
|
658
|
+
end
|
659
|
+
|
660
|
+
puts "Invalid arguments"
|
661
|
+
call_help(help_func)
|
662
|
+
return nil
|
663
|
+
|
664
|
+
end
|
665
|
+
|
666
|
+
#TODO: Document why this function does not use the default processor
|
667
|
+
def get_group_id(help_func,valid_args,args,user_vars,*options)
|
668
|
+
debug(4,valid_args,"valid_args")
|
669
|
+
debug(4,args,"args")
|
670
|
+
|
671
|
+
args=substitute_vars(args)
|
672
|
+
args=params_to_hash(args)
|
673
|
+
|
674
|
+
{:api_params=>args.keys, :show_params=>nil}
|
675
|
+
end
|
676
|
+
|
677
|
+
def get_user(help_func,valid_args,args,user_vars,*options)
|
678
|
+
debug(4,valid_args,"valid_args")
|
679
|
+
debug(4,args, "args")
|
680
|
+
|
681
|
+
retval=default_get_processor(help_func,valid_args,args,user_vars)
|
682
|
+
error=false
|
683
|
+
msg=''
|
684
|
+
|
685
|
+
if !retval[:show_params][:show].nil?
|
686
|
+
show_options=retval[:show_params][:show]
|
687
|
+
if !show_options.include?("all")
|
688
|
+
valid_show_options=['name','attempt_clock','theme','autologout','autologin','url','rows_per_page','attempt_ip',
|
689
|
+
'refresh','attempt_failed','type','userid','lang','alias','surname','passwd']
|
690
|
+
|
691
|
+
invalid_show_options=show_options-valid_show_options
|
692
|
+
|
693
|
+
if invalid_show_options.length!=0
|
694
|
+
error=true
|
695
|
+
msg = "Invalid show options: #{invalid_show_options}"
|
696
|
+
end
|
697
|
+
elsif show_options.length!=1
|
698
|
+
error=true
|
699
|
+
msg = "Show header option \"all\" cannot be included with other headers"
|
700
|
+
end
|
701
|
+
end
|
702
|
+
# raise ParameterError(msg,help_func) if error
|
703
|
+
|
704
|
+
return retval
|
705
|
+
end
|
706
|
+
|
707
|
+
#TODO: Use helper functions to make login more robust
|
708
|
+
def login(help_func,valid_args,args,user_vars,*options)
|
709
|
+
debug(4,args, "args")
|
710
|
+
args=args.split
|
711
|
+
if args.length!=3
|
712
|
+
call_help(help_func)
|
713
|
+
return nil
|
714
|
+
end
|
715
|
+
params={}
|
716
|
+
params[:server]=args[0]
|
717
|
+
params[:username]=args[1]
|
718
|
+
params[:password]=args[2]
|
719
|
+
return {:api_params=>params}
|
720
|
+
end
|
721
|
+
|
722
|
+
def raw_api(help_func,valid_args,args,user_vars,*options)
|
723
|
+
debug(7,args,"raw_api argument processor")
|
724
|
+
|
725
|
+
args=substitute_vars(args)
|
726
|
+
|
727
|
+
items=safe_split(args)
|
728
|
+
method=items[0]
|
729
|
+
items.delete_at(0)
|
730
|
+
args=items.join(" ")
|
731
|
+
args=params_to_hash(args)
|
732
|
+
args=nil if args=={}
|
733
|
+
|
734
|
+
{:api_params=>{:method=>method, :params=>args}, :show_params=>{}}
|
735
|
+
end
|
736
|
+
|
737
|
+
end
|
738
|
+
|
739
|
+
|
740
|
+
if __FILE__ == $0
|
741
|
+
|
742
|
+
#If we don't have the each_char method for the string class include the module that has it.
|
743
|
+
if !String.method_defined?("each_char")
|
744
|
+
require 'jcode'
|
745
|
+
end
|
746
|
+
|
747
|
+
require 'pp'
|
748
|
+
|
749
|
+
include ZDebug
|
750
|
+
set_debug_level(1)
|
751
|
+
arg_processor=ArgumentProcessor.new
|
752
|
+
|
753
|
+
p arg='i1=2 i2=item i3="this is a short sentence" i4="a string with a \" char"'
|
754
|
+
pp arg_processor.params_to_hash(arg),"----"
|
755
|
+
|
756
|
+
p arg='one=-2 two="" three=1,2 four=[1,2,three]'
|
757
|
+
pp arg_processor.params_to_hash(arg),"----"
|
758
|
+
|
759
|
+
p arg='hosts=[{hostid=10017}] name="zzz"'
|
760
|
+
pp arg_processor.params_to_hash(arg)
|
761
|
+
end
|
762
|
+
|
763
|
+
|
764
|
+
|
765
|
+
|
766
|
+
|
767
|
+
|
768
|
+
|