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.
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