shadow_puppet 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +165 -0
- data/README.rdoc +11 -0
- data/bin/shadow_puppet +102 -0
- data/lib/shadow_puppet.rb +1 -0
- data/lib/shadow_puppet/manifest.rb +276 -0
- metadata +111 -0
data/LICENSE
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/README.rdoc
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
= ShadowPuppet
|
2
|
+
|
3
|
+
ShadowPuppet is a Ruby DSL for Puppet, extracted out of the work we at Rails
|
4
|
+
Machine are doing on Moonshine[http://blog.railsmachine.com/articles/2009/01/16/moonshine-configuration-management-and-deployment/].
|
5
|
+
|
6
|
+
ShadowPuppet provides a DSL for creating collections ("manifests") of Puppet
|
7
|
+
Resources in Ruby. For documentation on writing these manifests, please see
|
8
|
+
ShadowPuppet::Manifest.
|
9
|
+
|
10
|
+
A binary[http://railsmachine.github.com/shadow_puppet/files/bin/shadow_puppet.html] is provided to parse and execute a
|
11
|
+
ShadowPuppet::Manifest.
|
data/bin/shadow_puppet
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#== Sample manifest:
|
3
|
+
#
|
4
|
+
# $ cat examples/foo.rb
|
5
|
+
# class Foo < ShadowPuppet::Manifest
|
6
|
+
# recipe :demo, :text => 'foo'
|
7
|
+
# recipe :some_gems
|
8
|
+
#
|
9
|
+
# def some_gems
|
10
|
+
# package 'rails', :ensure => :updated, :provider => :gem
|
11
|
+
# package 'railsmachine', :ensure => '1.0.5', :provider => :gem, :require => package('capistrano')
|
12
|
+
# package 'capistrano', :ensure => :updated, :provider => :gem
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def demo(options = {})
|
16
|
+
# exec 'sample', :command => "/bin/echo '#{options[:text]}' > /tmp/sample.txt"
|
17
|
+
# file '/tmp/sample2.txt', :ensure => :present, :content => Facter.to_hash.inspect
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
#== Executing this manifest:
|
22
|
+
#
|
23
|
+
# $ shadow_puppet examples/foo.rb
|
24
|
+
# notice: /shadow_puppet:19861340/Exec[foo]/returns: executed successfully
|
25
|
+
# $
|
26
|
+
#
|
27
|
+
#The shadow_puppet binary parses the given ruby code, which is
|
28
|
+
#expected to contain a class named Foo that inherits from
|
29
|
+
#ShadowPuppet::Manifest. An instance of this class is created, and the
|
30
|
+
#<tt>execute</tt> method is called. All output is printed to the console.
|
31
|
+
|
32
|
+
begin
|
33
|
+
|
34
|
+
require 'optparse'
|
35
|
+
opts = OptionParser.new do |opts|
|
36
|
+
opts.banner = <<-EOF
|
37
|
+
NAME
|
38
|
+
Shadow Puppet
|
39
|
+
|
40
|
+
AUTHOR
|
41
|
+
Jesse Newland
|
42
|
+
jesse@railsmachine.com
|
43
|
+
|
44
|
+
DESCRIPTION
|
45
|
+
A Ruby DSL for puppet
|
46
|
+
|
47
|
+
EXAMPLES
|
48
|
+
Sample manifest:
|
49
|
+
|
50
|
+
#foo.rb
|
51
|
+
class Foo < ShadowPuppet::Manifest
|
52
|
+
recipe :foo
|
53
|
+
|
54
|
+
def foo
|
55
|
+
exec :foo, :command => '/bin/echo "foo" > /tmp/foo.txt'
|
56
|
+
file '/tmp/example.txt', :ensure => :present, :content => Facter.to_hash.inspect
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Executing this manifest:
|
61
|
+
|
62
|
+
$ shadow_puppet foo.rb
|
63
|
+
notice: /shadow_puppet:19861340/Exec[foo]/returns: executed successfully
|
64
|
+
$
|
65
|
+
|
66
|
+
The shadow_puppet binary parses the given ruby code, which is
|
67
|
+
expected to contain a class named Foo that inherits from
|
68
|
+
ShadowPuppet::Manifest. An instance of this class is created, and the
|
69
|
+
execute method is called. All output is printed to the console.
|
70
|
+
EOF
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
opts.parse!
|
75
|
+
|
76
|
+
require 'rubygems'
|
77
|
+
require 'shadow_puppet'
|
78
|
+
gem "activesupport"
|
79
|
+
require 'active_support/inflector'
|
80
|
+
require 'fileutils'
|
81
|
+
|
82
|
+
filename = ARGV[0]
|
83
|
+
raise ArgumentError unless filename
|
84
|
+
|
85
|
+
klass = File.basename(filename, ".rb")
|
86
|
+
require filename
|
87
|
+
manifest = klass.classify.constantize.new
|
88
|
+
execute = manifest.execute
|
89
|
+
execute ? exit(0) : exit(1)
|
90
|
+
rescue Errno::EACCES
|
91
|
+
puts "Please run shadow_puppet as root"
|
92
|
+
rescue Exception => e
|
93
|
+
if e.instance_of?(SystemExit)
|
94
|
+
raise
|
95
|
+
else
|
96
|
+
puts 'Uncaught exception'
|
97
|
+
puts e.class
|
98
|
+
puts e.message
|
99
|
+
puts e.backtrace.join("\n")
|
100
|
+
exit(1)
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__) + '/shadow_puppet', 'manifest.rb')
|
@@ -0,0 +1,276 @@
|
|
1
|
+
require 'puppet'
|
2
|
+
require 'erb'
|
3
|
+
gem "activesupport"
|
4
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
5
|
+
require 'active_support/core_ext/array'
|
6
|
+
require 'active_support/inflector'
|
7
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
8
|
+
|
9
|
+
module ShadowPuppet
|
10
|
+
# A Manifest is an executable collection of Puppet Resources[http://reductivelabs.com/trac/puppet/wiki/TypeReference].
|
11
|
+
#
|
12
|
+
# ===Example
|
13
|
+
#
|
14
|
+
# class ManifestExample < ShadowPuppet::Manifest
|
15
|
+
# recipe :sample
|
16
|
+
# recipe :lamp, :ruby # queue calls to self.lamp and
|
17
|
+
# # self.ruby when executing
|
18
|
+
#
|
19
|
+
# recipe :mysql, { # queue a call to self.mysql
|
20
|
+
# :root_password => 'OMGSEKRET' # passing the provided hash
|
21
|
+
# } # as an option
|
22
|
+
#
|
23
|
+
# def sample
|
24
|
+
# exec :foo, :command => '/bin/echo "foo" > /tmp/foo.txt'
|
25
|
+
#
|
26
|
+
# package :foo, :ensure => :installed
|
27
|
+
#
|
28
|
+
# file '/tmp/example.txt',
|
29
|
+
# :ensure => :present,
|
30
|
+
# :contents => Facter.to_hash_inspect,
|
31
|
+
# :require => package(:foo)
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# def lamp
|
35
|
+
# #install a basic LAMP stack
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# def ruby
|
39
|
+
# #install a ruby interpreter and tools
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# def mysql(options)
|
43
|
+
# #install a mysql server and set the root password to options[:root_password]
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# To execute the above manifest, instantiate it and call execute on it:
|
49
|
+
#
|
50
|
+
# m = ManifestExample.new
|
51
|
+
# m.execute
|
52
|
+
#
|
53
|
+
# As shown in the +sample+ method in ManifestExample above, instance
|
54
|
+
# methods are created for each Puppet::Type available on your system. These
|
55
|
+
# methods behave identally to the Puppet Resources methods. See here[http://reductivelabs.com/trac/puppet/wiki/TypeReference]
|
56
|
+
# for documentation on these methods.
|
57
|
+
#
|
58
|
+
# To view a list of all defined methods on your system, run:
|
59
|
+
#
|
60
|
+
# ruby -rubygems -e 'require "shadow_puppet";puts ShadowPuppet::Manifest.puppet_type_methods'
|
61
|
+
#
|
62
|
+
# The use of methods (+sample+, +lamp+, +ruby+, and +mysql+ above) as a
|
63
|
+
# container for resources facilitates recipie re-use through the use of Ruby
|
64
|
+
# Modules. For example:
|
65
|
+
#
|
66
|
+
# module ApachePuppet
|
67
|
+
# # Required options:
|
68
|
+
# # domain
|
69
|
+
# # path
|
70
|
+
# def php_vhost(options)
|
71
|
+
# #...
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# class MyWebMainfest < ShadowPuppet::Manifest
|
76
|
+
# include ApachePuppet
|
77
|
+
# recipe :php_vhost, {
|
78
|
+
# :domain => 'foo.com',
|
79
|
+
# :path => '/var/www/apps/foo'
|
80
|
+
# }
|
81
|
+
# end
|
82
|
+
class Manifest
|
83
|
+
|
84
|
+
class_inheritable_accessor :recipes
|
85
|
+
self.recipes = []
|
86
|
+
attr_reader :puppet_resources
|
87
|
+
|
88
|
+
# Initialize a new instance of this manifest. This can take a hash of
|
89
|
+
# options that are avaliable later via the options method.
|
90
|
+
def initialize(options = {})
|
91
|
+
unless Process.uid == 0
|
92
|
+
Puppet[:confdir] = File.expand_path("~/.puppet")
|
93
|
+
Puppet[:vardir] = File.expand_path("~/.puppet/var")
|
94
|
+
end
|
95
|
+
Puppet[:user] = Process.uid
|
96
|
+
Puppet[:group] = Process.gid
|
97
|
+
Puppet::Util::Log.newdestination(:console)
|
98
|
+
Puppet::Util::Log.level = :info
|
99
|
+
|
100
|
+
@options = HashWithIndifferentAccess.new(options)
|
101
|
+
@executed = false
|
102
|
+
@puppet_resources = Hash.new do |hash, key|
|
103
|
+
hash[key] = {}
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Declares that the named method or methods will be called whenever
|
108
|
+
# execute is called on an instance of this class. If the last argument is
|
109
|
+
# a Hash, this hash is passed as an argument to all provided methods.
|
110
|
+
# Subclasses of the Manifest class properly inherit the parent classes'
|
111
|
+
# calls to recipe.
|
112
|
+
def self.recipe(*methods)
|
113
|
+
return nil if methods.nil? || methods == []
|
114
|
+
options = methods.extract_options!
|
115
|
+
methods.each do |meth|
|
116
|
+
recipes << [meth.to_sym, options]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#An array of all methods defined for creation of Puppet Resources
|
121
|
+
def self.puppet_type_methods
|
122
|
+
Puppet::Type.eachtype { |t| t.name }.keys.map { |n| n.to_s }.sort.inspect
|
123
|
+
end
|
124
|
+
|
125
|
+
# A HashWithIndifferentAccess[http://api.rubyonrails.com/classes/HashWithIndifferentAccess.html]
|
126
|
+
# containing the options passed into the initialize method. Useful to pass
|
127
|
+
# things not already in Facter.
|
128
|
+
def options
|
129
|
+
@options
|
130
|
+
end
|
131
|
+
|
132
|
+
#Create an instance method for every type that either creates or references
|
133
|
+
#a resource
|
134
|
+
Puppet::Type.loadall
|
135
|
+
Puppet::Type.eachtype do |type|
|
136
|
+
#undefine the method rdoc placeholders
|
137
|
+
undef_method(type.name) rescue nil
|
138
|
+
define_method(type.name) do |*args|
|
139
|
+
if args && args.flatten.size == 1
|
140
|
+
reference(type.name, args.first)
|
141
|
+
else
|
142
|
+
new_resource(type, args.first, args.last)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Returns true if this Manifest <tt>respond_to?</tt> all methods named by
|
148
|
+
# calls to recipe, and if this Manifest has not been executed before.
|
149
|
+
def executable?
|
150
|
+
self.class.recipes.each do |meth,args|
|
151
|
+
return false unless respond_to?(meth)
|
152
|
+
end
|
153
|
+
return false if executed?
|
154
|
+
true
|
155
|
+
end
|
156
|
+
|
157
|
+
# Execute this manifest, applying all resources defined. By default, this
|
158
|
+
# will only execute a manifest that is executable?. The +force+ argument,
|
159
|
+
# if true, removes this check.
|
160
|
+
def execute(force=false)
|
161
|
+
return false unless executable? || force
|
162
|
+
evaluate_recipes
|
163
|
+
apply
|
164
|
+
rescue Exception => e
|
165
|
+
raise e
|
166
|
+
else
|
167
|
+
true
|
168
|
+
ensure
|
169
|
+
@executed = true
|
170
|
+
end
|
171
|
+
|
172
|
+
protected
|
173
|
+
|
174
|
+
#Has this manifest instance been executed?
|
175
|
+
def executed?
|
176
|
+
@executed
|
177
|
+
end
|
178
|
+
|
179
|
+
#An Array of all currently defined resources.
|
180
|
+
def flat_resources
|
181
|
+
a = []
|
182
|
+
@puppet_resources.each_value do |by_type|
|
183
|
+
by_type.each_value do |by_name|
|
184
|
+
a << by_name
|
185
|
+
end
|
186
|
+
end
|
187
|
+
a
|
188
|
+
end
|
189
|
+
|
190
|
+
#A Puppet::TransBucket of all defined resoureces.
|
191
|
+
def export
|
192
|
+
transportable_objects = flat_resources.dup.reject { |a| a.nil? }.flatten.collect do |obj|
|
193
|
+
obj.to_trans
|
194
|
+
end
|
195
|
+
b = Puppet::TransBucket.new(transportable_objects)
|
196
|
+
b.name = "shadow_puppet:#{object_id}"
|
197
|
+
b.type = "class"
|
198
|
+
|
199
|
+
return b
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
#Evaluate the methods calls queued in self.recipes
|
205
|
+
def evaluate_recipes
|
206
|
+
self.class.recipes.each do |meth, args|
|
207
|
+
case arity = method(meth).arity
|
208
|
+
when 1, -1
|
209
|
+
send(meth, args)
|
210
|
+
else
|
211
|
+
send(meth)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Create a catalog of all contained Puppet Resources and apply that
|
217
|
+
# catalog to the currently running system
|
218
|
+
def apply(bucket = nil)
|
219
|
+
bucket ||= export()
|
220
|
+
catalog = bucket.to_catalog
|
221
|
+
catalog.apply
|
222
|
+
end
|
223
|
+
|
224
|
+
def scope #:nodoc:
|
225
|
+
unless defined?(@scope)
|
226
|
+
# Set the code to something innocuous; we just need the
|
227
|
+
# scopes, not the interpreter. Hackish, but true.
|
228
|
+
Puppet[:code] = " "
|
229
|
+
@interp = Puppet::Parser::Interpreter.new
|
230
|
+
require 'puppet/node'
|
231
|
+
@node = Puppet::Node.new(Facter.value(:hostname))
|
232
|
+
if env = Puppet[:environment] and env == ""
|
233
|
+
env = nil
|
234
|
+
end
|
235
|
+
@node.parameters = Facter.to_hash
|
236
|
+
@compile = Puppet::Parser::Compiler.new(@node, @interp.send(:parser, env))
|
237
|
+
@scope = @compile.topscope
|
238
|
+
end
|
239
|
+
@scope
|
240
|
+
end
|
241
|
+
|
242
|
+
#Create a reference to another Puppet Resource.
|
243
|
+
def reference(type, title)
|
244
|
+
Puppet::Parser::Resource::Reference.new(:type => type.to_s, :title => title.to_s, :scope => scope)
|
245
|
+
end
|
246
|
+
|
247
|
+
#Creates a new Puppet Resource.
|
248
|
+
def new_resource(type, name, params = {})
|
249
|
+
unless obj = @puppet_resources[type][name]
|
250
|
+
obj = Puppet::Parser::Resource.new(
|
251
|
+
:title => name,
|
252
|
+
:type => type.name,
|
253
|
+
:source => self,
|
254
|
+
:scope => scope
|
255
|
+
)
|
256
|
+
@puppet_resources[type][name] = obj
|
257
|
+
end
|
258
|
+
|
259
|
+
params.each do |param_name, param_value|
|
260
|
+
param = Puppet::Parser::Resource::Param.new(
|
261
|
+
:name => param_name,
|
262
|
+
:value => param_value,
|
263
|
+
:source => self
|
264
|
+
)
|
265
|
+
obj.send(:set_parameter, param)
|
266
|
+
end
|
267
|
+
|
268
|
+
obj
|
269
|
+
end
|
270
|
+
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
Dir.glob(File.join(File.dirname(__FILE__), '..', 'facts', '*.rb')).each do |fact|
|
275
|
+
require fact
|
276
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shadow_puppet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jesse Newland
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-27 00:00:00 -05:00
|
13
|
+
default_executable: shadow_puppet
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: puppet
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.24.6
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: facter
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.5.2
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: highline
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.5.0
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: builder
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.1.2
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
type: :runtime
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 2.2.2
|
64
|
+
version:
|
65
|
+
description: A Ruby Puppet DSL
|
66
|
+
email:
|
67
|
+
- jesse@railsmachine.com
|
68
|
+
executables:
|
69
|
+
- shadow_puppet
|
70
|
+
extensions: []
|
71
|
+
|
72
|
+
extra_rdoc_files:
|
73
|
+
- README.rdoc
|
74
|
+
- bin/shadow_puppet
|
75
|
+
files:
|
76
|
+
- README.rdoc
|
77
|
+
- LICENSE
|
78
|
+
- bin/shadow_puppet
|
79
|
+
- lib/shadow_puppet.rb
|
80
|
+
- lib/shadow_puppet/manifest.rb
|
81
|
+
has_rdoc: true
|
82
|
+
homepage: http://railsmachine.github.com/shadow_puppet
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options:
|
85
|
+
- --main
|
86
|
+
- README.rdoc
|
87
|
+
- --inline-source
|
88
|
+
- --webcvs=http://github.com/railsmachine/shadow_puppet/tree/master/
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: "0"
|
96
|
+
version:
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
version:
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: moonshine
|
106
|
+
rubygems_version: 1.3.1
|
107
|
+
signing_key:
|
108
|
+
specification_version: 2
|
109
|
+
summary: A Ruby Puppet DSL
|
110
|
+
test_files: []
|
111
|
+
|