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,245 @@
1
+
2
+ module CORL
3
+ module PuppetExt
4
+ class Resource < Core
5
+
6
+ extend Mixin::SubConfig
7
+
8
+ #-----------------------------------------------------------------------------
9
+ # Constructor / Destructor
10
+
11
+ def initialize(provisioner, info, title, properties = {})
12
+ super({
13
+ :title => string(title),
14
+ :info => symbol_map(hash(info)),
15
+ :provisioner => provisioner,
16
+ :ready => false
17
+ })
18
+ import(properties)
19
+ end
20
+
21
+ #-----------------------------------------------------------------------------
22
+ # Checks
23
+
24
+
25
+ #-----------------------------------------------------------------------------
26
+ # Property accessors / modifiers
27
+
28
+ def provisioner(default = nil)
29
+ return _get(:provisioner, default)
30
+ end
31
+
32
+ #---
33
+
34
+ def provisioner=provisioner
35
+ _set(:provisioner, provisioner)
36
+ end
37
+
38
+ #---
39
+
40
+ def info(default = {})
41
+ return hash(_get(:info, default))
42
+ end
43
+
44
+ #---
45
+
46
+ def info=info
47
+ _set(:info, hash(info))
48
+ end
49
+
50
+ #---
51
+
52
+ def title(default = '')
53
+ return string(_get(:title, default))
54
+ end
55
+
56
+ #---
57
+
58
+ def title=info
59
+ _set(:title, string(info))
60
+ end
61
+
62
+ #---
63
+
64
+ def ready(default = false)
65
+ return test(_get(:ready, default))
66
+ end
67
+
68
+ #---
69
+
70
+ def defaults(defaults, options = {})
71
+ super(defaults, options)
72
+
73
+ _set(:ready, false)
74
+ process(options)
75
+ return self
76
+ end
77
+
78
+ #---
79
+
80
+ def import(properties, options = {})
81
+ super(properties, options)
82
+
83
+ _set(:ready, false)
84
+ process(options)
85
+ return self
86
+ end
87
+
88
+ #-----------------------------------------------------------------------------
89
+ # Resource operations
90
+
91
+ def ensure_ready(options = {})
92
+ unless ready
93
+ process(options)
94
+ end
95
+ end
96
+
97
+ #---
98
+
99
+ def process(options = {})
100
+ config = Config.ensure(options)
101
+
102
+ tag(config[:tag])
103
+
104
+ render(config)
105
+ translate(config)
106
+
107
+ _set(:ready, true) # Ready for resource creation
108
+ return self
109
+ end
110
+
111
+ #---
112
+
113
+ def tag(tag, append = true)
114
+ unless Util::Data.empty?(tag)
115
+ tag = tag.to_s.split(/\s*,\s*/)
116
+ resource_tags = get(:tag)
117
+
118
+ if ! resource_tags || ! append
119
+ set(:tag, tag)
120
+ else
121
+ resource_tags << tag
122
+ set(:tag, resource_tags)
123
+ end
124
+ end
125
+ return self
126
+ end
127
+
128
+ #---
129
+
130
+ def self.render(resource_info, options = {})
131
+ resource = string_map(resource_info)
132
+ config = Config.ensure(options)
133
+
134
+ resource.keys.each do |name|
135
+ if match = name.match(/^(.+)_template$/)
136
+ target = match.captures[0]
137
+
138
+ config.set(:normalize_template, config.get("normalize_#{target}", true))
139
+ config.set(:interpolate_template, config.get("interpolate_#{target}", true))
140
+
141
+ resource[target] = CORL.template(resource[name], config).render(resource[target])
142
+ resource.delete(name)
143
+ end
144
+ end
145
+ return resource
146
+ end
147
+
148
+ #---
149
+
150
+ def render(options = {})
151
+ resource = self.class.render(export, options)
152
+ clear(options)
153
+ import(resource, options)
154
+ return self
155
+ end
156
+
157
+ #---
158
+
159
+ def translate(options = {})
160
+ config = Config.ensure(options)
161
+
162
+ set(:before, translate_resource_refs(get(:before), config)) if get(:before)
163
+ set(:notify, translate_resource_refs(get(:notify), config)) if get(:notify)
164
+ set(:require, translate_resource_refs(get(:require), config)) if get(:require)
165
+ set(:subscribe, translate_resource_refs(get(:subscribe), config)) if get(:subscribe)
166
+
167
+ return self
168
+ end
169
+
170
+ #-----------------------------------------------------------------------------
171
+ # Utilities
172
+
173
+ def translate_resource_refs(resource_refs, options = {})
174
+ return :undef if Util::Data.undef?(resource_refs)
175
+
176
+ config = Config.ensure(options)
177
+ resource_names = config.get(:resource_names, {})
178
+ title_prefix = config.get(:title_prefix, '')
179
+
180
+ title_pattern = config.get(:title_pattern, '^\s*([^\[\]]+)\s*$')
181
+ title_group = config.get(:title_var_group, 1)
182
+ title_flags = config.get(:title_flags, '')
183
+ title_regexp = Regexp.new(title_pattern, title_flags.split(''))
184
+
185
+ groups = config.get(:groups, {})
186
+
187
+ allow_single = config.get(:allow_single_return, true)
188
+
189
+ type_name = info[:name].sub(/^\@?\@/, '')
190
+ values = []
191
+
192
+ case resource_refs
193
+ when String
194
+ if resource_refs.empty?
195
+ return :undef
196
+ else
197
+ resource_refs = resource_refs.split(/\s*,\s*/)
198
+ end
199
+
200
+ when ::Puppet::Resource
201
+ resource_refs = [ resource_refs ]
202
+ end
203
+
204
+ resource_refs.collect! do |value|
205
+ if value.is_a?(::Puppet::Resource) || ! value.match(title_regexp)
206
+ value
207
+
208
+ elsif resource_names.has_key?(value)
209
+ if ! title_prefix.empty?
210
+ "#{title_prefix}_#{value}"
211
+ else
212
+ value
213
+ end
214
+
215
+ elsif groups.has_key?(value) && ! groups[value].empty?
216
+ results = []
217
+ groups[value].each do |resource_name|
218
+ unless title_prefix.empty?
219
+ resource_name = "#{title_prefix}_#{resource_name}"
220
+ end
221
+ results << resource_name
222
+ end
223
+ results
224
+
225
+ else
226
+ nil
227
+ end
228
+ end
229
+
230
+ resource_refs.flatten.each do |ref|
231
+ unless ref.nil?
232
+ unless ref.is_a?(::Puppet::Resource)
233
+ ref = ref.match(title_regexp) ? ::Puppet::Resource.new(type_name, ref) : ::Puppet::Resource.new(ref)
234
+ end
235
+ values << ref unless ref.nil?
236
+ end
237
+ end
238
+
239
+ return values[0] if allow_single && values.length == 1
240
+ return values
241
+ end
242
+ protected :translate_resource_refs
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,205 @@
1
+
2
+ module CORL
3
+ module PuppetExt
4
+ class ResourceGroup < Core
5
+
6
+ extend Mixin::SubConfig
7
+
8
+ #-----------------------------------------------------------------------------
9
+ # Constructor / Destructor
10
+
11
+ def initialize(provisioner, type_info, default = {})
12
+ super({
13
+ :info => hash(type_info),
14
+ :provisioner => provisioner,
15
+ :default => symbol_map(hash(default))
16
+ })
17
+ self.resources = {}
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
+
31
+ #---
32
+
33
+ def provisioner=provisioner
34
+ _set(:provisioner, provisioner)
35
+ end
36
+
37
+ #---
38
+
39
+ def info(default = {})
40
+ return hash(_get(:info, default))
41
+ end
42
+
43
+ #---
44
+
45
+ def info=info
46
+ _set(:info, hash(info))
47
+ end
48
+
49
+ #---
50
+
51
+ def default(default = {})
52
+ return hash(_get(:default, default))
53
+ end
54
+
55
+ #---
56
+
57
+ def default=default
58
+ _set(:default, symbol_map(hash(default)))
59
+ end
60
+
61
+ #---
62
+
63
+ def resources(default = {})
64
+ return hash(_get(:resources, default))
65
+ end
66
+
67
+ #---
68
+
69
+ def resources=resources
70
+ _set(:resources, symbol_map(hash(resources)))
71
+ end
72
+
73
+ #---
74
+
75
+ def composite_resources(default = {})
76
+ return hash(_get(:composite_resources, default))
77
+ end
78
+
79
+ #---
80
+
81
+ def composite_resources=resources
82
+ _set(:composite_resources, symbol_map(hash(resources)))
83
+ end
84
+
85
+ #---
86
+
87
+ def clear
88
+ self.resources = {}
89
+ return self
90
+ end
91
+
92
+ #---
93
+
94
+ def add(resources, options = {})
95
+ config = Config.ensure(options)
96
+ resources = normalize(resources, config)
97
+
98
+ unless Util::Data.empty?(resources)
99
+ collection = self.resources
100
+ resources.each do |title, resource|
101
+ provisioner.add_resource(info, title, resource.export)
102
+ collection[title] = resource
103
+ end
104
+ self.resources = collection
105
+ end
106
+ return self
107
+ end
108
+
109
+ #---
110
+
111
+ def add_composite_resource(name, resource_names)
112
+ composite = self.composite_resources
113
+ composite[name] = [] unless composite[name].is_a?(Array)
114
+
115
+ unless resource_names.is_a?(Array)
116
+ resource_names = [ resource_names ]
117
+ end
118
+
119
+ resource_names.each do |r_name|
120
+ unless composite[name].include?(r_name)
121
+ composite[name] << r_name
122
+ end
123
+ end
124
+
125
+ self.composite_resources = composite
126
+ end
127
+ protected :add_composite_resource
128
+
129
+ #-----------------------------------------------------------------------------
130
+ # Resource operations
131
+
132
+ def normalize(type_name, resources, options = {})
133
+ self.composite_resources = {}
134
+
135
+ config = Config.ensure(options)
136
+ resources = Util::Data.value(resources)
137
+
138
+ unless Util::Data.empty?(resources)
139
+ resources.keys.each do |name|
140
+ if ! resources[name] || resources[name].empty? || ! resources[name].is_a?(Hash)
141
+ resources.delete(name)
142
+ else
143
+ normalize = true
144
+
145
+ namevar = provisioner.namevar(type_name, name)
146
+ if resources[name].has_key?(namevar)
147
+ value = resources[name][namevar]
148
+ if Util::Data.empty?(value)
149
+ resources.delete(name)
150
+ normalize = false
151
+
152
+ elsif value.is_a?(Array)
153
+ value.each do |item|
154
+ item_name = "#{name}_#{item}".gsub(/\-/, '_')
155
+
156
+ new_resource = resources[name].clone
157
+ new_resource[namevar] = item
158
+
159
+ resources[item_name] = Resource.render(new_resource, config)
160
+ add_composite_resource(name, item_name)
161
+ end
162
+ resources.delete(name)
163
+ normalize = false
164
+ end
165
+ end
166
+
167
+ if normalize
168
+ resource = Resource.new(provisioner, info, name, resources[name])
169
+ resource.defaults(default, config.import({ :groups => self.composite_resources }))
170
+
171
+ resources[name] = resource
172
+ end
173
+ end
174
+ end
175
+ end
176
+ return translate(resources, config)
177
+ end
178
+ protected :normalize
179
+
180
+ #---
181
+
182
+ def translate(resources, options = {})
183
+ config = Config.ensure(options)
184
+ results = {}
185
+
186
+ prefix = config.get(:resource_prefix, '')
187
+ name_map = {}
188
+
189
+ resources.keys.each do |name|
190
+ name_map[name] = true
191
+ end
192
+ config[:resource_names] = name_map
193
+
194
+ resources.each do |name, resource|
195
+ unless prefix.empty?
196
+ name = "#{prefix}_#{name}"
197
+ end
198
+ results[name] = resource
199
+ end
200
+ return results
201
+ end
202
+ protected :translate
203
+ end
204
+ end
205
+ end