corl 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
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