corl 0.4.2 → 0.4.3

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 (41) hide show
  1. data/Gemfile.lock +1 -1
  2. data/VERSION +1 -1
  3. data/corl.gemspec +12 -7
  4. data/lib/CORL/action/build.rb +30 -0
  5. data/lib/CORL/action/provision.rb +34 -8
  6. data/lib/CORL/configuration/file.rb +50 -64
  7. data/lib/CORL/provisioner/puppetnode.rb +186 -314
  8. data/lib/core/mixin/lookup.rb +20 -15
  9. data/lib/core/mixin/macro/network_settings.rb +52 -0
  10. data/lib/core/plugin/action.rb +1 -1
  11. data/lib/core/plugin/configuration.rb +43 -4
  12. data/lib/core/plugin/network.rb +16 -3
  13. data/lib/core/plugin/node.rb +69 -2
  14. data/lib/core/plugin/provisioner.rb +286 -11
  15. data/lib/{CORL/provisioner/puppetnode → core/util/puppet}/resource.rb +36 -40
  16. data/lib/{CORL/provisioner/puppetnode → core/util/puppet}/resource_group.rb +33 -41
  17. data/lib/core/util/puppet.rb +303 -0
  18. data/lib/corl.rb +34 -11
  19. data/lib/facter/corl_build.rb +8 -0
  20. data/lib/facter/corl_exists.rb +3 -3
  21. data/lib/facter/corl_network.rb +1 -1
  22. data/lib/facter/custom_facts.rb +24 -0
  23. data/lib/facter/vagrant_exists.rb +15 -0
  24. data/lib/hiera/corl_logger.rb +1 -1
  25. data/lib/puppet/indirector/corl.rb +2 -2
  26. data/lib/puppet/parser/functions/corl_include.rb +10 -14
  27. data/lib/puppet/parser/functions/corl_initialize.rb +15 -0
  28. data/lib/puppet/parser/functions/{deep_merge.rb → corl_merge.rb} +4 -4
  29. data/lib/puppet/parser/functions/corl_resources.rb +9 -4
  30. data/lib/puppet/parser/functions/global_array.rb +1 -1
  31. data/lib/puppet/parser/functions/global_hash.rb +1 -1
  32. data/lib/puppet/parser/functions/global_param.rb +1 -1
  33. data/lib/puppet/parser/functions/interpolate.rb +1 -1
  34. data/lib/puppet/parser/functions/module_array.rb +8 -9
  35. data/lib/puppet/parser/functions/module_hash.rb +7 -8
  36. data/lib/puppet/parser/functions/module_param.rb +4 -5
  37. data/lib/puppet/parser/functions/name.rb +1 -1
  38. data/lib/puppet/parser/functions/render.rb +5 -5
  39. metadata +34 -29
  40. data/lib/CORL/extension/puppetloader.rb +0 -24
  41. data/lib/puppet/parser/functions/config_initialized.rb +0 -26
@@ -1,38 +1,29 @@
1
1
 
2
2
  module CORL
3
- module PuppetExt
3
+ module Util
4
+ module Puppet
4
5
  class Resource < Core
5
6
 
6
- extend Mixin::SubConfig
7
+ include Mixin::SubConfig
7
8
 
8
9
  #-----------------------------------------------------------------------------
9
10
  # Constructor / Destructor
10
11
 
11
- def initialize(provisioner, info, title, properties = {})
12
+ def initialize(group, info, title, properties = {})
12
13
  super({
13
- :title => string(title),
14
- :info => symbol_map(hash(info)),
15
- :provisioner => provisioner,
16
- :ready => false
14
+ :group => group,
15
+ :title => string(title),
16
+ :info => symbol_map(hash(info)),
17
+ :ready => false
17
18
  })
18
19
  import(properties)
19
20
  end
20
-
21
- #-----------------------------------------------------------------------------
22
- # Checks
23
-
24
21
 
25
22
  #-----------------------------------------------------------------------------
26
23
  # Property accessors / modifiers
27
24
 
28
- def provisioner(default = nil)
29
- return _get(:provisioner, default)
30
- end
31
-
32
- #---
33
-
34
- def provisioner=provisioner
35
- _set(:provisioner, provisioner)
25
+ def group
26
+ return _get(:group)
36
27
  end
37
28
 
38
29
  #---
@@ -71,7 +62,6 @@ class Resource < Core
71
62
  super(defaults, options)
72
63
 
73
64
  _set(:ready, false)
74
- process(options)
75
65
  return self
76
66
  end
77
67
 
@@ -81,7 +71,6 @@ class Resource < Core
81
71
  super(properties, options)
82
72
 
83
73
  _set(:ready, false)
84
- process(options)
85
74
  return self
86
75
  end
87
76
 
@@ -100,7 +89,6 @@ class Resource < Core
100
89
  config = Config.ensure(options)
101
90
 
102
91
  tag(config[:tag])
103
-
104
92
  render(config)
105
93
  translate(config)
106
94
 
@@ -110,15 +98,21 @@ class Resource < Core
110
98
 
111
99
  #---
112
100
 
113
- def tag(tag, append = true)
114
- unless Util::Data.empty?(tag)
115
- tag = tag.to_s.split(/\s*,\s*/)
101
+ def tag(tags, append = true)
102
+ unless Data.empty?(tags)
103
+ if tags.is_a?(String)
104
+ tags = tags.to_s.split(/\s*,\s*/)
105
+ else
106
+ tags = tags.flatten
107
+ end
116
108
  resource_tags = get(:tag)
117
109
 
118
110
  if ! resource_tags || ! append
119
- set(:tag, tag)
111
+ set(:tag, tags)
120
112
  else
121
- resource_tags << tag
113
+ tags.each do |tag|
114
+ resource_tags << tag unless resource_tags.include?(tag)
115
+ end
122
116
  set(:tag, resource_tags)
123
117
  end
124
118
  end
@@ -132,13 +126,13 @@ class Resource < Core
132
126
  config = Config.ensure(options)
133
127
 
134
128
  resource.keys.each do |name|
135
- if match = name.match(/^(.+)_template$/)
129
+ if match = name.to_s.match(/^(.+)_template$/)
136
130
  target = match.captures[0]
137
131
 
138
132
  config.set(:normalize_template, config.get("normalize_#{target}", true))
139
133
  config.set(:interpolate_template, config.get("interpolate_#{target}", true))
140
134
 
141
- resource[target] = CORL.template(resource[name], config).render(resource[target])
135
+ resource[target] = CORL.template(config, resource[name]).render(resource[target])
142
136
  resource.delete(name)
143
137
  end
144
138
  end
@@ -149,8 +143,8 @@ class Resource < Core
149
143
 
150
144
  def render(options = {})
151
145
  resource = self.class.render(export, options)
152
- clear(options)
153
- import(resource, options)
146
+ clear
147
+ import(Config.ensure(resource).export, options)
154
148
  return self
155
149
  end
156
150
 
@@ -171,7 +165,7 @@ class Resource < Core
171
165
  # Utilities
172
166
 
173
167
  def translate_resource_refs(resource_refs, options = {})
174
- return :undef if Util::Data.undef?(resource_refs)
168
+ return :undef if Data.undef?(resource_refs)
175
169
 
176
170
  config = Config.ensure(options)
177
171
  resource_names = config.get(:resource_names, {})
@@ -182,12 +176,12 @@ class Resource < Core
182
176
  title_flags = config.get(:title_flags, '')
183
177
  title_regexp = Regexp.new(title_pattern, title_flags.split(''))
184
178
 
185
- groups = config.get(:groups, {})
186
-
187
179
  allow_single = config.get(:allow_single_return, true)
188
180
 
189
181
  type_name = info[:name].sub(/^\@?\@/, '')
190
182
  values = []
183
+
184
+ composite_resources = group.composite_resources
191
185
 
192
186
  case resource_refs
193
187
  when String
@@ -202,19 +196,19 @@ class Resource < Core
202
196
  end
203
197
 
204
198
  resource_refs.collect! do |value|
205
- if value.is_a?(::Puppet::Resource) || ! value.match(title_regexp)
206
- value
199
+ if value.is_a?(::Puppet::Resource) || ! value.to_s.match(title_regexp)
200
+ value.to_s
207
201
 
208
- elsif resource_names.has_key?(value)
202
+ elsif resource_names.has_key?(value.to_s)
209
203
  if ! title_prefix.empty?
210
204
  "#{title_prefix}_#{value}"
211
205
  else
212
- value
206
+ value.to_s
213
207
  end
214
208
 
215
- elsif groups.has_key?(value) && ! groups[value].empty?
209
+ elsif composite_resources.has_key?(value.to_sym) && ! composite_resources[value.to_sym].empty?
216
210
  results = []
217
- groups[value].each do |resource_name|
211
+ composite_resources[value.to_sym].each do |resource_name|
218
212
  unless title_prefix.empty?
219
213
  resource_name = "#{title_prefix}_#{resource_name}"
220
214
  end
@@ -243,3 +237,5 @@ class Resource < Core
243
237
  end
244
238
  end
245
239
  end
240
+ end
241
+
@@ -1,40 +1,30 @@
1
1
 
2
2
  module CORL
3
- module PuppetExt
3
+ module Util
4
+ module Puppet
4
5
  class ResourceGroup < Core
5
6
 
6
- extend Mixin::SubConfig
7
+ include Mixin::SubConfig
7
8
 
8
9
  #-----------------------------------------------------------------------------
9
10
  # Constructor / Destructor
10
11
 
11
- def initialize(provisioner, type_info, default = {})
12
+ def initialize(type_info, default = {})
12
13
  super({
13
- :info => hash(type_info),
14
- :provisioner => provisioner,
15
- :default => symbol_map(hash(default))
14
+ :info => hash(type_info),
15
+ :default => symbol_map(hash(default))
16
16
  })
17
17
  self.resources = {}
18
18
  end
19
-
20
- #-----------------------------------------------------------------------------
21
- # Checks
22
-
23
-
24
- #-----------------------------------------------------------------------------
25
- # Property accessors / modifiers
26
-
27
- def provisioner(default = nil)
28
- return _get(:provisioner, default)
29
- end
30
19
 
31
20
  #---
32
21
 
33
- def provisioner=provisioner
34
- _set(:provisioner, provisioner)
22
+ def inspect
23
+ "#{self.class}#{info.to_s}[#{composite_resources.keys.length}]"
35
24
  end
36
-
37
- #---
25
+
26
+ #-----------------------------------------------------------------------------
27
+ # Property accessors / modifiers
38
28
 
39
29
  def info(default = {})
40
30
  return hash(_get(:info, default))
@@ -84,21 +74,18 @@ class ResourceGroup < Core
84
74
 
85
75
  #---
86
76
 
87
- def clear
88
- self.resources = {}
89
- return self
90
- end
91
-
92
- #---
93
-
94
77
  def add(resources, options = {})
95
78
  config = Config.ensure(options)
96
- resources = normalize(resources, config)
97
79
 
98
- unless Util::Data.empty?(resources)
80
+ dbg(resources, 'before')
81
+ dbg(default, 'defaults')
82
+ resources = normalize(info[:name], resources, config)
83
+
84
+ unless Data.empty?(resources)
99
85
  collection = self.resources
100
86
  resources.each do |title, resource|
101
- provisioner.add_resource(info, title, resource.export)
87
+ dbg(resource.export, "#{info[:type]} #{info[:name]}: #{title}")
88
+ Puppet.add_resource(info, title, resource.export, config)
102
89
  collection[title] = resource
103
90
  end
104
91
  self.resources = collection
@@ -109,6 +96,7 @@ class ResourceGroup < Core
109
96
  #---
110
97
 
111
98
  def add_composite_resource(name, resource_names)
99
+ name = name.to_sym
112
100
  composite = self.composite_resources
113
101
  composite[name] = [] unless composite[name].is_a?(Array)
114
102
 
@@ -117,11 +105,12 @@ class ResourceGroup < Core
117
105
  end
118
106
 
119
107
  resource_names.each do |r_name|
108
+ r_name = r_name.to_sym
109
+
120
110
  unless composite[name].include?(r_name)
121
111
  composite[name] << r_name
122
112
  end
123
113
  end
124
-
125
114
  self.composite_resources = composite
126
115
  end
127
116
  protected :add_composite_resource
@@ -133,19 +122,19 @@ class ResourceGroup < Core
133
122
  self.composite_resources = {}
134
123
 
135
124
  config = Config.ensure(options)
136
- resources = Util::Data.value(resources)
125
+ resources = Data.value(resources)
137
126
 
138
- unless Util::Data.empty?(resources)
127
+ unless Data.empty?(resources)
139
128
  resources.keys.each do |name|
140
- if ! resources[name] || resources[name].empty? || ! resources[name].is_a?(Hash)
129
+ if ! resources[name] || resources[name].empty? || ! resources[name].is_a?(Hash)
141
130
  resources.delete(name)
142
131
  else
143
132
  normalize = true
144
133
 
145
- namevar = provisioner.namevar(type_name, name)
134
+ namevar = Puppet.namevar(type_name, name)
146
135
  if resources[name].has_key?(namevar)
147
136
  value = resources[name][namevar]
148
- if Util::Data.empty?(value)
137
+ if Data.empty?(value)
149
138
  resources.delete(name)
150
139
  normalize = false
151
140
 
@@ -156,7 +145,7 @@ class ResourceGroup < Core
156
145
  new_resource = resources[name].clone
157
146
  new_resource[namevar] = item
158
147
 
159
- resources[item_name] = Resource.render(new_resource, config)
148
+ resources[item_name] = Resource.new(self, info, item_name, new_resource).defaults(default, config)
160
149
  add_composite_resource(name, item_name)
161
150
  end
162
151
  resources.delete(name)
@@ -165,13 +154,14 @@ class ResourceGroup < Core
165
154
  end
166
155
 
167
156
  if normalize
168
- resource = Resource.new(provisioner, info, name, resources[name])
169
- resource.defaults(default, config.import({ :groups => self.composite_resources }))
170
-
157
+ resource = Resource.new(self, info, name, resources[name]).defaults(default, config)
171
158
  resources[name] = resource
172
159
  end
173
160
  end
174
161
  end
162
+ resources.each do |name, resource|
163
+ resource.process(config)
164
+ end
175
165
  end
176
166
  return translate(resources, config)
177
167
  end
@@ -203,3 +193,5 @@ class ResourceGroup < Core
203
193
  end
204
194
  end
205
195
  end
196
+ end
197
+
@@ -0,0 +1,303 @@
1
+
2
+ module CORL
3
+ module Util
4
+ module Puppet
5
+
6
+ def self.logger
7
+ CORL.logger
8
+ end
9
+
10
+ #-----------------------------------------------------------------------------
11
+ # Plugins
12
+
13
+ @@register = {}
14
+
15
+ #---
16
+
17
+ def self.register_plugins(options = {})
18
+ config = Config.ensure(options)
19
+
20
+ puppet_scope = config.get(:puppet_scope, nil)
21
+ return unless puppet_scope
22
+
23
+ each_module(config) do |mod|
24
+ unless @@register.has_key?(mod.path)
25
+ lib_dir = File.join(mod.path, 'lib')
26
+ if File.directory?(lib_dir)
27
+ logger.debug("Registering Puppet module at #{lib_dir}")
28
+ CORL.register(lib_dir)
29
+ @@register[mod.path] = true
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ #-----------------------------------------------------------------------------
36
+ # Resources
37
+
38
+ def self.type_info(type_name, options = {})
39
+ config = Config.ensure(options)
40
+ reset = config.get(:reset, false)
41
+
42
+ puppet_scope = config.get(:puppet_scope, nil)
43
+ return nil unless puppet_scope
44
+
45
+ type_name = type_name.to_s.downcase
46
+ type_info = config.get(:type_info, {})
47
+
48
+ if reset || ! type_info.has_key?(type_name)
49
+ resource_type = nil
50
+ type_exported, type_virtual = false
51
+
52
+ if type_name.start_with?('@@')
53
+ type_name = type_name[2..-1]
54
+ type_exported = true
55
+
56
+ elsif type_name.start_with?('@')
57
+ type_name = type_name[1..-1]
58
+ type_virtual = true
59
+ end
60
+
61
+ if type_name == 'class'
62
+ resource_type = :class
63
+ else
64
+ if resource = ::Puppet::Type.type(type_name.to_sym)
65
+ resource_type = :type
66
+
67
+ elsif resource = puppet_scope.find_definition(type_name)
68
+ resource_type = :define
69
+ end
70
+ end
71
+
72
+ type_info[type_name] = {
73
+ :name => type_name,
74
+ :type => resource_type,
75
+ :resource => resource,
76
+ :exported => type_exported,
77
+ :virtual => type_virtual
78
+ }
79
+ config.set(:type_info, type_info)
80
+ end
81
+
82
+ type_info[type_name]
83
+ end
84
+
85
+ #-----------------------------------------------------------------------------
86
+ # Catalog alterations
87
+
88
+ def self.add(type_name, resources, defaults = {}, options = {})
89
+ config = Config.ensure(options)
90
+
91
+ puppet_scope = config.get(:puppet_scope, nil)
92
+ return unless puppet_scope
93
+
94
+ info = type_info(type_name, options)
95
+ ResourceGroup.new(info, defaults).add(resources, config)
96
+ end
97
+
98
+ #---
99
+
100
+ def self.add_resource(type, title, properties, options = {})
101
+ config = Config.ensure(options)
102
+
103
+ puppet_scope = config.get(:puppet_scope, nil)
104
+ return unless puppet_scope
105
+
106
+ if type.is_a?(String)
107
+ type = type_info(type, config)
108
+ end
109
+
110
+ case type[:type]
111
+ when :type, :define
112
+ CORL.ui_group(puppet_scope.source.module_name) do |ui|
113
+ #ui.info("Adding #{type[:name]} #{title} definition")
114
+ end
115
+ add_definition(type, title, properties, config)
116
+ when :class
117
+ CORL.ui_group(puppet_scope.source.module_name) do |ui|
118
+ #ui.info("Adding #{title} class")
119
+ end
120
+ add_class(title, properties, config)
121
+ end
122
+ end
123
+
124
+ #---
125
+
126
+ def self.add_class(title, properties, options = {})
127
+ config = Config.ensure(options)
128
+ puppet_scope = config.get(:puppet_scope, nil)
129
+
130
+ if puppet_scope
131
+ klass = puppet_scope.find_hostclass(title)
132
+ return unless klass
133
+
134
+ #dbg(properties, "class #{title}")
135
+ klass.ensure_in_catalog(puppet_scope, properties)
136
+ puppet_scope.catalog.add_class(title)
137
+ end
138
+ end
139
+
140
+ #---
141
+
142
+ def self.add_definition(type, title, properties, options = {})
143
+ config = Config.ensure(options)
144
+
145
+ puppet_scope = config.get(:puppet_scope, nil)
146
+ return unless puppet_scope
147
+
148
+ type = type_info(type, config) if type.is_a?(String)
149
+
150
+ resource = ::Puppet::Parser::Resource.new(type[:name], title, :scope => puppet_scope, :source => type[:resource])
151
+ resource.virtual = type[:virtual]
152
+ resource.exported = type[:exported]
153
+
154
+ namevar = namevar(type[:name], title).to_sym
155
+ resource_name = properties.has_key?(namevar) ? properties[namevar] : title
156
+
157
+ { :name => resource_name }.merge(properties).each do |key, value|
158
+ resource.set_parameter(key, value)
159
+ end
160
+ if type[:type] == :define
161
+ type[:resource].instantiate_resource(puppet_scope, resource)
162
+ end
163
+ #dbg(resource, "definition/type #{type[:type]} #{title}")
164
+ puppet_scope.compiler.add_resource(puppet_scope, resource)
165
+ end
166
+
167
+ #--
168
+
169
+ def self.import(files, options = {})
170
+ config = Config.ensure(options)
171
+
172
+ puppet_scope = config.get(:puppet_scope, nil)
173
+ return unless puppet_scope
174
+
175
+ if types = puppet_scope.environment.known_resource_types
176
+ Util::Data.array(files).each do |file|
177
+ types.loader.import(file, config.get(:puppet_import_base, nil))
178
+ end
179
+ end
180
+ end
181
+
182
+ #---
183
+
184
+ def self.include(resource_name, properties = {}, options = {})
185
+ config = Config.ensure(options)
186
+ class_data = {}
187
+
188
+ puppet_scope = config.get(:puppet_scope, nil)
189
+ return false unless puppet_scope
190
+
191
+ if resource_name.is_a?(Array)
192
+ resource_name = resource_name.flatten
193
+ else
194
+ resource_name = [ resource_name ]
195
+ end
196
+
197
+ resource_name.each do |name|
198
+ classes = Config.lookup(name, nil, config)
199
+ if classes.is_a?(Array)
200
+ classes.each do |klass|
201
+ class_data[klass] = properties
202
+ end
203
+ else
204
+ class_data[name.to_s] = properties
205
+ end
206
+ end
207
+
208
+ klasses = puppet_scope.compiler.evaluate_classes(class_data, puppet_scope, false)
209
+ missing = class_data.keys.find_all do |klass|
210
+ ! klasses.include?(klass)
211
+ end
212
+ return false unless missing.empty?
213
+ true
214
+ end
215
+
216
+ #-----------------------------------------------------------------------------
217
+ # Lookup
218
+
219
+ def self.lookup(property, default = nil, options = {})
220
+ config = Config.ensure(options)
221
+ value = nil
222
+
223
+ puppet_scope = config.get(:puppet_scope, nil)
224
+ base_names = config.get(:search, nil)
225
+ search_name = config.get(:search_name, true)
226
+ reverse_lookup = config.get(:reverse_lookup, true)
227
+
228
+ return default unless puppet_scope
229
+
230
+ log_level = ::Puppet::Util::Log.level
231
+ ::Puppet::Util::Log.level = :err # Don't want failed parameter lookup warnings here.
232
+
233
+ if base_names
234
+ if base_names.is_a?(String)
235
+ base_names = [ base_names ]
236
+ end
237
+ base_names = base_names.reverse if reverse_lookup
238
+
239
+ base_names.each do |base|
240
+ value = puppet_scope.lookupvar("::#{base}::#{property}")
241
+ break unless Util::Data.undef?(value)
242
+ end
243
+ end
244
+ if Util::Data.undef?(value)
245
+ components = property.to_s.split('::')
246
+
247
+ if components.length > 1
248
+ components += [ 'default', components.pop ]
249
+ value = puppet_scope.lookupvar('::' + components.flatten.join('::'))
250
+ end
251
+ end
252
+ if Util::Data.undef?(value) && search_name
253
+ value = puppet_scope.lookupvar("::#{property}")
254
+ end
255
+
256
+ ::Puppet::Util::Log.level = log_level
257
+ value
258
+ end
259
+
260
+ #-----------------------------------------------------------------------------
261
+ # Utilities
262
+
263
+ def self.each_module(options = {}, &code)
264
+ config = Config.ensure(options)
265
+ values = []
266
+
267
+ puppet_scope = config.get(:puppet_scope, nil)
268
+ return nil unless puppet_scope
269
+
270
+ puppet_scope.compiler.environment.modules.each do |mod|
271
+ values << code.call(mod)
272
+ end
273
+ values
274
+ end
275
+
276
+ #---
277
+
278
+ def self.to_name(name)
279
+ Util::Data.value(name).to_s.gsub(/[\/\\\-\.]/, '_')
280
+ end
281
+
282
+ #---
283
+
284
+ def self.type_name(value)
285
+ return :main if value == :main
286
+ return "Class" if value == "" or value.nil? or value.to_s.downcase == "component"
287
+ value.to_s.split("::").collect { |s| s.capitalize }.join("::")
288
+ end
289
+
290
+ #---
291
+
292
+ def self.namevar(type_name, resource_name)
293
+ resource = ::Puppet::Resource.new(type_name.sub(/^\@?\@/, ''), resource_name)
294
+
295
+ if resource.builtin_type? and type = resource.resource_type and type.key_attributes.length == 1
296
+ type.key_attributes.first.to_s
297
+ else
298
+ 'name'
299
+ end
300
+ end
301
+ end
302
+ end
303
+ end