Permalink
Browse files

implemented config as yaml file with cli overrides

  • Loading branch information...
gerir
gerir committed Mar 15, 2012
1 parent 5673ae0 commit aaeb7ba44f3940a4a29b050bac6b713cb0df1fd5
Showing with 84 additions and 72 deletions.
  1. +39 −25 lib/zettabee.rb
  2. +45 −47 lib/zettabee/cli.rb
View
@@ -13,6 +13,7 @@
require 'digest/md5'
require 'zettabee/zfs'
require 'date'
+require 'yaml'
module ZettaBee
@@ -22,40 +23,51 @@ class Set
attr_accessor :pairs
- @debug = false
- @nagios = false
- @verbose = false
- @cfgfile = nil
- @fullstatus = false
- class << self; attr_accessor :debug, :nagios, :verbose, :cfgfile, :fullstatus; end
-
class Error < StandardError; end
class ConfigurationError < Error; end
- def initialize(cfgfile)
+ def initialize(options_cli)
@pairs_by_port = {}
@pairs_by_destination = {}
@pairs_by_fingerprint = {}
@pairs = []
+ @options = {
+ :config => "/local/etc/zettabee/zettabee.cfg",
+ :zonfig => "/local/etc/zettabee/zettabee.zfg",
+ :nagios => false,
+ :debug => false,
+ :fullstatus => false,
+ :verbose => false
+ }
+
begin
- File.open(cfgfile,"r").readlines.each do |cfgline|
- cfgline.chomp!
- next if cfgline[0] == 35 # need to change in 1.9
- c = cfgline.split(/\s+/)
- shost,szfs = c[0].split(':')
- dhost,dzfs = c[1].split(':')
- cfgoptions = {}
- c[2].split(',').each do |o|
- cfgoptions[o.split('=')[0].to_sym] = o.split('=')[1]
+ options_cfg = YAML::load_file (options_cli[:config] || @options[:config])
+ @options.merge! options_cfg unless options_cfg.nil? or options_cfg == false
+ @options.merge! options_cli
+ rescue Errno::ENOENT
+ raise ConfigurationError, "could not read main configuration file #{options_cli[:config]}" if options_cli[:config]
+ @options[:config] = nil
+ end
+
+ begin
+ File.open(@options[:zonfig],"r").readlines.each do |zfgline|
+ zfgline.chomp!
+ next if zfgline[0] == 35 # need to change in 1.9
+ z = zfgline.split(/\s+/)
+ shost,szfs = z[0].split(':')
+ dhost,dzfs = z[1].split(':')
+ zfgoptions = {}
+ z[2].split(',').each do |o|
+ zfgoptions[o.split('=')[0].to_sym] = o.split('=')[1]
end
- pair = Pair.new(shost,szfs,dhost,dzfs,cfgoptions)
+ pair = Pair.new(shost,szfs,dhost,dzfs,zfgoptions,@options)
- raise ConfigurationError, "duplicate destination in configuration file: #{dzfs}:#{cfgoptions[:port]}" if @pairs_by_destination.has_key?(dzfs)
- raise ConfigurationError, "duplicate port in configuration file: #{dzfs}:#{cfgoptions[:port]}" if @pairs_by_port.has_key?(cfgoptions[:port])
+ raise ConfigurationError, "duplicate destination in configuration file: #{dzfs}:#{zfgoptions[:port]}" if @pairs_by_destination.has_key?(dzfs)
+ raise ConfigurationError, "duplicate port in configuration file: #{dzfs}:#{zfgoptions[:port]}" if @pairs_by_port.has_key?(zfgoptions[:port])
raise ConfigurationError, "duplicate source::destination #{dzfs}}" if @pairs_by_fingerprint.has_key?(pair.fingerprint)
- @pairs_by_port[cfgoptions[:port]] = pair
+ @pairs_by_port[zfgoptions[:port]] = pair
@pairs_by_destination[dzfs] = pair
@pairs_by_fingerprint[pair.fingerprint] = pair
@pairs.push(pair)
@@ -144,7 +156,7 @@ class ZettabeeError < Error; end
class Info < StandardError; end
class IsRunningInfo < Info; end
- def initialize(shost,szfs,dhost,dzfs,cfgoptions={})
+ def initialize(shost,szfs,dhost,dzfs,cfgoptions={},options)
@transport = cfgoptions[:transport]
@port = cfgoptions[:port]
@@ -177,6 +189,8 @@ def initialize(shost,szfs,dhost,dzfs,cfgoptions={})
@source_lastsnap = nil
@destination_lastsnap = nil
+ @options = options
+
begin
lsnp = @destination.get(@zfsproperties[:lastsnap])
@source_lastsnap = ZFS::Dataset.new("#{@source.name}@#{lsnp}",@source.host, :log => @log)
@@ -185,8 +199,8 @@ def initialize(shost,szfs,dhost,dzfs,cfgoptions={})
raise unless e.message.include?("dataset does not exist")
end
- @log.add Log4r::StdoutOutputter.new('console', :formatter => Log4r::PatternFormatter.new(:pattern => "[%d] zettabee:%c [%p] %l %m"), :level => Log4r::DEBUG) if Set.verbose
- Set.debug ? log4level = Log4r::DEBUG : log4level = Log4r::INFO
+ @log.add Log4r::StdoutOutputter.new('console', :formatter => Log4r::PatternFormatter.new(:pattern => "[%d] zettabee:%c [%p] %l %m"), :level => Log4r::DEBUG) if @options[:verbose]
+ @options[:debug] ? log4level = Log4r::DEBUG : log4level = Log4r::INFO
@log.add Log4r::FileOutputter.new("logfile", :filename => @logfile, :trunc => false, :formatter => Log4r::PatternFormatter.new(:pattern => "[%d] #{ZFIX}:%c [%p] %l %m"), :level => log4level)
@nagios_svc_description = "service/#{ZFIX}:#{@fingerprint}"
@@ -220,7 +234,7 @@ def output_status
end
rh,rm,rs = runtime(:hms)
@destination.exists? ? lss = lastsnapshot : lss = '-'
- if Set.fullstatus then
+ if @options[:fullstatus] then
print Kernel.sprintf("%s:%s %s:%s %s %3d:%02d:%02d%s %s:%d %s (%d:%02d:%02d)\n",@source.host.ljust(8),@source.name.ljust(45),@destination.host.rjust(8),@destination.name.ljust(36),state.ljust(14),h,m,s,lbang,lss.rjust(26),@port,status,rh,rm,rs)
else
print Kernel.sprintf("%s:%s %s:%s %s %3d:%02d:%02d%s %s (%d:%02d:%02d)\n",@source.host.ljust(8),@source.name.ljust(45),@destination.host.rjust(8),@destination.name.ljust(36),state.ljust(14),h,m,s,lbang,status,rh,rm,rs)
View
@@ -20,62 +20,55 @@ class CLI
def initialize(arguments)
@arguments = arguments
- @options = OpenStruct.new
-
- # defaults
- @options.cfgfile = "/local/etc/zettabee/zettabee.cfg"
- @options.debug = false
- @options.nagios = false
- @options.verbose = false
+ @options = {}
@action = nil
@destination = nil
@pairs = {}
-
end
def run
- if parsed_options? && arguments_valid?
- process_arguments
- process_command
- else
- output_help
- exit 127
+ begin
+ parsed_options?
+ options_valid?
+ arguments_valid?
+ rescue ArgumentError => e
+ output_error(e.message)
+ exit 1
end
+ process_options
+ process_arguments
+ process_command
end
protected
def parsed_options?
opts = OptionParser.new
- opts.on('-V', '--version') { output_version ; exit 0 }
- opts.on('-h', '--help') { output_help ; exit 0}
- opts.on('-d', '--debug', "Debug mode" ) { @options.debug = true }
- opts.on('-v', '--verbose', "Verbose Mode") { @options.verbose = true }
- opts.on('-N', '--nagios NAGIOSHOST', String, "Nagios Host for NSCA") { |nagioshost| @options.nagios = nagioshost }
- opts.on('-c', '--config CONFIG', String, "Configuration file location") { |cfgfile| @options.cfgfile = cfgfile }
- opts.on('-F', '--full-status', "Show full status") { @options.fullstatus = true }
+ opts.on('-V', '--version') { output_version ; exit 0 }
+ opts.on('-h', '--help') { output_help ; exit 0}
+ opts.on('-d', '--debug', "Debug mode" ) { @options[:debug] = true }
+ opts.on('-v', '--verbose', "Verbose Mode") { @options[:verbose] = true }
+ opts.on('-z', '--zonfig ZONFIG', String, "Zettabee pairs configuration file location") { |zfgfile| @options[:zonfig] = zfgfile }
+ opts.on('-c', '--config CONFIG', String, "Zettabee main configuration file location") { |cfgfile| @options[:config] = cfgfile }
+ opts.on('-N', '--nagios NAGIOSHOST', String, "Nagios Host for NSCA") { |nagioshost| @options[:nagios] = nagioshost }
+ opts.on('-F', '--full-status', "Show full status") { @options[:fullstatus] = true }
opts.parse!(@arguments) rescue return false
-
process_options
true
end
- def arguments_valid?
- if @arguments.length < 1 or @arguments.length > 2
- $stderr.puts "#{ME}: error: invalid number of arguments: #{@arguments}"
- return false
- end
+ def options_valid?
true
end
+ def arguments_valid?
+ raise ArgumentError, "error: invalid number of arguments: #{@arguments}" if @arguments.length < 1 or @arguments.length > 2
+ end
+
def process_options
- Set.nagios = @options.nagios if @options.nagios
- Set.debug = @options.debug if @options.debug
- Set.cfgfile = @options.cfgfile if @options.cfgfile
- Set.verbose = @options.verbose if @options.verbose
- Set.fullstatus = @options.fullstatus if @options.fullstatus
+ true
end
def process_arguments
@@ -96,14 +89,14 @@ def process_arguments
def process_command
begin
- @zettabees = Set.new(@options.cfgfile)
+ @zettabees = Set.new(@options)
execpairs = []
rescue Set::ConfigurationError => e
- $stderr.write "#{ME}: error: #{e.message}\n"
+ output_error(e.message)
exit 1
end
-
- if @destination then
+
+ if @destination
# a destination can be fully specified (a/b/c) or using the last component (c)
if @destination.split('/').length > 1
execpairs.push(@zettabees.pair_by_destination[@destination])
@@ -124,7 +117,7 @@ def process_command
end
execpairs.each do |pair|
- sn = NSCA.new(@options.nagios,pair.destination.host,pair.nagios_svc_description)
+ sn = NSCA.new(@options[:nagios],pair.destination.host,pair.nagios_svc_description)
sn_rt = NAGIOS_OK
sn_svc_out = "#{@action.to_s.upcase} #{pair.destination}: #{Time.now.asctime}: "
@@ -155,7 +148,7 @@ def process_command
end
begin
- sn.send_nsca(sn_rt,sn_svc_out) if @options.nagios
+ sn.send_nsca(sn_rt,sn_svc_out) if @options[:nagios]
rescue NSCA::SendNSCAError => e
$stderr.write "#{ME}: error: send_nsca failed: #{e.message}\n"
end
@@ -170,20 +163,25 @@ def output_version
def output_help
$stderr.write "#{ME} [<options>] <action> [<destination>]\n"
$stderr.write "\n"
- $stderr.write " <action> setup : initial #{ME} setup\n"
- $stderr.write " status [<destination>] : display status for all destinations or <destination>\n"
- $stderr.write " runstatus <destination> : show running status for <destination>\n"
- $stderr.write " initialize <destination> : perform first sync for <destination>\n"
- $stderr.write " update <destination> : update sync for <destination>\n"
+ $stderr.write " <action> setup : initial #{ME} setup\n"
+ $stderr.write " status [<destination>] : display status for all destinations or <destination>\n"
+ $stderr.write " runstatus <destination> : show running status for <destination>\n"
+ $stderr.write " initialize <destination> : perform first sync for <destination>\n"
+ $stderr.write " update <destination> : update sync for <destination>\n"
$stderr.write " \n"
- $stderr.write " <options> -d, --debug : debug (to logfile)\n"
- $stderr.write " -v, --verbose : verbose (to console)\n"
- $stderr.write " -n, --nagios <nagioshost> : send NSCA result to <nagioshost>\n"
- $stderr.write " -c, --config <configfile> : read configuration from <configfile>\n"
+ $stderr.write " <options> -d, --debug : debug (to logfile)\n"
+ $stderr.write " -v, --verbose : verbose (to console)\n"
+ $stderr.write " -n, --nagios <nagioshost> : send NSCA result to <nagioshost>\n"
+ $stderr.write " -z, --zonfig <zonfigfile> : read zettabee pairs configuration from <zonfigfile>\n"
+ $stderr.write " -c, --config <configfile> : read main configuration from <configfile>\n"
$stderr.write " \n"
$stderr.write " <destination> is [<host>:]<filesystem>\n"
end
+ def output_error(message)
+ $stderr.write "#{ME}: error: #{message}\n"
+ end
+
def output_options(exit_status)
puts "Options:\n"

0 comments on commit aaeb7ba

Please sign in to comment.