corl 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/.document +5 -0
  2. data/.gitmodules +4 -0
  3. data/Gemfile +24 -0
  4. data/Gemfile.lock +123 -0
  5. data/LICENSE.txt +674 -0
  6. data/README.rdoc +27 -0
  7. data/Rakefile +78 -0
  8. data/VERSION +1 -0
  9. data/bin/corl +55 -0
  10. data/corl.gemspec +228 -0
  11. data/lib/corl/action/add.rb +69 -0
  12. data/lib/corl/action/bootstrap.rb +83 -0
  13. data/lib/corl/action/clone.rb +40 -0
  14. data/lib/corl/action/create.rb +55 -0
  15. data/lib/corl/action/exec.rb +41 -0
  16. data/lib/corl/action/extract.rb +49 -0
  17. data/lib/corl/action/image.rb +30 -0
  18. data/lib/corl/action/images.rb +55 -0
  19. data/lib/corl/action/lookup.rb +35 -0
  20. data/lib/corl/action/machines.rb +51 -0
  21. data/lib/corl/action/provision.rb +37 -0
  22. data/lib/corl/action/remove.rb +51 -0
  23. data/lib/corl/action/save.rb +53 -0
  24. data/lib/corl/action/seed.rb +115 -0
  25. data/lib/corl/action/spawn.rb +75 -0
  26. data/lib/corl/action/start.rb +37 -0
  27. data/lib/corl/action/stop.rb +30 -0
  28. data/lib/corl/action/update.rb +37 -0
  29. data/lib/corl/command/shell.rb +164 -0
  30. data/lib/corl/configuration/file.rb +386 -0
  31. data/lib/corl/event/puppet.rb +90 -0
  32. data/lib/corl/event/regex.rb +52 -0
  33. data/lib/corl/extension/puppetloader.rb +24 -0
  34. data/lib/corl/machine/fog.rb +310 -0
  35. data/lib/corl/machine/physical.rb +161 -0
  36. data/lib/corl/network/default.rb +26 -0
  37. data/lib/corl/node/aws.rb +90 -0
  38. data/lib/corl/node/fog.rb +198 -0
  39. data/lib/corl/node/google.rb +115 -0
  40. data/lib/corl/node/local.rb +26 -0
  41. data/lib/corl/node/rackspace.rb +89 -0
  42. data/lib/corl/project/git.rb +465 -0
  43. data/lib/corl/project/github.rb +108 -0
  44. data/lib/corl/provisioner/puppetnode/resource.rb +245 -0
  45. data/lib/corl/provisioner/puppetnode/resource_group.rb +205 -0
  46. data/lib/corl/provisioner/puppetnode.rb +407 -0
  47. data/lib/corl/template/environment.rb +73 -0
  48. data/lib/corl/template/json.rb +16 -0
  49. data/lib/corl/template/wrapper.rb +16 -0
  50. data/lib/corl/template/yaml.rb +16 -0
  51. data/lib/corl/translator/json.rb +27 -0
  52. data/lib/corl/translator/yaml.rb +27 -0
  53. data/lib/corl.rb +173 -0
  54. data/lib/corl_core/codes.rb +107 -0
  55. data/lib/corl_core/config/collection.rb +57 -0
  56. data/lib/corl_core/config/options.rb +70 -0
  57. data/lib/corl_core/config.rb +337 -0
  58. data/lib/corl_core/core.rb +59 -0
  59. data/lib/corl_core/corl.rb +254 -0
  60. data/lib/corl_core/errors.rb +84 -0
  61. data/lib/corl_core/facade.rb +126 -0
  62. data/lib/corl_core/gems.rb +72 -0
  63. data/lib/corl_core/manager.rb +425 -0
  64. data/lib/corl_core/mixin/action/commit.rb +58 -0
  65. data/lib/corl_core/mixin/action/keypair.rb +105 -0
  66. data/lib/corl_core/mixin/action/node.rb +129 -0
  67. data/lib/corl_core/mixin/action/project.rb +53 -0
  68. data/lib/corl_core/mixin/action/push.rb +52 -0
  69. data/lib/corl_core/mixin/config/collection.rb +53 -0
  70. data/lib/corl_core/mixin/config/ops.rb +53 -0
  71. data/lib/corl_core/mixin/config/options.rb +39 -0
  72. data/lib/corl_core/mixin/lookup.rb +196 -0
  73. data/lib/corl_core/mixin/macro/object_interface.rb +361 -0
  74. data/lib/corl_core/mixin/macro/plugin_interface.rb +380 -0
  75. data/lib/corl_core/mixin/settings.rb +46 -0
  76. data/lib/corl_core/mixin/sub_config.rb +148 -0
  77. data/lib/corl_core/mod/hash.rb +29 -0
  78. data/lib/corl_core/mod/hiera_backend.rb +63 -0
  79. data/lib/corl_core/plugin/action.rb +381 -0
  80. data/lib/corl_core/plugin/base.rb +374 -0
  81. data/lib/corl_core/plugin/command.rb +98 -0
  82. data/lib/corl_core/plugin/configuration.rb +177 -0
  83. data/lib/corl_core/plugin/event.rb +53 -0
  84. data/lib/corl_core/plugin/extension.rb +12 -0
  85. data/lib/corl_core/plugin/machine.rb +266 -0
  86. data/lib/corl_core/plugin/network.rb +359 -0
  87. data/lib/corl_core/plugin/node.rb +904 -0
  88. data/lib/corl_core/plugin/project.rb +927 -0
  89. data/lib/corl_core/plugin/provisioner.rb +51 -0
  90. data/lib/corl_core/plugin/template.rb +80 -0
  91. data/lib/corl_core/plugin/translator.rb +38 -0
  92. data/lib/corl_core/util/cli.rb +352 -0
  93. data/lib/corl_core/util/data.rb +404 -0
  94. data/lib/corl_core/util/disk.rb +114 -0
  95. data/lib/corl_core/util/git.rb +47 -0
  96. data/lib/corl_core/util/interface.rb +319 -0
  97. data/lib/corl_core/util/liquid.rb +17 -0
  98. data/lib/corl_core/util/package.rb +93 -0
  99. data/lib/corl_core/util/shell.rb +239 -0
  100. data/lib/corl_core/util/ssh.rb +286 -0
  101. data/lib/facter/corl_config_ready.rb +13 -0
  102. data/lib/facter/corl_exists.rb +15 -0
  103. data/lib/facter/corl_network.rb +17 -0
  104. data/lib/hiera/corl_logger.rb +18 -0
  105. data/lib/puppet/indirector/corl.rb +27 -0
  106. data/lib/puppet/indirector/data_binding/corl.rb +6 -0
  107. data/lib/puppet/parser/functions/config_initialized.rb +26 -0
  108. data/lib/puppet/parser/functions/corl_include.rb +44 -0
  109. data/lib/puppet/parser/functions/corl_resources.rb +58 -0
  110. data/lib/puppet/parser/functions/deep_merge.rb +21 -0
  111. data/lib/puppet/parser/functions/ensure.rb +29 -0
  112. data/lib/puppet/parser/functions/file_exists.rb +19 -0
  113. data/lib/puppet/parser/functions/global_array.rb +35 -0
  114. data/lib/puppet/parser/functions/global_hash.rb +35 -0
  115. data/lib/puppet/parser/functions/global_options.rb +23 -0
  116. data/lib/puppet/parser/functions/global_param.rb +43 -0
  117. data/lib/puppet/parser/functions/interpolate.rb +26 -0
  118. data/lib/puppet/parser/functions/is_false.rb +21 -0
  119. data/lib/puppet/parser/functions/is_true.rb +21 -0
  120. data/lib/puppet/parser/functions/module_array.rb +38 -0
  121. data/lib/puppet/parser/functions/module_hash.rb +38 -0
  122. data/lib/puppet/parser/functions/module_options.rb +23 -0
  123. data/lib/puppet/parser/functions/module_param.rb +48 -0
  124. data/lib/puppet/parser/functions/name.rb +21 -0
  125. data/lib/puppet/parser/functions/render.rb +33 -0
  126. data/lib/puppet/parser/functions/value.rb +21 -0
  127. data/locales/en.yml +232 -0
  128. data/spec/corl_core/interface_spec.rb +489 -0
  129. data/spec/corl_mock_input.rb +29 -0
  130. data/spec/corl_test_kernel.rb +22 -0
  131. data/spec/spec_helper.rb +15 -0
  132. 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,13 @@
1
+
2
+ Facter.add(:corl_config_ready) do
3
+ setcode do
4
+ begin
5
+ require 'corl'
6
+ configured = CORL::Config.config_initialized?
7
+
8
+ rescue Exception # Prevent abortions.
9
+ end
10
+
11
+ configured ? true : nil
12
+ end
13
+ 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,6 @@
1
+
2
+ require 'puppet/indirector/corl'
3
+
4
+ class Puppet::DataBinding::CORL < Puppet::Indirector::CORL
5
+ desc "Retrieve data using CORL lookup methods."
6
+ 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