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.
@@ -0,0 +1,106 @@
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: command_help.rb 258 2010-12-28 22:49:21Z nelsonab $
22
+ # $Revision: 258 $
23
+ ##########################################
24
+
25
+ require 'libs/zdebug'
26
+
27
+ require 'pp'
28
+ require 'rexml/document'
29
+
30
+ # CommandHelp is the class which behaves as a wrapper to the help text stored in a separate file.
31
+ # All help functions are dynamically generated by default. This is done through the lambda procedure
32
+ # in the method "method". The overloaded method "method" attempts to determine if the symbol passed
33
+ # in matches a pre-existing method. If it does not a local default lambda is created and returned.
34
+ class CommandHelp
35
+
36
+ include ZDebug
37
+
38
+ def initialize(language)
39
+ @file = File.new("libs/help.xml")
40
+
41
+ @doc=REXML::Document.new(@file).elements["//help[@language='#{language}']"]
42
+ # puts @doc.root.attributes
43
+
44
+ EnvVars.instance.register_notifier("language",self.method(:language=))
45
+ end
46
+
47
+ def language=(language)
48
+ @file.rewind
49
+ @doc=REXML::Document.new(@file).elements["//help[@language='#{language}']"]
50
+ end
51
+
52
+ alias o_method method
53
+
54
+ # This overloaded method returns a local lambda if the symbol passed in is not found
55
+ # The lambda behaves as a default help function looking up the passed in symbol in the help file
56
+ # If the command is found but no help exists, a message stating this is printed
57
+ def method(sym)
58
+ debug(8,sym,"CommandHelp.method overload (sym)")
59
+ methods=self.methods
60
+ index=methods.index(sym.to_s)
61
+ if !index.nil?
62
+ method_local=o_method(sym)
63
+ else
64
+ method_local=lambda do |not_used| #not_used is here due to zabcon_globals and callbacks.
65
+ debug(6, sym, "auto generated help func for")
66
+ item=@doc.elements["//item[@command='#{sym.to_s}']"]
67
+ if item.nil?
68
+ puts "Help not available for internal command: #{sym.to_s}"
69
+ else
70
+ puts item.text
71
+ end
72
+ end
73
+ end
74
+ debug(8,method_local,"returning")
75
+ method_local
76
+ end
77
+
78
+ def help(command_tree,input)
79
+ debug(6,command_tree.commands,"command_tree",350)
80
+ debug(6,input,"input")
81
+
82
+ items=input.split(" ")
83
+ if items.length==1
84
+ debug(6)
85
+
86
+ puts @doc.elements["//item[@command='help']"].text
87
+ else # more than "help" was typed by the user
88
+ items.delete("help")
89
+ help_cmd=items.join(" ").lstrip.chomp
90
+
91
+ if help_cmd=="commands"
92
+ puts @doc.elements["//item[@command='help_commands']"].text
93
+ else
94
+ debug(4,help_cmd,"Searching for help on")
95
+
96
+ cmd=command_tree.search(help_cmd)[0] #search returns an array
97
+
98
+ if !cmd.helpproc.nil?
99
+ cmd.helpproc.call(nil) #TODO: need to fix, see line 67 above
100
+ else
101
+ puts "Unable to find help for \"#{help_cmd}\""
102
+ end
103
+ end
104
+ end
105
+ end #def help
106
+ end
@@ -0,0 +1,307 @@
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: command_tree.rb 258 2010-12-28 22:49:21Z nelsonab $
22
+ # $Revision: 258 $
23
+ ##########################################
24
+
25
+ require 'libs/zdebug'
26
+ require 'libs/zabcon_exceptions'
27
+
28
+ class Parser
29
+
30
+ include ZDebug
31
+
32
+ attr_reader :commands
33
+
34
+ def initialize(default_argument_processor)
35
+ @commands=CommandTree.new("",nil,0,nil,nil,nil,nil)
36
+ @default_argument_processor=default_argument_processor
37
+ end
38
+
39
+ def strip_comments(str)
40
+ str.lstrip!
41
+ str.chomp!
42
+ if str =~ /^ ## .*/ then
43
+ str = ""
44
+ elsif str =~ /(.+) ## .*/ then
45
+ str = Regexp.last_match(1)
46
+ else
47
+ str
48
+ end
49
+ end
50
+
51
+ def search(str)
52
+ debug(7,str,"Searching")
53
+
54
+ str=strip_comments(str)
55
+
56
+ nodes = [""]+str.split
57
+
58
+ cmd_node=@commands.search(nodes) # a side effect of the function is that it also manipulates nodes
59
+ debug(7,cmd_node,"search result")
60
+ args=nodes.join(" ")
61
+
62
+ return cmd_node,args
63
+
64
+ end
65
+
66
+
67
+ # Returns nil if the command is incomplete or unknown
68
+ # If the command is known the associated argument processor is also called and it's results are returned as part
69
+ # of the return hash
70
+ # the return hash consists of:
71
+ # :proc - the name of the procedure which will execute the associated command
72
+ # :api_params - parameters to pass to the API call
73
+ # :show_params - parameters to pass to the print routines
74
+ # :helpproc - help procedure associated with the command
75
+ # The argument processor function is passed a string of the arguments after the command, along with the
76
+ # array of valid arguments and the help function associated with the command.
77
+ # If the argument processor has an error it should call the help function and return nil. In which case this function
78
+ # will return nil
79
+ def parse(str,user_vars=nil)
80
+ debug(7,str,"Parsing")
81
+ # options=
82
+ debug(7,user_vars,"User Variables")
83
+ cmd_node,args=search(str)
84
+
85
+ if cmd_node.commandproc.nil? then
86
+ raise ParseError.new("Parse error, incomplete/unknown command: #{str}",:retry=>true)
87
+ else
88
+ # The call here to the argument process requires one argument as it's a lambda block which is setup when the
89
+ # command node is created
90
+ debug(6,args,"calling argument processor")
91
+ args=cmd_node.argument_processor.call(args,user_vars)
92
+ debug(6,args,"received from argument processor")
93
+ retval = args.nil? ? nil : {:proc=>cmd_node.commandproc, :helpproc=>cmd_node.helpproc, :options=>cmd_node.options}.merge(args)
94
+ return retval
95
+ end
96
+ end
97
+
98
+ def complete(str,loggedin=false)
99
+ nodes = str.split
100
+ cmd_node=@commands
101
+ i=0
102
+ while i<nodes.length
103
+ tmp=cmd_node.search(nodes[i])
104
+ break if tmp.nil?
105
+ cmd_node=tmp
106
+ i+=1
107
+ end
108
+
109
+ if cmd_node.commandproc.nil? then
110
+ # roll up the list of available commands.
111
+ commands = cmd_node.children.collect {|node| node.command}
112
+
113
+ # don't include the current node if the command is empty
114
+ if cmd_node.command!="" then commands += [cmd_node.command] end
115
+ return commands
116
+ else
117
+ puts "complete"
118
+ return nil
119
+ end
120
+ end
121
+
122
+ def insert(insert_path,command,commandproc,arguments=[],helpproc=nil,argument_processor=nil,*options)
123
+ debug(10,{"insert_path"=>insert_path, "command"=>command, "commandproc"=>commandproc, "arguments"=> arguments, "helpproc"=>helpproc, "argument_processor"=>argument_processor, "options"=>options})
124
+ insert_path_arr=[""]+insert_path.split # we must pre-load our array with a blank node at the front
125
+ # p insert_path_arr
126
+
127
+ # If the parameter "argument_processor" is nil use the default argument processor
128
+ arg_processor = argument_processor.nil? ? @default_argument_processor : argument_processor
129
+ @commands.insert(insert_path_arr,command,commandproc,arguments,helpproc,arg_processor,options)
130
+ end
131
+
132
+ end
133
+
134
+
135
+ class CommandTree
136
+
137
+ include ZDebug
138
+
139
+ attr_reader :command, :commandproc, :children, :arguments, :helpproc, :depth, :argument_processor, :options
140
+
141
+ # Arguments hash takes the form of {"name"=>{:type=>Class, :optional=>true/false}}
142
+ # If type is nil then the argument takes no options
143
+ def initialize(command,commandproc,depth,arguments,helpproc,argument_processor,options)
144
+ debug(10,{"command"=>command, "commandproc"=>commandproc, "arguments"=> arguments,"helpproc"=>helpproc,
145
+ "verify_func"=>argument_processor, "depth"=>depth, "options"=>options})
146
+ @command=command
147
+ @commandproc=commandproc
148
+ @children=[]
149
+ @arguments=arguments
150
+ @helpproc=helpproc
151
+ @depth=depth
152
+ # verify functions are special.
153
+ # We pass them the list of valid arguments first and then the parameters which need to be verified
154
+ # This will allow for either unique or generalized verification functions
155
+ # The verify function can safely be called with objects with no verify function as nil checking is performed in the
156
+ # lambda
157
+ # If no verify function was setup we return true
158
+ @argument_processor=lambda do |params,user_vars|
159
+ if argument_processor.nil?
160
+ nil
161
+ else
162
+ argument_processor.call(@helpproc,@arguments,params,user_vars,options) # We pass the list of valid arguments to
163
+ end
164
+ end
165
+ if options.nil?
166
+ @options=nil
167
+ else
168
+ @options = Hash[*options.collect { |v|
169
+ [v, true]
170
+ }.flatten]
171
+ end
172
+ debug(10,self.inspect,"Initialization complete")
173
+ end
174
+
175
+ def inspect
176
+ r_str ="#<#{self.class.to_s}:0x#{self.object_id.to_s(16)} @command=#{@command.inspect}, @commandproc=#{@commandproc.inspect}, "
177
+ r_str+="@helpproc=#{@helpproc.inspect}, @argument_processor=#{@argument_processor.inspect}, @arguments=#{@arguments.inspect}, "
178
+ r_str+="@options=#{@options.inspect}, "
179
+ r_str+="@depth=#{@depth}, @children="
180
+ if @children.empty?
181
+ r_str+= "[]"
182
+ else
183
+ children=@children.map {|child| child.command }
184
+ r_str+= children.inspect
185
+ end
186
+ r_str+=">"
187
+ r_str
188
+ end
189
+
190
+ # search will search check to see if the parameter command is found in the current node
191
+ # or the immediate children nodes. It does not search the tree beyond one level.
192
+ # The loggedin argument is used to differentiate searching for commands which require a valid
193
+ # login or not. If loggedin is false it will return commands which do not require a valid login.
194
+ def search(search_path)
195
+ debug(10,search_path,"search_path")
196
+ debug(10,self,"self",300)
197
+
198
+ return nil if search_path.nil?
199
+ return nil if search_path.empty?
200
+
201
+ retval=nil
202
+
203
+ retval=self if search_path[0]==@command
204
+
205
+
206
+ search_path.shift
207
+ debug(10,search_path, "shifted search path")
208
+
209
+ return retval if search_path.length==0
210
+
211
+ # p search_path
212
+ # p @children.map {|child| child.command}
213
+ debug(10,@children.map{|child| child.command},"Current children")
214
+
215
+ results=@children.map {|child| child.command==search_path[0] ? child : nil }
216
+ results.compact!
217
+ debug(10,results,"Children search results",200)
218
+ return retval if results.empty? # no more children to search, return retval which may be self or nil, see logic above
219
+ debug(10)
220
+
221
+ return results[0].search(search_path)
222
+ debug(10,"Not digging deeper")
223
+
224
+ return self if search_path[0]==@command
225
+
226
+ end
227
+
228
+ def insert(insert_path,command,commandproc,arguments,helpproc,argument_processor,options)
229
+ do_insert(insert_path,command,commandproc,arguments,helpproc,argument_processor,options,0)
230
+ end
231
+
232
+ # Insert path is the path to insert the item into the tree
233
+ # Insert path is passed in as an array of names which associate with pre-existing nodes
234
+ # The function will recursively insert the command and will remove the top of the input path stack at each level until it
235
+ # finds the appropraite level. If the appropriate level is never found an exception is raised.
236
+ def do_insert(insert_path,command,commandproc,arguments,helpproc,argument_processor,options,depth)
237
+ debug(11,{"insert_path"=>insert_path, "command"=>command, "commandproc"=>commandproc, "arguments"=> arguments,
238
+ "helpproc"=>helpproc, "verify_func"=>argument_processor, "depth"=>depth})
239
+ debug(11,@command,"self.command")
240
+ # debug(11,@children.map {|child| child.command},"children")
241
+
242
+ if insert_path[0]==@command then
243
+ debug(11,"Found node")
244
+ if insert_path.length==1 then
245
+ debug(11,command,"inserting")
246
+ @children << CommandTree.new(command,commandproc,depth+1,arguments,helpproc,argument_processor,options)
247
+ else
248
+ debug(11,"Not found walking tree")
249
+ insert_path.shift
250
+ if !@children.empty? then
251
+ @children.each { |node| node.do_insert(insert_path,command,commandproc,arguments,helpproc,argument_processor,options,depth+1)}
252
+ else
253
+ raise(Command_Tree_Exception,"Unable to find insert point in Command Tree")
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ end
260
+
261
+
262
+ if __FILE__ == $0
263
+
264
+ require 'pp'
265
+ require 'argument_processor'
266
+
267
+ arg_processor=ArgumentProcessor.new()
268
+ commands=Parser.new(arg_processoor.method(:default))
269
+ commands.set_debug_level(6)
270
+
271
+
272
+ def test_parse(cmd)
273
+ puts "\ntesting \"#{cmd}\""
274
+ retval=commands.parse(cmd)
275
+ puts "result:"
276
+ return retval
277
+ end
278
+ commands.set_debug_level(0)
279
+ commands.insert "", "help", lambda { puts "This is a generic help stub" }
280
+ puts
281
+ commands.insert "", "get", nil
282
+ puts
283
+ commands.insert "get", "host", :gethost, {"show"=>{:type=>nil,:optional=>true}}
284
+ commands.set_debug_level(0)
285
+ puts
286
+ commands.insert "get", "user", :getuser
287
+ puts
288
+ commands.insert "get user", "group", :getusergroup
289
+ puts
290
+
291
+ pp commands
292
+
293
+ commands.set_debug_level(0)
294
+
295
+ test_parse("get user")
296
+ test_parse("get user show=all arg1 arg2")
297
+ test_parse("get user show=\"id, one, two, three\" arg1 arg2")
298
+ test_parse("get user group show=all arg1")
299
+ test_parse("set value")
300
+ test_parse("help")[:proc].call
301
+
302
+
303
+ p commands.complete("hel")
304
+ p commands.complete("help")
305
+ p commands.complete("get user all")
306
+
307
+ end
data/libs/defines.rb ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #GPL 2.0 http://www.gnu.org/licenses/gpl-2.0.html
4
+ #Zabbix CLI Tool and associated files
5
+ #Copyright (C) 2009,2010 Andrew Nelson nelsonab(at)red-tux(dot)net
6
+ #
7
+ #This program is free software; you can redistribute it and/or
8
+ #modify it under the terms of the GNU General Public License
9
+ #as published by the Free Software Foundation; either version 2
10
+ #of the License, or (at your option) any later version.
11
+ #
12
+ #This program is distributed in the hope that it will be useful,
13
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ #GNU General Public License for more details.
16
+ #
17
+ #You should have received a copy of the GNU General Public License
18
+ #along with this program; if not, write to the Free Software
19
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
+
21
+ ##########################################
22
+ # Subversion information
23
+ # $Id: defines.rb 215 2010-09-25 21:22:37Z richlv $
24
+ # $Revision: 215 $
25
+ ##########################################
26
+
27
+ # Zabbix constants
28
+
29
+ # Sysmap elements (Create Element Type drop down menu):
30
+ ME_HOST=0
31
+ ME_MAP=1
32
+ ME_TRIGGER=2
33
+ ME_HOSTGROUP=3
34
+ ME_IMAGE=4
35
+
36
+ # Sysmap connection draw type
37
+ MC_DT_LINE=1
38
+ MC_DT_BOLD=2
39
+ MC_DT_DOT=3
40
+ MC_DT_DASHED=4
41
+
42
+ # Sysmap label location
43
+ ML_BOTTOM=0
44
+ ML_LEFT=1
45
+ ML_RIGHT=2
46
+ ML_TOP=3