Updated mcollective.init according to OSCI-658
[packages/precise/mcollective.git] / lib / mcollective / config.rb
diff --git a/lib/mcollective/config.rb b/lib/mcollective/config.rb
new file mode 100644 (file)
index 0000000..8b5e409
--- /dev/null
@@ -0,0 +1,223 @@
+module MCollective
+  # A pretty sucky config class, ripe for refactoring/improving
+  class Config
+    include Singleton
+
+    attr_accessor :mode
+
+    attr_reader :topicprefix, :daemonize, :pluginconf, :libdir, :configured
+    attr_reader :logfile, :keeplogs, :max_log_size, :loglevel, :logfacility
+    attr_reader :identity, :daemonize, :connector, :securityprovider, :factsource
+    attr_reader :registration, :registerinterval, :topicsep, :classesfile
+    attr_reader :rpcauditprovider, :rpcaudit, :configdir, :rpcauthprovider
+    attr_reader :rpcauthorization, :color, :configfile, :rpchelptemplate
+    attr_reader :rpclimitmethod, :logger_type, :fact_cache_time, :collectives
+    attr_reader :main_collective, :ssl_cipher, :registration_collective
+    attr_reader :direct_addressing, :direct_addressing_threshold, :ttl, :helptemplatedir
+    attr_reader :queueprefix, :default_discovery_method, :default_discovery_options
+
+    def initialize
+      @configured = false
+    end
+
+    def loadconfig(configfile)
+      set_config_defaults(configfile)
+
+      if File.exists?(configfile)
+        File.open(configfile, "r").each do |line|
+
+          # strip blank spaces, tabs etc off the end of all lines
+          line.gsub!(/\s*$/, "")
+
+          unless line =~ /^#|^$/
+            if (line =~ /(.+?)\s*=\s*(.+)/)
+              key = $1
+              val = $2
+
+              case key
+                when "topicsep"
+                  @topicsep = val
+                when "registration"
+                  @registration = val.capitalize
+                when "registration_collective"
+                  @registration_collective = val
+                when "registerinterval"
+                  @registerinterval = val.to_i
+                when "collectives"
+                  @collectives = val.split(",").map {|c| c.strip}
+                when "main_collective"
+                  @main_collective = val
+                when "topicprefix"
+                  @topicprefix = val
+                when "queueprefix"
+                  @queueprefix = val
+                when "logfile"
+                  @logfile = val
+                when "keeplogs"
+                  @keeplogs = val.to_i
+                when "max_log_size"
+                  @max_log_size = val.to_i
+                when "loglevel"
+                  @loglevel = val
+                when "logfacility"
+                  @logfacility = val
+                when "libdir"
+                  paths = val.split(File::PATH_SEPARATOR)
+                  paths.each do |path|
+                    raise("libdir paths should be absolute paths but '%s' is relative" % path) unless Util.absolute_path?(path)
+
+                    @libdir << path
+                    unless $LOAD_PATH.include?(path)
+                      $LOAD_PATH << path
+                    end
+                  end
+                when "identity"
+                  @identity = val
+                when "direct_addressing"
+                  val =~ /^1|y/i ? @direct_addressing = true : @direct_addressing = false
+                when "direct_addressing_threshold"
+                  @direct_addressing_threshold = val.to_i
+                when "color"
+                  val =~ /^1|y/i ? @color = true : @color = false
+                when "daemonize"
+                  val =~ /^1|y/i ? @daemonize = true : @daemonize = false
+                when "securityprovider"
+                  @securityprovider = val.capitalize
+                when "factsource"
+                  @factsource = val.capitalize
+                when "connector"
+                  @connector = val.capitalize
+                when "classesfile"
+                  @classesfile = val
+                when /^plugin.(.+)$/
+                  @pluginconf[$1] = val
+                when "rpcaudit"
+                  val =~ /^1|y/i ? @rpcaudit = true : @rpcaudit = false
+                when "rpcauditprovider"
+                  @rpcauditprovider = val.capitalize
+                when "rpcauthorization"
+                  val =~ /^1|y/i ? @rpcauthorization = true : @rpcauthorization = false
+                when "rpcauthprovider"
+                  @rpcauthprovider = val.capitalize
+                when "rpchelptemplate"
+                  @rpchelptemplate = val
+                when "rpclimitmethod"
+                  @rpclimitmethod = val.to_sym
+                when "logger_type"
+                  @logger_type = val
+                when "fact_cache_time"
+                  @fact_cache_time = val.to_i
+                when "ssl_cipher"
+                  @ssl_cipher = val
+                when "ttl"
+                  @ttl = val.to_i
+                when "helptemplatedir"
+                  @helptemplatedir = val
+                when "default_discovery_options"
+                  @default_discovery_options << val
+                when "default_discovery_method"
+                  @default_discovery_method = val
+                else
+                  raise("Unknown config parameter #{key}")
+              end
+            end
+          end
+        end
+
+        I18n.load_path = Dir[File.expand_path(File.join(File.dirname(__FILE__), "locales", "*.yml"))]
+        I18n.locale = :en
+
+        read_plugin_config_dir("#{@configdir}/plugin.d")
+
+        raise 'Identities can only match /\w\.\-/' unless @identity.match(/^[\w\.\-]+$/)
+
+        @configured = true
+
+        @libdir.each {|dir| Log.warn("Cannot find libdir: #{dir}") unless File.directory?(dir)}
+
+        if @logger_type == "syslog"
+          raise "The sylog logger is not usable on the Windows platform" if Util.windows?
+        end
+
+        PluginManager.loadclass("Mcollective::Facts::#{@factsource}_facts")
+        PluginManager.loadclass("Mcollective::Connector::#{@connector}")
+        PluginManager.loadclass("Mcollective::Security::#{@securityprovider}")
+        PluginManager.loadclass("Mcollective::Registration::#{@registration}")
+        PluginManager.loadclass("Mcollective::Audit::#{@rpcauditprovider}") if @rpcaudit
+        PluginManager << {:type => "global_stats", :class => RunnerStats.new}
+
+        Log.logmsg(:PLMC1, "The Marionette Collective version %{version} started by %{name} using config file %{config}", :info, :version => MCollective::VERSION, :name => $0, :config => configfile)
+      else
+        raise("Cannot find config file '#{configfile}'")
+      end
+    end
+
+    def set_config_defaults(configfile)
+      @stomp = Hash.new
+      @subscribe = Array.new
+      @pluginconf = Hash.new
+      @connector = "activemq"
+      @securityprovider = "Psk"
+      @factsource = "Yaml"
+      @identity = Socket.gethostname
+      @registration = "Agentlist"
+      @registerinterval = 0
+      @registration_collective = nil
+      @topicsep = "."
+      @topicprefix = "/topic/"
+      @queueprefix = "/queue/"
+      @classesfile = "/var/lib/puppet/state/classes.txt"
+      @rpcaudit = false
+      @rpcauditprovider = ""
+      @rpcauthorization = false
+      @rpcauthprovider = ""
+      @configdir = File.dirname(configfile)
+      @color = !Util.windows?
+      @configfile = configfile
+      @logger_type = "file"
+      @keeplogs = 5
+      @max_log_size = 2097152
+      @rpclimitmethod = :first
+      @libdir = Array.new
+      @fact_cache_time = 300
+      @loglevel = "info"
+      @logfacility = "user"
+      @collectives = ["mcollective"]
+      @main_collective = @collectives.first
+      @ssl_cipher = "aes-256-cbc"
+      @direct_addressing = false
+      @direct_addressing_threshold = 10
+      @default_discovery_method = "mc"
+      @default_discovery_options = []
+      @ttl = 60
+      @mode = :client
+
+      # look in the config dir for the template so users can provide their own and windows
+      # with odd paths will just work more often, but fall back to old behavior if it does
+      # not exist
+      @rpchelptemplate = File.join(File.dirname(configfile), "rpc-help.erb")
+      @rpchelptemplate = "/etc/mcollective/rpc-help.erb" unless File.exists?(@rpchelptemplate)
+      @helptemplatedir = File.dirname(@rpchelptemplate)
+    end
+
+    def read_plugin_config_dir(dir)
+      return unless File.directory?(dir)
+
+      Dir.new(dir).each do |pluginconfigfile|
+        next unless pluginconfigfile =~ /^([\w]+).cfg$/
+
+        plugin = $1
+        File.open("#{dir}/#{pluginconfigfile}", "r").each do |line|
+          # strip blank lines
+          line.gsub!(/\s*$/, "")
+          next if line =~ /^#|^$/
+          if (line =~ /(.+?)\s*=\s*(.+)/)
+            key = $1
+            val = $2
+            @pluginconf["#{plugin}.#{key}"] = val
+          end
+        end
+      end
+    end
+  end
+end