summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-05-13 04:52:34 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-05-13 04:52:34 +0000
commit5863a0336e1f3bd5e1be85676bb0e7ac7337f2e6 (patch)
tree7d6cadbf16f19cab8d3c89db3a4b95161241c88b /lib/puppet
parent0819e35be74bc997c3a953f05bab874b8d76429d (diff)
downloadpuppet-5863a0336e1f3bd5e1be85676bb0e7ac7337f2e6.tar.gz
puppet-5863a0336e1f3bd5e1be85676bb0e7ac7337f2e6.tar.xz
puppet-5863a0336e1f3bd5e1be85676bb0e7ac7337f2e6.zip
Adding initial rails support. One can now store host configurations using ActiveRecord into a database (I have only tested sqlite3). Tomorrow will be the grammars used to retrieve those records for object collection.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1187 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/parser/interpreter.rb49
-rw-r--r--lib/puppet/rails.rb80
-rw-r--r--lib/puppet/rails/database.rb36
-rw-r--r--lib/puppet/rails/host.rb80
-rw-r--r--lib/puppet/rails/rails_object.rb40
-rw-r--r--lib/puppet/rails/rails_parameter.rb5
-rw-r--r--lib/puppet/transportable.rb11
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