zabcon 0.0.370 → 0.0.392

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.
@@ -20,8 +20,8 @@
20
20
 
21
21
  ##########################################
22
22
  # Subversion information
23
- # $Id: zabcon_core.rb 370 2011-12-22 05:51:45Z nelsonab $
24
- # $Revision: 370 $
23
+ # $Id: zabcon_core.rb 384 2012-04-23 04:50:17Z nelsonab $
24
+ # $Revision: 384 $
25
25
  ##########################################
26
26
 
27
27
  #require 'libs/utility_items'
@@ -58,38 +58,8 @@ class ZabconCore
58
58
  debug(5,:msg=>"Setting up help")
59
59
  CommandHelp.setup("english")
60
60
 
61
- #TODO Remove reference to ArgumentProcessor when new command objects in use
62
- debug(5,:msg=>"Setting up ArgumentProcessor")
63
-
64
- loaded_session=false
65
- begin
66
- if !env["server"].nil? && !env["session_file"].nil? &&
67
- !env["session_file"].empty?
68
- path=File.expand_path(env["session_file"])
69
- puts "Attempting to load previous session key from #{env["session_file"]}" if env["echo"]
70
- yaml=YAML::load(File.open(path))
71
- loaded_session=ZabbixServer.instance.use_auth(yaml["auth"])
72
- puts "#{env["server"]} connected" if env["echo"]
73
- puts "API Version: #{ZabbixServer.instance.version}" if env["echo"]
74
- end
75
- rescue Errno::ENOENT
76
- puts "Failed to load previous session key" if env["echo"]
77
- rescue ZbxAPI_ExceptionLoginPermission
78
- puts "Failed to load previous session key" if env["echo"]
79
- end
80
-
81
- if !loaded_session && !env["server"].nil? &&
82
- !env["username"].nil? && !env["password"].nil?
83
- puts "Found valid login credentials, attempting login" if env["echo"]
84
- begin
85
- ZabbixServer.instance.login
86
-
87
- rescue ZbxAPI_ExceptionBadAuth => e
88
- puts e.message
89
- rescue ZbxAPI_ExceptionLoginPermission
90
- puts "Error Invalid login or no API permissions."
91
- end
92
- end
61
+ server_login unless env["no_login"]
62
+ env.delete("no_login") if env["no_login"]
93
63
 
94
64
  debug(5,:msg=>"Setting up prompt")
95
65
  @debug_prompt=false
@@ -166,6 +136,58 @@ class ZabconCore
166
136
  debug(5,:msg=>"Setup complete")
167
137
  end
168
138
 
139
+ #TODO clean up and streamline with multiple server capabilities
140
+ def server_login
141
+ loaded_session=false
142
+ begin
143
+ if !env["session_file"].nil? && !env["session_file"].empty?
144
+ path=File.expand_path(env["session_file"])
145
+ # puts "Attempting to load previous session keys from #{env["session_file"]}" if env["echo"]
146
+ yaml=YAML::load(File.open(path))
147
+ if yaml["auth"]
148
+ yaml["auth"].each {|k,v|
149
+ if v.nil? #cleanup for old auth file
150
+ k="global"
151
+ v=k
152
+ end
153
+ ServerCredentials.instance[k]["auth"]=v
154
+ }
155
+ end
156
+ credentials=ServerCredentials.instance[env["default_server"]]
157
+ if credentials["auth"]
158
+ puts "Attempting to use previous key" if env["echo"]
159
+ loaded_session=ZabbixServer.instance.use_auth(credentials)
160
+ puts "#{env["server"]} connected" if env["echo"]
161
+ puts "API Version: #{ZabbixServer.instance.version}" if env["echo"]
162
+ end
163
+ end
164
+ rescue Errno::ECONNREFUSED, Errno::ENOENT, ZbxAPI_ExceptionLoginPermission
165
+ puts "Failed to load previous session key" if env["echo"]
166
+ # return
167
+ end
168
+
169
+
170
+ credentials=ServerCredentials.instance[env["default_server"]] if credentials.nil?
171
+
172
+ if !loaded_session && !credentials["server"].nil? &&
173
+ !credentials["username"].nil? && !credentials["password"].nil?
174
+ puts "Found valid login credentials, attempting login" if env["echo"]
175
+ begin
176
+
177
+ #
178
+ ZabbixServer.instance.login(credentials)
179
+
180
+ rescue ZbxAPI_ExceptionBadAuth => e
181
+ puts e.message
182
+ rescue ZbxAPI_ExceptionLoginPermission
183
+ puts "Error Invalid login or no API permissions."
184
+ rescue ZbxAPI_ExceptionBadServerUrl
185
+ puts "Error connecting to server" #TODO Fix message to show hostname
186
+ end
187
+ end
188
+
189
+ end
190
+
169
191
  def load_command_path(path,base_path=nil,show_load=nil)
170
192
  base_path||="~"
171
193
  load_path=nil
@@ -216,7 +238,28 @@ class ZabconCore
216
238
  #tokens=ExpressionTokenizer.new(line)
217
239
  tokens=CommandTokenizer.new(line)
218
240
 
219
- tokens.delete_if {|item| item.kind==:comment }
241
+ # tokens.delete_if {|item| item.kind==:comment }
242
+ tokens.map!{|item|
243
+ case item.kind
244
+ when :comment
245
+ item=nil
246
+ when :variable
247
+ var_name=item.value[1..-1]
248
+ if var_name=="auth"
249
+ item.set_value(ServerCredentials.instance[env["default_server"]]["auth"])
250
+ elsif env[var_name]
251
+ item.set_value(env[var_name])
252
+ elsif vars[var_name]
253
+ item.set_value(vars[var_name])
254
+ else
255
+ raise ZbxAPI_ParameterError.new("Unknown Variable #{item.value}")
256
+ end
257
+ item
258
+ else
259
+ item
260
+ end
261
+ }.compact!
262
+
220
263
  next if tokens.nil? || tokens.first.kind==:end ||
221
264
  (tokens.first.kind==:whitespace && tokens[1].kind==:end)
222
265
  debug(6, :var=>line, :msg=>"Input from user")
@@ -292,6 +335,7 @@ class ZabconCore
292
335
  end
293
336
 
294
337
  #
338
+ # TODO: Fix XML Import capability to work again.
295
339
  # Import config from an XML file:
296
340
  #
297
341
  def do_import(input)
@@ -18,8 +18,8 @@
18
18
 
19
19
  ##########################################
20
20
  # Subversion information
21
- # $Id: zabcon_globals.rb 325 2011-09-26 08:57:00Z nelsonab $
22
- # $Revision: 325 $
21
+ # $Id: zabcon_globals.rb 372 2011-12-22 08:49:30Z nelsonab $
22
+ # $Revision: 372 $
23
23
  ##########################################
24
24
 
25
25
  #------------------------------------------------------------------------------
@@ -34,6 +34,7 @@ require 'zbxapi/zdebug'
34
34
 
35
35
  require 'singleton'
36
36
  require 'parseconfig'
37
+ require 'pp'
37
38
 
38
39
  #This class is for containing responses from the Command tree
39
40
  class Response
@@ -101,6 +102,10 @@ class GlobalsBase
101
102
  end
102
103
  end
103
104
 
105
+ def select_keys(keys)
106
+ @hash.select_keys(keys)
107
+ end
108
+
104
109
  def delete(key)
105
110
  @hash.delete(key)
106
111
  end
@@ -132,123 +137,14 @@ class GlobalVars < GlobalsBase
132
137
 
133
138
  end
134
139
 
135
- class EnvVars < GlobalsBase
136
-
137
- class NoConfig < Exception
138
- end
139
-
140
+ class ServerCredentials < GlobalsBase
140
141
  def initialize
141
142
  super()
142
143
  end
144
+ end
143
145
 
144
- #overrides is a hash of options which will override what is found in the config file.
145
- #useful for command line options.
146
- #if there is a hash called "config_file" this will override the default config file.
147
- def load_config(overrides={})
148
- begin
149
- config_file = overrides["config_file"].nil? ? self["config_file"] : overrides["config_file"]
150
-
151
- if config_file==:default
152
- home_default=File::expand_path("~/zabcon.conf")
153
- if File::exists?("zabcon.conf")
154
- config_file="zabcon.conf"
155
- elsif File::exists?(home_default)
156
- config_file=home_default
157
- self["config_file"]=home_default
158
- else
159
- raise NoConfig
160
- end
161
- end
162
-
163
- config = overrides["load_config"]==false ? # nil != false
164
- {} : ParseConfig.new(config_file).params
165
-
166
-
167
- # If we are not loading the config use an empty hash
168
- rescue Errno::EACCES
169
- if !(config_file=="zabcon.conf" and !File::exists?(config_file))
170
- puts "Unable to access configuration file: #{config_file}"
171
- end
172
- config={}
173
- rescue NoConfig
174
- puts "Unable to find a default configuration file"
175
- config={}
176
- end
177
-
178
- config.merge!(overrides) # merge the two option sets together but give precedence
179
- # to command line options
180
-
181
- config.each_pair { |k,v|
182
- self[k]=v
183
- }
184
-
185
-
186
- # debug(6,params)
187
- #
188
- # #Setup a local OpenStruct to copy potentially passed in OpenStruct
189
- # #rather than query every time weather or not params is an OpenStruct
190
- # localoptions=OpenStruct.new
191
- #
192
- # env=EnvVars.instance # Instantiate the global EnvVars
193
- #
194
- # if params.nil? or params.empty? # nil or empty, use conffile
195
- # fname=@conffile
196
- # elsif params.class==OpenStruct # use OpenStruct value or conffile
197
- # if params.configfile.nil?
198
- # fname=@conffile
199
- # else
200
- # fname=params.configfile
201
- # localoptions=params # Since we have an OpenStruct passed in let's setup
202
- # # our local OpenStruct variable for use later
203
- # end
204
- # elsif params.class==Hash # use Hash[:filename] or raise an exception
205
- # if params[:filename].nil?
206
- # raise ZabconError.new("Expected a hash with the key 'filename'")
207
- # else
208
- # fname=params[:filename]
209
- # end
210
- # else # If we get here something went wrong.
211
- # raise ZabconError.new("OH NO!!! Received something unexpected in do_load_config. Try again with debug level 6.")
212
- # end
213
- #
214
- # begin
215
- # config=ParseConfig.new(fname).params
216
- # debug(1,config)
217
- #
218
- # if !config["debug"].nil?
219
- # # If the command line option debug was not passed in use the config file
220
- # env["debug"]=config["debug"].to_i if localoptions.debug.nil?
221
- # end
222
- #
223
- # if !config["server"].nil? and !config["username"].nil? and !config["password"].nil? then
224
- # do_login({:server=>config["server"], :username=>config["username"],:password=>config["password"]})
225
- # else
226
- # puts "Missing one of the following, server, username or password or bad syntax"
227
- # end
228
- #
229
- # if !config["lines"].nil?
230
- # env["sheight"]=config["lines"].to_i
231
- # end
232
- #
233
- # if !config["language"].nil?
234
- # env["language"]=config["language"]
235
- # end
236
- #
237
- # rescue Errno::EACCES
238
- # puts "Unable to open file #{fname}"
239
- # rescue ZbxAPI_GeneralError => e
240
- # puts "An error was received from the Zabbix server"
241
- # if e.message.class==Hash
242
- # puts "Error code: #{e.message["code"]}"
243
- # puts "Error message: #{e.message["message"]}"
244
- # puts "Error data: #{e.message["data"]}"
245
- # retry
246
- # else
247
- # puts "Error: #{e.message}"
248
- # e.attempt_retry
249
- # end
250
- # end
146
+ class EnvVars < GlobalsBase
147
+ def initialize
148
+ super()
251
149
  end
252
-
253
-
254
150
  end
@@ -1,6 +1,7 @@
1
- server=http://localhost
2
- username=Admin
3
- password=zabbix
1
+ #Uncomment the following to enable automatic server login
2
+ #server=http://localhost
3
+ #username=Admin
4
+ #password=zabbix
4
5
 
5
6
  #Use the following to enable proxy server support
6
7
  #Only "proxy_server" is required to enable proxy support
@@ -10,6 +11,27 @@ password=zabbix
10
11
  #proxy_user=
11
12
  #proxy_password=
12
13
 
14
+ #It is possible to define "named" servers and log into them individually
15
+ #Named servers do not inherit any values from the global default server,
16
+ #and will not be logged into at startup by default.
17
+ #The syntax is a follows:
18
+ #server[name][parameter]=value
19
+ #"global" is reserved and cannot be used in the config file
20
+ #The string "server" is required, and will not be part of the server name
21
+ #in Zabcon. At a minimum values are required for server,username and password
22
+ #The following example would be referenced as "colo1" in Zabcon
23
+ #server[colo1][server]=http://zabbix.example.com/zabbix
24
+ #server[colo1][username]=Admin
25
+ #server[colo1][password]=zabbix
26
+ #server[colo1][proxy_server]=localhost
27
+ #server[colo1][proxy_port]=3128
28
+ #server[colo1][proxy_user]=user_proxy
29
+ #server[colo1][proxy_password]=password
30
+
31
+ #Which server will zabcon log into by default?
32
+ #The gloabl keyword denotes the default unnamed server options above.
33
+ #default_server=global
34
+
13
35
  # The following is a list of user editable config file options, the following
14
36
  # values are the defaults. These can be changed as needed.
15
37
 
data/zabcon.rb CHANGED
@@ -20,8 +20,8 @@
20
20
 
21
21
  ##########################################
22
22
  # Subversion information
23
- # $Id: zabcon.rb 370 2011-12-22 05:51:45Z nelsonab $
24
- # $Revision: 370 $
23
+ # $Id: zabcon.rb 388 2012-04-23 07:45:29Z nelsonab $
24
+ # $Revision: 388 $
25
25
  ##########################################
26
26
 
27
27
  #setup our search path or libraries
@@ -42,45 +42,31 @@ DEPENDENCIES={
42
42
  "parseconfig"=>true,
43
43
  "json"=>true,
44
44
  "highline"=>true,
45
- "zbxapi"=>Gem::Version.new("0.1.369")
45
+ "zbxapi"=>Gem::Version.new("0.1.386")
46
46
  }
47
47
 
48
-
49
- required_rev=REQUIRED_RUBY_VER.split('.')
50
- ruby_rev=RUBY_VERSION.split('.')
51
- items=ruby_rev.length < required_rev.length ? ruby_rev.length : required_rev.length
52
-
53
- for i in 0..items-1 do
54
- if ruby_rev[i].to_i<required_rev[i].to_i
55
- puts
56
- puts "Zabcon requires Ruby version #{required_rev.join('.')} or higher."
57
- puts "you are using Ruby version #{RUBY_VERSION}."
58
- puts
59
- exit(1)
60
- end
61
- #If this step is higher than the required version break out of loop
62
- break if ruby_rev[i].to_i>required_rev[i].to_i
48
+ if Gem::Version.create(RUBY_VERSION) < Gem::Version.create(REQUIRED_RUBY_VER)
49
+ puts "Zabcon requires Ruby version #{REQUIRED_RUBY_VER} or higher."
50
+ puts "you are using Ruby version #{RUBY_VERSION}."
51
+ puts
52
+ exit(1)
63
53
  end
64
54
 
65
-
66
55
  depsok=true #assume we will not fail dependencies
67
56
 
68
- DEPENDENCIES.each_key {|dep|
69
- gem=Gem.source_index.find_name(dep)
70
- if gem.empty?
71
- puts " #{dep} : Not Installed"
57
+ DEPENDENCIES.each do |pkg,ver|
58
+ begin
59
+ require pkg
60
+ if ver.is_a?(Gem::Version) && Gem.loaded_specs[pkg].version<ver
61
+ depsok=false
62
+ puts "Error: '#{pkg}' must be at least version #{ver.to_s} or higher, #{Gem.loaded_specs[pkg].version.to_s} installed"
63
+ end
64
+ rescue LoadError
72
65
  depsok=false
73
- break
66
+ puts "Error: '#{pkg}' is a missing required dependency"
74
67
  end
75
- gem.sort!{ |a,b| a.version <=> b.version }
76
- depsok=depsok && !gem.map { |g|
77
- if DEPENDENCIES[dep].class==Gem::Version && g.version<DEPENDENCIES[dep]
78
- "#{dep} needs to be at least version #{DEPENDENCIES[dep]}, found #{g.version}"
79
- else
68
+ end
80
69
 
81
- end
82
- }.delete_if {|i| i==false}.empty?
83
- }
84
70
  if !depsok
85
71
  puts
86
72
  puts "One or more dependencies failed"
@@ -97,19 +83,23 @@ require 'ostruct'
97
83
  require 'strscan'
98
84
  require 'zbxapi/zdebug'
99
85
  require 'libs/zabcon_globals'
100
-
101
- if RUBY_VERSION=="1.8.6" #Ruby 1.8.6 lacks the each_char function in the string object, so we add it here
102
- String.class_eval do
103
- def each_char
104
- if block_given?
105
- scan(/./m) do |x|
106
- yield x
86
+ require 'parseconfig'
87
+
88
+ #Make any changes to base classes which are version specific
89
+ case Gem::Version.create(RUBY_VERSION)
90
+ when Gem::Version.create("1.8.6")
91
+ #Ruby 1.8.6 lacks the each_char function in the string object, so we add it here
92
+ String.class_eval do
93
+ def each_char
94
+ if block_given?
95
+ scan(/./m) do |x|
96
+ yield x
97
+ end
98
+ else
99
+ scan(/./m)
107
100
  end
108
- else
109
- scan(/./m)
110
101
  end
111
102
  end
112
- end
113
103
  end
114
104
 
115
105
  class ZabconApp
@@ -141,6 +131,12 @@ class ZabconApp
141
131
  "./zabcon.conf, ~/zabcon.conf in that","order") do |file|
142
132
  @cmd_opts.config_file=file
143
133
  end
134
+ opts.on("--no-login", "Do not automaticly log into Zabbix server on startup") do
135
+ @cmd_opts.no_login=true
136
+ end
137
+ opts.on("-S","--use-server SERVER","Log into the named server from the config file on startup") do |server|
138
+ @cmd_opts.default_server=server
139
+ end
144
140
  opts.on("--no-config", "Do not attempt to automatically load","the configuration file") do
145
141
  @cmd_opts.load_config=false
146
142
  end
@@ -189,6 +185,7 @@ class ZabconApp
189
185
  env["truncate_length"]=5000
190
186
  env["custom_commands"]=nil
191
187
  env["session_file"]="~/zabcon.session"
188
+ env["default_server"]="global"
192
189
 
193
190
  #output related environment variables
194
191
  env["table_output"]=STDIN.tty? # Is the output a well formatted table, or csv like?
@@ -196,6 +193,71 @@ class ZabconApp
196
193
  env["table_separator"]=","
197
194
 
198
195
  end
196
+ #overrides is a hash of options which will override what is found in the config file.
197
+ #useful for command line options.
198
+ #if there is a hash called "config_file" this will override the default config file.
199
+ def load_config(overrides={})
200
+ begin
201
+ config_file = overrides["config_file"] || env["config_file"]
202
+
203
+ if config_file==:default
204
+ home_default=File::expand_path("~/zabcon.conf")
205
+ if File::exists?("zabcon.conf")
206
+ config_file="zabcon.conf"
207
+ elsif File::exists?(home_default)
208
+ config_file=home_default
209
+ env["config_file"]=home_default
210
+ else
211
+ raise "NoConfig"
212
+ end
213
+ end
214
+
215
+ config = overrides["load_config"]==false ? # nil != false
216
+ {} : ParseConfig.new(config_file).params
217
+
218
+ # If we are not loading the config use an empty hash
219
+ rescue Errno::EACCES
220
+ if !(config_file=="zabcon.conf" and !File::exists?(config_file))
221
+ puts "Unable to access configuration file: #{config_file}"
222
+ end
223
+ config={}
224
+ rescue RuntimeError=>e
225
+ if e.message=="NoConfig"
226
+ puts "Unable to find a default configuration file"
227
+ config={}
228
+ else
229
+ raise e
230
+ end
231
+ end
232
+
233
+ config.merge!(overrides) # merge the two option sets together but give precedence
234
+ # to command line options
235
+
236
+ server_keys=["server","username","password","proxy_server",
237
+ "proxy_port","proxy_user","proxy_password"]
238
+
239
+ if !config.empty?
240
+ ServerCredentials.instance["global"]=config.select_keys(server_keys).merge({"name"=>"global"})
241
+ config.delete_keys(server_keys)
242
+ end
243
+
244
+ config.each_pair { |k,v|
245
+ if k.match(/(.+)\[(.+)\]\[(.+)\]/)
246
+ if $1.downcase=="server"
247
+ ServerCredentials.instance[$2] ||= {"name"=>$2}
248
+ ServerCredentials.instance[$2].merge!($3=>v)
249
+ else
250
+ env[$1] ||= {}
251
+ env[$1][$2] ||= {}
252
+ env[$1][$2].merge({$3=>v})
253
+ end
254
+ else
255
+ env[k]=v
256
+ end
257
+ }
258
+
259
+ end
260
+
199
261
 
200
262
  #checks to ensure all dependencies are available, forcefully exits with an
201
263
  # exit code of 1 if the dependency check fails
@@ -213,7 +275,7 @@ class ZabconApp
213
275
  cmd_hash[k.to_s]=v
214
276
  end
215
277
 
216
- EnvVars.instance.load_config(cmd_hash)
278
+ load_config(cmd_hash)
217
279
 
218
280
  rescue OptionParser::InvalidOption => e
219
281
  puts e