zabcon 0.0.1
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/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
|
+
|