corl 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitmodules +4 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +123 -0
- data/LICENSE.txt +674 -0
- data/README.rdoc +27 -0
- data/Rakefile +78 -0
- data/VERSION +1 -0
- data/bin/corl +55 -0
- data/corl.gemspec +228 -0
- data/lib/corl/action/add.rb +69 -0
- data/lib/corl/action/bootstrap.rb +83 -0
- data/lib/corl/action/clone.rb +40 -0
- data/lib/corl/action/create.rb +55 -0
- data/lib/corl/action/exec.rb +41 -0
- data/lib/corl/action/extract.rb +49 -0
- data/lib/corl/action/image.rb +30 -0
- data/lib/corl/action/images.rb +55 -0
- data/lib/corl/action/lookup.rb +35 -0
- data/lib/corl/action/machines.rb +51 -0
- data/lib/corl/action/provision.rb +37 -0
- data/lib/corl/action/remove.rb +51 -0
- data/lib/corl/action/save.rb +53 -0
- data/lib/corl/action/seed.rb +115 -0
- data/lib/corl/action/spawn.rb +75 -0
- data/lib/corl/action/start.rb +37 -0
- data/lib/corl/action/stop.rb +30 -0
- data/lib/corl/action/update.rb +37 -0
- data/lib/corl/command/shell.rb +164 -0
- data/lib/corl/configuration/file.rb +386 -0
- data/lib/corl/event/puppet.rb +90 -0
- data/lib/corl/event/regex.rb +52 -0
- data/lib/corl/extension/puppetloader.rb +24 -0
- data/lib/corl/machine/fog.rb +310 -0
- data/lib/corl/machine/physical.rb +161 -0
- data/lib/corl/network/default.rb +26 -0
- data/lib/corl/node/aws.rb +90 -0
- data/lib/corl/node/fog.rb +198 -0
- data/lib/corl/node/google.rb +115 -0
- data/lib/corl/node/local.rb +26 -0
- data/lib/corl/node/rackspace.rb +89 -0
- data/lib/corl/project/git.rb +465 -0
- data/lib/corl/project/github.rb +108 -0
- data/lib/corl/provisioner/puppetnode/resource.rb +245 -0
- data/lib/corl/provisioner/puppetnode/resource_group.rb +205 -0
- data/lib/corl/provisioner/puppetnode.rb +407 -0
- data/lib/corl/template/environment.rb +73 -0
- data/lib/corl/template/json.rb +16 -0
- data/lib/corl/template/wrapper.rb +16 -0
- data/lib/corl/template/yaml.rb +16 -0
- data/lib/corl/translator/json.rb +27 -0
- data/lib/corl/translator/yaml.rb +27 -0
- data/lib/corl.rb +173 -0
- data/lib/corl_core/codes.rb +107 -0
- data/lib/corl_core/config/collection.rb +57 -0
- data/lib/corl_core/config/options.rb +70 -0
- data/lib/corl_core/config.rb +337 -0
- data/lib/corl_core/core.rb +59 -0
- data/lib/corl_core/corl.rb +254 -0
- data/lib/corl_core/errors.rb +84 -0
- data/lib/corl_core/facade.rb +126 -0
- data/lib/corl_core/gems.rb +72 -0
- data/lib/corl_core/manager.rb +425 -0
- data/lib/corl_core/mixin/action/commit.rb +58 -0
- data/lib/corl_core/mixin/action/keypair.rb +105 -0
- data/lib/corl_core/mixin/action/node.rb +129 -0
- data/lib/corl_core/mixin/action/project.rb +53 -0
- data/lib/corl_core/mixin/action/push.rb +52 -0
- data/lib/corl_core/mixin/config/collection.rb +53 -0
- data/lib/corl_core/mixin/config/ops.rb +53 -0
- data/lib/corl_core/mixin/config/options.rb +39 -0
- data/lib/corl_core/mixin/lookup.rb +196 -0
- data/lib/corl_core/mixin/macro/object_interface.rb +361 -0
- data/lib/corl_core/mixin/macro/plugin_interface.rb +380 -0
- data/lib/corl_core/mixin/settings.rb +46 -0
- data/lib/corl_core/mixin/sub_config.rb +148 -0
- data/lib/corl_core/mod/hash.rb +29 -0
- data/lib/corl_core/mod/hiera_backend.rb +63 -0
- data/lib/corl_core/plugin/action.rb +381 -0
- data/lib/corl_core/plugin/base.rb +374 -0
- data/lib/corl_core/plugin/command.rb +98 -0
- data/lib/corl_core/plugin/configuration.rb +177 -0
- data/lib/corl_core/plugin/event.rb +53 -0
- data/lib/corl_core/plugin/extension.rb +12 -0
- data/lib/corl_core/plugin/machine.rb +266 -0
- data/lib/corl_core/plugin/network.rb +359 -0
- data/lib/corl_core/plugin/node.rb +904 -0
- data/lib/corl_core/plugin/project.rb +927 -0
- data/lib/corl_core/plugin/provisioner.rb +51 -0
- data/lib/corl_core/plugin/template.rb +80 -0
- data/lib/corl_core/plugin/translator.rb +38 -0
- data/lib/corl_core/util/cli.rb +352 -0
- data/lib/corl_core/util/data.rb +404 -0
- data/lib/corl_core/util/disk.rb +114 -0
- data/lib/corl_core/util/git.rb +47 -0
- data/lib/corl_core/util/interface.rb +319 -0
- data/lib/corl_core/util/liquid.rb +17 -0
- data/lib/corl_core/util/package.rb +93 -0
- data/lib/corl_core/util/shell.rb +239 -0
- data/lib/corl_core/util/ssh.rb +286 -0
- data/lib/facter/corl_config_ready.rb +13 -0
- data/lib/facter/corl_exists.rb +15 -0
- data/lib/facter/corl_network.rb +17 -0
- data/lib/hiera/corl_logger.rb +18 -0
- data/lib/puppet/indirector/corl.rb +27 -0
- data/lib/puppet/indirector/data_binding/corl.rb +6 -0
- data/lib/puppet/parser/functions/config_initialized.rb +26 -0
- data/lib/puppet/parser/functions/corl_include.rb +44 -0
- data/lib/puppet/parser/functions/corl_resources.rb +58 -0
- data/lib/puppet/parser/functions/deep_merge.rb +21 -0
- data/lib/puppet/parser/functions/ensure.rb +29 -0
- data/lib/puppet/parser/functions/file_exists.rb +19 -0
- data/lib/puppet/parser/functions/global_array.rb +35 -0
- data/lib/puppet/parser/functions/global_hash.rb +35 -0
- data/lib/puppet/parser/functions/global_options.rb +23 -0
- data/lib/puppet/parser/functions/global_param.rb +43 -0
- data/lib/puppet/parser/functions/interpolate.rb +26 -0
- data/lib/puppet/parser/functions/is_false.rb +21 -0
- data/lib/puppet/parser/functions/is_true.rb +21 -0
- data/lib/puppet/parser/functions/module_array.rb +38 -0
- data/lib/puppet/parser/functions/module_hash.rb +38 -0
- data/lib/puppet/parser/functions/module_options.rb +23 -0
- data/lib/puppet/parser/functions/module_param.rb +48 -0
- data/lib/puppet/parser/functions/name.rb +21 -0
- data/lib/puppet/parser/functions/render.rb +33 -0
- data/lib/puppet/parser/functions/value.rb +21 -0
- data/locales/en.yml +232 -0
- data/spec/corl_core/interface_spec.rb +489 -0
- data/spec/corl_mock_input.rb +29 -0
- data/spec/corl_test_kernel.rb +22 -0
- data/spec/spec_helper.rb +15 -0
- metadata +406 -0
@@ -0,0 +1,286 @@
|
|
1
|
+
|
2
|
+
module CORL
|
3
|
+
module Util
|
4
|
+
class SSH < Core
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# User key home
|
8
|
+
|
9
|
+
@@key_path = nil
|
10
|
+
|
11
|
+
#---
|
12
|
+
|
13
|
+
def self.key_path
|
14
|
+
unless @@key_path
|
15
|
+
home_path = ( ENV['USER'] == 'root' ? '/root' : ENV['HOME'] ) # In case we are using sudo
|
16
|
+
@@key_path = File.join(home_path, '.ssh')
|
17
|
+
|
18
|
+
FileUtils.mkdir(@@key_path) unless File.directory?(@@key_path)
|
19
|
+
end
|
20
|
+
@@key_path
|
21
|
+
end
|
22
|
+
|
23
|
+
#-----------------------------------------------------------------------------
|
24
|
+
# Instance generators
|
25
|
+
|
26
|
+
def self.generate(options = {})
|
27
|
+
config = Config.ensure(options)
|
28
|
+
|
29
|
+
private_key = config.get(:private_key, nil)
|
30
|
+
original_key = nil
|
31
|
+
key_comment = config.get(:comment, '')
|
32
|
+
|
33
|
+
if private_key.nil?
|
34
|
+
key_type = config.get(:type, "RSA")
|
35
|
+
key_bits = config.get(:bits, 2048)
|
36
|
+
passphrase = config.get(:passphrase, nil)
|
37
|
+
|
38
|
+
key_data = SSHKey.generate(
|
39
|
+
:type => key_type,
|
40
|
+
:bits => key_bits,
|
41
|
+
:comment => key_comment,
|
42
|
+
:passphrase => passphrase
|
43
|
+
)
|
44
|
+
is_new = true
|
45
|
+
|
46
|
+
else
|
47
|
+
if private_key.include?('PRIVATE KEY')
|
48
|
+
original_key = private_key
|
49
|
+
else
|
50
|
+
original_key = Disk.read(private_key)
|
51
|
+
end
|
52
|
+
|
53
|
+
key_data = SSHKey.new(original_key, :comment => key_comment) if original_key
|
54
|
+
is_new = false
|
55
|
+
end
|
56
|
+
|
57
|
+
return nil unless key_data && ! key_data.ssh_public_key.empty?
|
58
|
+
Keypair.new(key_data, is_new, original_key)
|
59
|
+
end
|
60
|
+
|
61
|
+
#-----------------------------------------------------------------------------
|
62
|
+
# Checks
|
63
|
+
|
64
|
+
def self.valid?(public_ssh_key)
|
65
|
+
SSHKey.valid_ssh_public_key?(public_ssh_key)
|
66
|
+
end
|
67
|
+
|
68
|
+
#-----------------------------------------------------------------------------
|
69
|
+
# Keypair interface
|
70
|
+
|
71
|
+
class Keypair
|
72
|
+
attr_reader :type, :private_key, :encrypted_key, :public_key, :ssh_key
|
73
|
+
|
74
|
+
def initialize(key_data, is_new, original_key)
|
75
|
+
@type = key_data.type
|
76
|
+
@private_key = key_data.private_key
|
77
|
+
@encrypted_key = is_new ? key_data.encrypted_private_key : original_key
|
78
|
+
@public_key = key_data.public_key
|
79
|
+
@ssh_key = key_data.ssh_public_key
|
80
|
+
end
|
81
|
+
|
82
|
+
#---
|
83
|
+
|
84
|
+
def store(key_path = nil, key_base = 'id')
|
85
|
+
key_path = SSH.key_path if key_path.nil?
|
86
|
+
private_key_file = File.join(key_path, "#{key_base}_#{type.downcase}")
|
87
|
+
public_key_file = File.join(key_path, "#{key_base}_#{type.downcase}.pub")
|
88
|
+
|
89
|
+
private_success = Disk.write(private_key_file, encrypted_key)
|
90
|
+
FileUtils.chmod(0600, private_key_file) if private_success
|
91
|
+
|
92
|
+
public_success = Disk.write(public_key_file, ssh_key)
|
93
|
+
|
94
|
+
if private_success && public_success
|
95
|
+
return { :private_key => private_key_file, :public_key => public_key_file }
|
96
|
+
end
|
97
|
+
false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#-----------------------------------------------------------------------------
|
102
|
+
# SSH Execution interface
|
103
|
+
|
104
|
+
@@sessions = {}
|
105
|
+
|
106
|
+
#---
|
107
|
+
|
108
|
+
def self.session_id(hostname, user)
|
109
|
+
"#{hostname}-#{user}"
|
110
|
+
end
|
111
|
+
|
112
|
+
#---
|
113
|
+
|
114
|
+
def self.session(hostname, user, port = 22, private_key = nil, reset = false, options = {})
|
115
|
+
require 'net/ssh'
|
116
|
+
|
117
|
+
ssh_options = Config.new({
|
118
|
+
:user_known_hosts_file => [ File.join(key_path, 'known_hosts'), File.join(key_path, 'known_hosts2') ],
|
119
|
+
:key_data => [],
|
120
|
+
:keys_only => false,
|
121
|
+
:auth_methods => [ 'publickey' ],
|
122
|
+
:paranoid => :very
|
123
|
+
}).import(options)
|
124
|
+
|
125
|
+
ssh_options[:port] = port
|
126
|
+
ssh_options[:keys] = private_key.nil? ? [] : [ private_key ]
|
127
|
+
|
128
|
+
session_id = session_id(hostname, user)
|
129
|
+
|
130
|
+
if reset || ! @@sessions.has_key?(session_id)
|
131
|
+
@@sessions[session_id] = Net::SSH.start(hostname, user, ssh_options.export)
|
132
|
+
end
|
133
|
+
yield(@@sessions[session_id]) if block_given? && @@sessions[session_id]
|
134
|
+
@@sessions[session_id]
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.init_session(hostname, user, port = 22, private_key = nil, options = {})
|
138
|
+
session(hostname, user, port, private_key, true, options)
|
139
|
+
end
|
140
|
+
|
141
|
+
#---
|
142
|
+
|
143
|
+
def self.close(hostname = nil, user = nil)
|
144
|
+
if hostname && user.nil? # Assume we entered a session id
|
145
|
+
if @@sessions.has_key?(hostname)
|
146
|
+
@@sessions[hostname].close
|
147
|
+
@@sessions.delete(hostname)
|
148
|
+
end
|
149
|
+
|
150
|
+
elsif hostname && user # Generate session id from args
|
151
|
+
session_id = session_id(hostname, user)
|
152
|
+
|
153
|
+
if @@sessions.has_key?(session_id)
|
154
|
+
@@sessions[session_id].close
|
155
|
+
@@sessions.delete(session_id)
|
156
|
+
end
|
157
|
+
|
158
|
+
else # Close all connections
|
159
|
+
@@sessions.keys.each do |id|
|
160
|
+
@@sessions[id].close
|
161
|
+
@@sessions.delete(id)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
#---
|
167
|
+
|
168
|
+
def self.exec(hostname, user, commands)
|
169
|
+
results = []
|
170
|
+
|
171
|
+
begin
|
172
|
+
session(hostname, user) do |ssh|
|
173
|
+
Data.array(commands).each do |command|
|
174
|
+
command = command.flatten.join(' ') if command.is_a?(Array)
|
175
|
+
command = command.to_s
|
176
|
+
result = Shell::Result.new(command)
|
177
|
+
|
178
|
+
ssh.open_channel do |ssh_channel|
|
179
|
+
ssh_channel.request_pty
|
180
|
+
ssh_channel.exec(command) do |channel, success|
|
181
|
+
unless success
|
182
|
+
raise "Could not execute command: #{command.inspect}"
|
183
|
+
end
|
184
|
+
|
185
|
+
channel.on_data do |ch, data|
|
186
|
+
result.append_output(data)
|
187
|
+
yield(:output, command, data) if block_given?
|
188
|
+
end
|
189
|
+
|
190
|
+
channel.on_extended_data do |ch, type, data|
|
191
|
+
next unless type == 1
|
192
|
+
result.append_errors(data)
|
193
|
+
yield(:error, command, data) if block_given?
|
194
|
+
end
|
195
|
+
|
196
|
+
channel.on_request('exit-status') do |ch, data|
|
197
|
+
result.status = data.read_long
|
198
|
+
end
|
199
|
+
|
200
|
+
channel.on_request('exit-signal') do |ch, data|
|
201
|
+
result.status = 255
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
ssh.loop
|
206
|
+
results << result
|
207
|
+
end
|
208
|
+
end
|
209
|
+
rescue Net::SSH::HostKeyMismatch => error
|
210
|
+
error.remember_host!
|
211
|
+
sleep 0.2
|
212
|
+
retry
|
213
|
+
end
|
214
|
+
results
|
215
|
+
end
|
216
|
+
|
217
|
+
#---
|
218
|
+
|
219
|
+
def self.download(hostname, user, remote_path, local_path, options = {})
|
220
|
+
config = Config.ensure(options)
|
221
|
+
|
222
|
+
require 'net/scp'
|
223
|
+
|
224
|
+
# Accepted options:
|
225
|
+
# * :recursive - the +remote+ parameter refers to a remote directory, which
|
226
|
+
# should be downloaded to a new directory named +local+ on the local
|
227
|
+
# machine.
|
228
|
+
# * :preserve - the atime and mtime of the file should be preserved.
|
229
|
+
# * :verbose - the process should result in verbose output on the server
|
230
|
+
# end (useful for debugging).
|
231
|
+
#
|
232
|
+
config.init(:recursive, true)
|
233
|
+
config.init(:preserve, true)
|
234
|
+
config.init(:verbose, true)
|
235
|
+
|
236
|
+
blocking = config.delete(:blocking, true)
|
237
|
+
|
238
|
+
session(hostname, user) do |ssh|
|
239
|
+
if blocking
|
240
|
+
ssh.scp.download!(remote_path, local_path, config.export) do |ch, name, received, total|
|
241
|
+
yield(name, received, total) if block_given?
|
242
|
+
end
|
243
|
+
else
|
244
|
+
ssh.scp.download(remote_path, local_path, config.export)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
#---
|
250
|
+
|
251
|
+
def self.upload(hostname, user, local_path, remote_path, options = {})
|
252
|
+
config = Config.ensure(options)
|
253
|
+
|
254
|
+
require 'net/scp'
|
255
|
+
|
256
|
+
# Accepted options:
|
257
|
+
# * :recursive - the +local+ parameter refers to a local directory, which
|
258
|
+
# should be uploaded to a new directory named +remote+ on the remote
|
259
|
+
# server.
|
260
|
+
# * :preserve - the atime and mtime of the file should be preserved.
|
261
|
+
# * :verbose - the process should result in verbose output on the server
|
262
|
+
# end (useful for debugging).
|
263
|
+
# * :chunk_size - the size of each "chunk" that should be sent. Defaults
|
264
|
+
# to 2048. Changing this value may improve throughput at the expense
|
265
|
+
# of decreasing interactivity.
|
266
|
+
#
|
267
|
+
config.init(:recursive, true)
|
268
|
+
config.init(:preserve, true)
|
269
|
+
config.init(:verbose, true)
|
270
|
+
config.init(:chunk_size, 2048)
|
271
|
+
|
272
|
+
blocking = config.delete(:blocking, true)
|
273
|
+
|
274
|
+
session(hostname, user) do |ssh|
|
275
|
+
if blocking
|
276
|
+
ssh.scp.upload!(local_path, remote_path, config.export) do |ch, name, sent, total|
|
277
|
+
yield(name, sent, total) if block_given?
|
278
|
+
end
|
279
|
+
else
|
280
|
+
ssh.scp.upload(local_path, remote_path, config.export)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
Facter.add(:corl_exists) do
|
3
|
+
confine :kernel => :linux
|
4
|
+
|
5
|
+
setcode do
|
6
|
+
begin
|
7
|
+
Facter::Util::Resolution::exec('gem list corl -i 2> /dev/null')
|
8
|
+
corl_exists = true if $?.exitstatus == 0
|
9
|
+
|
10
|
+
rescue Exception # Prevent abortions.
|
11
|
+
end
|
12
|
+
|
13
|
+
corl_exists ? true : nil
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
Facter.add(:corl_network) do
|
3
|
+
confine :kernel => :linux
|
4
|
+
|
5
|
+
setcode do
|
6
|
+
require 'corl'
|
7
|
+
|
8
|
+
network_path = '/var/corl'
|
9
|
+
|
10
|
+
CORL.exec(:network_location) do |op, results|
|
11
|
+
if op == :process
|
12
|
+
network_path = results unless results.nil? || ! File.directory?(results)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
network_path
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
class Hiera
|
3
|
+
module CORL_logger
|
4
|
+
class << self
|
5
|
+
def suitable?
|
6
|
+
defined?(::CORL) == "constant"
|
7
|
+
end
|
8
|
+
|
9
|
+
def warn(message)
|
10
|
+
::CORL.logger.warn("hiera: #{message}")
|
11
|
+
end
|
12
|
+
|
13
|
+
def debug(message)
|
14
|
+
::CORL.logger.debug("hiera: #{message}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
require 'puppet/indirector/terminus'
|
3
|
+
|
4
|
+
class Puppet::Indirector::CORL < Puppet::Indirector::Terminus
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
unless CORL::Config.initialized?
|
8
|
+
raise "CORL terminus not supported without the CORL library"
|
9
|
+
end
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
#---
|
14
|
+
|
15
|
+
def find(request)
|
16
|
+
config = CORL::Config.init({}, [ :all, :param, :data_binding ], {
|
17
|
+
:hiera_scope => request.options[:variables],
|
18
|
+
:puppet_scope => request.options[:variables],
|
19
|
+
:search => 'core::default',
|
20
|
+
:search_name => false,
|
21
|
+
:init_fact => 'corl_config_ready',
|
22
|
+
:force => true,
|
23
|
+
:merge => true
|
24
|
+
})
|
25
|
+
value = CORL::Config.lookup(request.key, nil, config)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# config_initialized.rb
|
3
|
+
#
|
4
|
+
# This function checks if the configuration system is fully configured
|
5
|
+
# and ready to query.
|
6
|
+
#
|
7
|
+
module Puppet::Parser::Functions
|
8
|
+
newfunction(:config_initialized, :type => :rvalue, :doc => <<-EOS
|
9
|
+
This function checks if Hiera is fully configured and ready to query.
|
10
|
+
EOS
|
11
|
+
) do |args|
|
12
|
+
|
13
|
+
value = nil
|
14
|
+
CORL.run do
|
15
|
+
options = ( args[0].is_a?(Hash) ? args[0] : {} )
|
16
|
+
|
17
|
+
config = CORL::Config.init_flat(options, [ :init, :config_initialized ], {
|
18
|
+
:hiera_scope => self,
|
19
|
+
:puppet_scope => self,
|
20
|
+
:init_fact => 'corl_config_ready'
|
21
|
+
})
|
22
|
+
value = CORL::Config.initialized?(config)
|
23
|
+
end
|
24
|
+
return value
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#
|
2
|
+
# corl_include.rb
|
3
|
+
#
|
4
|
+
# This function includes classes based on dynamic configurations.
|
5
|
+
# following this order
|
6
|
+
# - Hiera backend, if present (no prefix)
|
7
|
+
# - ::data::default::varname
|
8
|
+
# - ::varname
|
9
|
+
# - {default parameter}
|
10
|
+
#
|
11
|
+
module Puppet::Parser::Functions
|
12
|
+
newfunction(:corl_include, :doc => <<-EOS
|
13
|
+
This function performs a lookup for a variable value in various locations following this order:
|
14
|
+
- Hiera backend, if present (no prefix)
|
15
|
+
- ::data::default::varname
|
16
|
+
- ::varname
|
17
|
+
- {default parameter}
|
18
|
+
If no value is found in the defined sources, it does not include any classes.
|
19
|
+
EOS
|
20
|
+
) do |args|
|
21
|
+
|
22
|
+
CORL.run do
|
23
|
+
raise(Puppet::ParseError, "corl_include(): Define at least the variable name " +
|
24
|
+
"given (#{args.size} for 1)") if args.size < 1
|
25
|
+
|
26
|
+
var_name = args[0]
|
27
|
+
parameters = ( args.size > 1 ? args[1] : {} )
|
28
|
+
options = ( args.size > 2 ? args[2] : {} )
|
29
|
+
|
30
|
+
unless CORL.provisioner(:puppet).include(var_name, parameters, options)
|
31
|
+
# Throw an error if we didn't evaluate all of the classes.
|
32
|
+
str = "Could not find class"
|
33
|
+
str += "es" if missing.length > 1
|
34
|
+
|
35
|
+
str += " " + missing.join(", ")
|
36
|
+
|
37
|
+
if n = namespaces and ! n.empty? and n != [""]
|
38
|
+
str += " in namespaces #{@namespaces.join(", ")}"
|
39
|
+
end
|
40
|
+
self.fail Puppet::ParseError, str
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#
|
2
|
+
# corl_resources.rb
|
3
|
+
#
|
4
|
+
# This function adds resource definitions of a specific type to the Puppet catalog
|
5
|
+
# - Requires
|
6
|
+
# - -> Puppet resource definition name (define)
|
7
|
+
# - -> Hiera lookup name (full name)
|
8
|
+
# - Optional
|
9
|
+
# - -> default values for new resources
|
10
|
+
# If no resources are found, it returns without creating anything.
|
11
|
+
#
|
12
|
+
module Puppet::Parser::Functions
|
13
|
+
newfunction(:corl_resources, :doc => <<-EOS
|
14
|
+
This function adds resource definitions of a specific type to the Puppet catalog
|
15
|
+
- Requires
|
16
|
+
- -> Puppet resource definition name (define)
|
17
|
+
- -> Hiera lookup name (full name)
|
18
|
+
- Optional
|
19
|
+
- -> default values for new resources
|
20
|
+
If no resources are found, it returns without creating anything.
|
21
|
+
EOS
|
22
|
+
) do |args|
|
23
|
+
|
24
|
+
CORL.run do
|
25
|
+
raise(Puppet::ParseError, "corl_resources(): Define at least the resource type and optional variable name " +
|
26
|
+
"given (#{args.size} for 1)") if args.size < 1
|
27
|
+
|
28
|
+
definition_name = args[0]
|
29
|
+
type_name = definition_name.sub(/^\@?\@/, '')
|
30
|
+
|
31
|
+
resources = ( args[1] ? args[1] : definition_name )
|
32
|
+
defaults = ( args[2] ? args[2] : {} )
|
33
|
+
|
34
|
+
tag = ( args[3] ? args[3] : '' )
|
35
|
+
tag_var = tag.empty? ? '' : tag.gsub(/\_/, '::')
|
36
|
+
override_var = tag_var.empty? ? nil : "#{tag_var}::#{type_name}"
|
37
|
+
default_var = tag_var.empty? ? nil : "#{tag_var}::#{type_name}_defaults"
|
38
|
+
|
39
|
+
options = ( args[4] ? args[4] : {} )
|
40
|
+
|
41
|
+
config = CORL::Config.init_flat(options, [ :resource, :corl_resources ], {
|
42
|
+
:hiera_scope => self,
|
43
|
+
:puppet_scope => self,
|
44
|
+
:search => 'core::default',
|
45
|
+
:init_fact => 'hiera_ready',
|
46
|
+
:force => true,
|
47
|
+
:merge => true,
|
48
|
+
:resource_prefix => tag,
|
49
|
+
:title_prefix => tag
|
50
|
+
})
|
51
|
+
|
52
|
+
resources = CORL::Config.normalize(resources, override_var, config)
|
53
|
+
defaults = CORL::Config.normalize(defaults, default_var, config)
|
54
|
+
|
55
|
+
CORL.provisioner(:puppet).add(definition_name, resources, defaults, config)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# deep_merge.rb
|
3
|
+
#
|
4
|
+
# Merges multiple hashes together recursively.
|
5
|
+
#
|
6
|
+
module Puppet::Parser::Functions
|
7
|
+
newfunction(:deep_merge, :type => :rvalue, :doc => <<-EOS
|
8
|
+
This function Merges multiple hashes together recursively.
|
9
|
+
EOS
|
10
|
+
) do |args|
|
11
|
+
|
12
|
+
value = nil
|
13
|
+
CORL.run do
|
14
|
+
raise(Puppet::ParseError, "deep_merge(): Define at least one hash " +
|
15
|
+
"given (#{args.size} for 1)") if args.size < 1
|
16
|
+
|
17
|
+
value = CORL::Util::Data.merge(args)
|
18
|
+
end
|
19
|
+
return value
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# ensure.rb
|
3
|
+
#
|
4
|
+
# Checks a given test and returns the success value or a failure value based on test results.
|
5
|
+
#
|
6
|
+
module Puppet::Parser::Functions
|
7
|
+
newfunction(:ensure, :type => :rvalue, :doc => <<-EOS
|
8
|
+
This function checks a given test and returns the success value or a failure value based on test results.
|
9
|
+
EOS
|
10
|
+
) do |args|
|
11
|
+
|
12
|
+
value = nil
|
13
|
+
CORL.run do
|
14
|
+
raise(Puppet::ParseError, "ensure(): Must have at least a test and optional success and failure values specified; " +
|
15
|
+
"given (#{args.size} for 1)") if args.size < 1
|
16
|
+
|
17
|
+
test = args[0]
|
18
|
+
success_value = (args.size > 1 ? args[1] : test)
|
19
|
+
failure_value = (args.size > 2 ? args[2] : :undef)
|
20
|
+
|
21
|
+
#dbg(test, 'test')
|
22
|
+
#dbg(success_value, 'success')
|
23
|
+
|
24
|
+
value = CORL::Util::Data.ensure(test, success_value, failure_value)
|
25
|
+
#dbg(value, 'value')
|
26
|
+
end
|
27
|
+
return value
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# file_exists.rb
|
3
|
+
#
|
4
|
+
module Puppet::Parser::Functions
|
5
|
+
newfunction(:file_exists, :type => :rvalue, :doc => <<-EOS
|
6
|
+
Returns an boolean value if a given file and/or directory exists on Puppet Master.
|
7
|
+
EOS
|
8
|
+
) do |args|
|
9
|
+
|
10
|
+
value = nil
|
11
|
+
CORL.run do
|
12
|
+
raise(Puppet::ParseError, "file_exists(): Must have a file or directory name specified; " +
|
13
|
+
"given (#{args.size} for 1)") if args.size < 1
|
14
|
+
|
15
|
+
value = CORL::Data::Disk.exists?(args[0])
|
16
|
+
end
|
17
|
+
return value
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# global_array.rb
|
3
|
+
#
|
4
|
+
# See: global_param.rb
|
5
|
+
#
|
6
|
+
module Puppet::Parser::Functions
|
7
|
+
newfunction(:global_array, :type => :rvalue, :doc => <<-EOS
|
8
|
+
This function performs a lookup for a variable value in various locations:
|
9
|
+
See: global_params()
|
10
|
+
If no value is found in the defined sources, it returns an empty array ([])
|
11
|
+
EOS
|
12
|
+
) do |args|
|
13
|
+
|
14
|
+
value = nil
|
15
|
+
CORL.run do
|
16
|
+
raise(Puppet::ParseError, "global_array(): Define at least the variable name " +
|
17
|
+
"given (#{args.size} for 1)") if args.size < 1
|
18
|
+
|
19
|
+
var_name = args[0]
|
20
|
+
default = ( args.size > 1 ? args[1] : [] )
|
21
|
+
options = ( args.size > 2 ? args[2] : {} )
|
22
|
+
|
23
|
+
config = CORL::Config.init_flat(options, [ :param, :global_array ], {
|
24
|
+
:hiera_scope => self,
|
25
|
+
:puppet_scope => self,
|
26
|
+
:search => 'core::default',
|
27
|
+
:init_fact => 'hiera_ready',
|
28
|
+
:force => true,
|
29
|
+
:merge => true
|
30
|
+
})
|
31
|
+
value = CORL::Config.lookup_array(var_name, default, config)
|
32
|
+
end
|
33
|
+
return value
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# global_hash.rb
|
3
|
+
#
|
4
|
+
# See: global_param.rb
|
5
|
+
#
|
6
|
+
module Puppet::Parser::Functions
|
7
|
+
newfunction(:global_hash, :type => :rvalue, :doc => <<-EOS
|
8
|
+
This function performs a lookup for a variable value in various locations:
|
9
|
+
See: global_params()
|
10
|
+
If no value is found in the defined sources, it returns an empty hash ({})
|
11
|
+
EOS
|
12
|
+
) do |args|
|
13
|
+
|
14
|
+
value = nil
|
15
|
+
CORL.run do
|
16
|
+
raise(Puppet::ParseError, "global_hash(): Define at least the variable name " +
|
17
|
+
"given (#{args.size} for 1)") if args.size < 1
|
18
|
+
|
19
|
+
var_name = args[0]
|
20
|
+
default = ( args.size > 1 ? args[1] : {} )
|
21
|
+
options = ( args.size > 2 ? args[2] : {} )
|
22
|
+
|
23
|
+
config = CORL::Config.init_flat(options, [ :param, :global_hash ], {
|
24
|
+
:hiera_scope => self,
|
25
|
+
:puppet_scope => self,
|
26
|
+
:search => 'core::default',
|
27
|
+
:init_fact => 'hiera_ready',
|
28
|
+
:force => true,
|
29
|
+
:merge => true
|
30
|
+
})
|
31
|
+
value = CORL::Config.lookup_hash(var_name, default, config)
|
32
|
+
end
|
33
|
+
return value
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# global_options.rb
|
3
|
+
#
|
4
|
+
# This function sets globally available default options for other functions.
|
5
|
+
#
|
6
|
+
module Puppet::Parser::Functions
|
7
|
+
newfunction(:global_options, :doc => <<-EOS
|
8
|
+
This function sets globally available default options for other functions:
|
9
|
+
EOS
|
10
|
+
) do |args|
|
11
|
+
|
12
|
+
CORL.run do
|
13
|
+
raise(Puppet::ParseError, "global_options(): Define a context name and at least one option name/value pair: " +
|
14
|
+
"given (#{args.size} for 2)") if args.size < 2
|
15
|
+
|
16
|
+
contexts = args[0]
|
17
|
+
options = args[1]
|
18
|
+
force = ( args[2] ? true : false )
|
19
|
+
|
20
|
+
CORL::Config.set_options(contexts, options, force)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|