Update version according to OSCI-856
[packages/precise/mcollective.git] / lib / mcollective / config.rb
1 module MCollective
2   # A pretty sucky config class, ripe for refactoring/improving
3   class Config
4     include Singleton
5
6     attr_accessor :mode
7
8     attr_reader :daemonize, :pluginconf, :libdir, :configured
9     attr_reader :logfile, :keeplogs, :max_log_size, :loglevel, :logfacility
10     attr_reader :identity, :daemonize, :connector, :securityprovider, :factsource
11     attr_reader :registration, :registerinterval, :classesfile
12     attr_reader :rpcauditprovider, :rpcaudit, :configdir, :rpcauthprovider
13     attr_reader :rpcauthorization, :color, :configfile
14     attr_reader :rpclimitmethod, :logger_type, :fact_cache_time, :collectives
15     attr_reader :main_collective, :ssl_cipher, :registration_collective
16     attr_reader :direct_addressing, :direct_addressing_threshold, :ttl
17     attr_reader :default_discovery_method, :default_discovery_options
18     attr_reader :publish_timeout, :threaded
19
20     def initialize
21       @configured = false
22     end
23
24     def loadconfig(configfile)
25       set_config_defaults(configfile)
26
27       if File.exists?(configfile)
28         File.readlines(configfile).each do |line|
29
30           # strip blank spaces, tabs etc off the end of all lines
31           line.gsub!(/\s*$/, "")
32
33           unless line =~ /^#|^$/
34             if (line =~ /(.+?)\s*=\s*(.+)/)
35               key = $1.strip
36               val = $2
37
38               case key
39                 when "registration"
40                   @registration = val.capitalize
41                 when "registration_collective"
42                   @registration_collective = val
43                 when "registerinterval"
44                   @registerinterval = val.to_i
45                 when "collectives"
46                   @collectives = val.split(",").map {|c| c.strip}
47                 when "main_collective"
48                   @main_collective = val
49                 when "logfile"
50                   @logfile = val
51                 when "keeplogs"
52                   @keeplogs = val.to_i
53                 when "max_log_size"
54                   @max_log_size = val.to_i
55                 when "loglevel"
56                   @loglevel = val
57                 when "logfacility"
58                   @logfacility = val
59                 when "libdir"
60                   paths = val.split(File::PATH_SEPARATOR)
61                   paths.each do |path|
62                     raise("libdir paths should be absolute paths but '%s' is relative" % path) unless Util.absolute_path?(path)
63
64                     @libdir << path
65                     unless $LOAD_PATH.include?(path)
66                       $LOAD_PATH << path
67                     end
68                   end
69                 when "identity"
70                   @identity = val
71                 when "direct_addressing"
72                   @direct_addressing = Util.str_to_bool(val)
73                 when "direct_addressing_threshold"
74                   @direct_addressing_threshold = val.to_i
75                 when "color"
76                   @color = Util.str_to_bool(val)
77                 when "daemonize"
78                   @daemonize = Util.str_to_bool(val)
79                 when "securityprovider"
80                   @securityprovider = val.capitalize
81                 when "factsource"
82                   @factsource = val.capitalize
83                 when "connector"
84                   @connector = val.capitalize
85                 when "classesfile"
86                   @classesfile = val
87                 when /^plugin.(.+)$/
88                   @pluginconf[$1] = val
89                 when "publish_timeout"
90                   @publish_timeout = val.to_i
91                 when "rpcaudit"
92                   @rpcaudit = Util.str_to_bool(val)
93                 when "rpcauditprovider"
94                   @rpcauditprovider = val.capitalize
95                 when "rpcauthorization"
96                   @rpcauthorization = Util.str_to_bool(val)
97                 when "rpcauthprovider"
98                   @rpcauthprovider = val.capitalize
99                 when "rpclimitmethod"
100                   @rpclimitmethod = val.to_sym
101                 when "logger_type"
102                   @logger_type = val
103                 when "fact_cache_time"
104                   @fact_cache_time = val.to_i
105                 when "ssl_cipher"
106                   @ssl_cipher = val
107                 when "threaded"
108                   @threaded = Util.str_to_bool(val)
109                 when "ttl"
110                   @ttl = val.to_i
111                 when "default_discovery_options"
112                   @default_discovery_options << val
113                 when "default_discovery_method"
114                   @default_discovery_method = val
115                 else
116                   raise("Unknown config parameter '#{key}'")
117               end
118             end
119           end
120         end
121
122         raise('The %s config file does not specify a libdir setting, cannot continue' % configfile) if @libdir.empty?
123
124         I18n.load_path = Dir[File.expand_path(File.join(File.dirname(__FILE__), "locales", "*.yml"))]
125         I18n.locale = :en
126
127         read_plugin_config_dir("#{@configdir}/plugin.d")
128
129         raise 'Identities can only match /\w\.\-/' unless @identity.match(/^[\w\.\-]+$/)
130
131         @configured = true
132
133         @libdir.each {|dir| Log.warn("Cannot find libdir: #{dir}") unless File.directory?(dir)}
134
135         if @logger_type == "syslog"
136           raise "The sylog logger is not usable on the Windows platform" if Util.windows?
137         end
138
139         PluginManager.loadclass("Mcollective::Facts::#{@factsource}_facts")
140         PluginManager.loadclass("Mcollective::Connector::#{@connector}")
141         PluginManager.loadclass("Mcollective::Security::#{@securityprovider}")
142         PluginManager.loadclass("Mcollective::Registration::#{@registration}")
143         PluginManager.loadclass("Mcollective::Audit::#{@rpcauditprovider}") if @rpcaudit
144         PluginManager << {:type => "global_stats", :class => RunnerStats.new}
145
146         Log.logmsg(:PLMC1, "The Marionette Collective version %{version} started by %{name} using config file %{config}", :info, :version => MCollective::VERSION, :name => $0, :config => configfile)
147       else
148         raise("Cannot find config file '#{configfile}'")
149       end
150     end
151
152     def set_config_defaults(configfile)
153       @stomp = Hash.new
154       @subscribe = Array.new
155       @pluginconf = Hash.new
156       @connector = "activemq"
157       @securityprovider = "Psk"
158       @factsource = "Yaml"
159       @identity = Socket.gethostname
160       @registration = "Agentlist"
161       @registerinterval = 0
162       @registration_collective = nil
163       @classesfile = "/var/lib/puppet/state/classes.txt"
164       @rpcaudit = false
165       @rpcauditprovider = ""
166       @rpcauthorization = false
167       @rpcauthprovider = ""
168       @configdir = File.dirname(configfile)
169       @color = !Util.windows?
170       @configfile = configfile
171       @logger_type = "file"
172       @keeplogs = 5
173       @max_log_size = 2097152
174       @rpclimitmethod = :first
175       @libdir = Array.new
176       @fact_cache_time = 300
177       @loglevel = "info"
178       @logfacility = "user"
179       @collectives = ["mcollective"]
180       @main_collective = @collectives.first
181       @ssl_cipher = "aes-256-cbc"
182       @direct_addressing = true
183       @direct_addressing_threshold = 10
184       @default_discovery_method = "mc"
185       @default_discovery_options = []
186       @ttl = 60
187       @mode = :client
188       @publish_timeout = 2
189       @threaded = false
190     end
191
192     def read_plugin_config_dir(dir)
193       return unless File.directory?(dir)
194
195       Dir.new(dir).each do |pluginconfigfile|
196         next unless pluginconfigfile =~ /^([\w]+).cfg$/
197
198         plugin = $1
199         File.open("#{dir}/#{pluginconfigfile}", "r").each do |line|
200           # strip blank lines
201           line.gsub!(/\s*$/, "")
202           next if line =~ /^#|^$/
203           if (line =~ /(.+?)\s*=\s*(.+)/)
204             key = $1.strip
205             val = $2
206             @pluginconf["#{plugin}.#{key}"] = val
207           end
208         end
209       end
210     end
211   end
212 end