diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/parser/interpreter.rb | 49 | ||||
-rw-r--r-- | lib/puppet/rails.rb | 80 | ||||
-rw-r--r-- | lib/puppet/rails/database.rb | 36 | ||||
-rw-r--r-- | lib/puppet/rails/host.rb | 80 | ||||
-rw-r--r-- | lib/puppet/rails/rails_object.rb | 40 | ||||
-rw-r--r-- | lib/puppet/rails/rails_parameter.rb | 5 | ||||
-rw-r--r-- | lib/puppet/transportable.rb | 11 |
7 files changed, 277 insertions, 24 deletions
diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb index ee89433f3..a11e870ab 100644 --- a/lib/puppet/parser/interpreter.rb +++ b/lib/puppet/parser/interpreter.rb @@ -38,6 +38,12 @@ module Puppet branch under your main directory."] ) + Puppet.setdefaults(:puppetmaster, + :storeconfigs => [false, + "Whether to store each client's configuration. This + requires ActiveRecord from Ruby on Rails."] + ) + attr_accessor :ast, :filetimeout # just shorten the constant path a bit, using what amounts to an alias AST = Puppet::Parser::AST @@ -220,7 +226,7 @@ module Puppet end begin - return scope.evaluate(args) + objects = scope.evaluate(args) rescue Puppet::DevError, Puppet::Error, Puppet::ParseError => except raise rescue => except @@ -232,6 +238,24 @@ module Puppet #end raise error end + + if Puppet[:storeconfigs] + unless defined? ActiveRecord + require 'puppet/rails' + unless defined? ActiveRecord + raise LoadError, + "storeconfigs is enabled but rails is unavailable" + end + Puppet::Rails.init + end + Puppet::Rails::Host.store( + :objects => objects, + :host => client, + :facts => facts + ) + end + + return objects end def scope @@ -240,25 +264,6 @@ module Puppet private - # Evaluate the configuration. If there aren't any nodes defined, then - # this doesn't actually do anything, because we have to evaluate the - # entire configuration each time we get a connect. - def evaluate - # FIXME When this produces errors, it should specify which - # node caused those errors. - if @usenodes - @scope = Puppet::Parser::Scope.new() # no parent scope - @scope.name = "top" - @scope.type = "puppet" - @scope.interp = self - Puppet.debug "Nodes defined" - @ast.safeevaluate(:scope => @scope) - else - Puppet.debug "No nodes defined" - return - end - end - def parsefiles if @file if defined? @parser @@ -305,10 +310,6 @@ module Puppet # Mark when we parsed, so we can check freshness @parsedate = Time.now.to_i @lastchecked = Time.now - - # Reevaluate the config. This is what actually replaces the - # existing scope. - evaluate end end end diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb new file mode 100644 index 000000000..e9eeeaed5 --- /dev/null +++ b/lib/puppet/rails.rb @@ -0,0 +1,80 @@ +# Load the appropriate libraries, or set a class indicating they aren't available + +require 'facter' +require 'puppet' + +begin + require 'active_record' +rescue LoadError => detail + if Facter["operatingsystem"].value == "Debian" + count = 0 + Dir.entries("/usr/share/rails").each do |dir| + libdir = File.join("/usr/share/rails", dir, "lib") + if FileTest.exists?(libdir) and ! $:.include?(libdir) + count += 1 + $: << libdir + end + end + + if count > 0 + retry + end + end +end + +module Puppet::Rails + Puppet.config.setdefaults(:puppetmaster, + :dblocation => { :default => "$statedir/clientconfigs.sqlite3", + :mode => 0600, + :desc => "The database cache for client configurations. Used for + querying within the language." + }, + :dbadapter => [ "sqlite3", "The type of database to use." ], + :dbname => [ "puppet", "The name of the database to use." ], + :dbserver => [ "puppet", "The database server for Client caching. Only + used when networked databases are used."], + :dbuser => [ "puppet", "The database user for Client caching. Only + used when networked databases are used."], + :dbpassword => [ "puppet", "The database password for Client caching. Only + used when networked databases are used."], + :railslog => {:default => "$logdir/puppetrails.log", + :mode => 0600, + :desc => "Where Rails-specific logs are sent" + } + ) + + def self.setupdb + + end + + def self.init + Puppet.config.use(:puppet) + Puppet.config.use(:puppetmaster) + + ActiveRecord::Base.logger = Logger.new(Puppet[:railslog]) + args = {:adapter => Puppet[:dbadapter]} + + case Puppet[:dbadapter] + when "sqlite3": + args[:database] = Puppet[:dblocation] + when "mysql": + args[:host] = Puppet[:dbserver] + args[:username] = Puppet[:dbuser] + args[:password] = Puppet[:dbpassword] + args[:database] = Puppet[:dbname] + end + + ActiveRecord::Base.establish_connection(args) + + unless FileTest.exists?(args[:database]) + require 'puppet/rails/database' + Puppet::Rails::Database.up + end + end +end + +if defined? ActiveRecord::Base + require 'puppet/rails/host' +end + +# $Id$ diff --git a/lib/puppet/rails/database.rb b/lib/puppet/rails/database.rb new file mode 100644 index 000000000..3127693cf --- /dev/null +++ b/lib/puppet/rails/database.rb @@ -0,0 +1,36 @@ +class Puppet::Rails::Database < ActiveRecord::Migration + require 'sqlite3' + + def self.up + ActiveRecord::Migration.verbose = false + + create_table :rails_objects do |table| + table.column :name, :string, :null => false + table.column :ptype, :string, :null => false + table.column :tags, :string + table.column :file, :string + table.column :line, :integer + table.column :host_id, :integer + table.column :collectable, :boolean + end + + create_table :rails_parameters do |table| + table.column :name, :string, :null => false + table.column :value, :string, :null => false + table.column :rails_object_id, :integer + end + + create_table :hosts do |table| + table.column :name, :string, :null => false + table.column :ip, :string + table.column :facts, :string + table.column :classes, :string + end + end + + def self.down + drop_table :rails_objects + drop_table :rails_parameters + drop_table :hosts + end +end diff --git a/lib/puppet/rails/host.rb b/lib/puppet/rails/host.rb new file mode 100644 index 000000000..0cfb3ec44 --- /dev/null +++ b/lib/puppet/rails/host.rb @@ -0,0 +1,80 @@ +require 'puppet/rails/rails_object' + +RailsObject = Puppet::Rails::RailsObject +class Puppet::Rails::Host < ActiveRecord::Base + Host = self + serialize :facts, Hash + serialize :classes, Array + + has_many :rails_objects, :dependent => :delete_all + + # If the host already exists, get rid of its objects + def self.clean(host) + if obj = Host.find_by_name(host) + obj.rails_objects.clear + return obj + else + return nil + end + end + + # Store our host in the database. + def self.store(hash) + name = hash[:host] || "localhost" + ip = hash[:ip] || "127.0.0.1" + facts = hash[:facts] || {} + objects = hash[:objects] + + unless objects + raise ArgumentError, "You must pass objects" + end + + hostargs = { + :name => name, + :ip => ip, + :facts => facts, + :classes => objects.classes + } + + objects = objects.flatten + + host = nil + if host = clean(name) + [:name, :facts, :classes].each do |param| + unless host[param] == hostargs[param] + host[param] = hostargs[param] + end + end + else + host = Host.new(hostargs) + end + + host.addobjects(objects) + + host.save + + return host + end + + # Add all of our RailsObjects + def addobjects(objects) + objects.each do |tobj| + params = {} + tobj.each do |p,v| params[p] = v end + + args = {:ptype => tobj.type, :name => tobj.name} + [:tags, :file, :line].each do |param| + if val = tobj.send(param) + args[param] = val + end + end + + robj = RailsObject.new(args) + self.rails_objects << robj + + robj.addparams(params) + end + end +end + +# $Id$ diff --git a/lib/puppet/rails/rails_object.rb b/lib/puppet/rails/rails_object.rb new file mode 100644 index 000000000..819706957 --- /dev/null +++ b/lib/puppet/rails/rails_object.rb @@ -0,0 +1,40 @@ +require 'puppet' +require 'puppet/rails/rails_parameter' + +RailsParameter = Puppet::Rails::RailsParameter +class Puppet::Rails::RailsObject < ActiveRecord::Base + has_many :rails_parameters, :dependent => :delete_all + serialize :tags, Array + + belongs_to :host + + # Add a set of parameters. + def addparams(params) + params.each do |pname, pvalue| + pobj = RailsParameter.new( + :name => pname, + :value => pvalue + ) + + self.rails_parameters << pobj + end + end + + # Convert our object to a trans_object + def to_trans + obj = Puppet::TransObject.new(name(), ptype()) + + [:file, :line, :tags].each do |method| + if val = send(method) + obj.send(method.to_s + "=", val) + end + end + params.each do |name, value| + obj[name] = value + end + + return obj + end +end + +# $Id$ diff --git a/lib/puppet/rails/rails_parameter.rb b/lib/puppet/rails/rails_parameter.rb new file mode 100644 index 000000000..a1966e3dc --- /dev/null +++ b/lib/puppet/rails/rails_parameter.rb @@ -0,0 +1,5 @@ +class Puppet::Rails::RailsParameter < ActiveRecord::Base + belongs_to :rails_objects +end + +# $Id$ diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb index 3422cd71b..9921aecef 100644 --- a/lib/puppet/transportable.rb +++ b/lib/puppet/transportable.rb @@ -106,6 +106,17 @@ module Puppet @children.each { |c| yield c } end + # Turn our heirarchy into a flat list + def flatten + @children.collect do |obj| + if obj.is_a? Puppet::TransBucket + obj.flatten + else + obj + end + end.flatten + end + def initialize @children = [] end |