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,310 @@
1
+
2
+ module CORL
3
+ module Machine
4
+ class Fog < Plugin::Machine
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Checks
8
+
9
+ def created?
10
+ server && ! server.state != 'DELETED'
11
+ end
12
+
13
+ #---
14
+
15
+ def running?
16
+ created? && server.ready?
17
+ end
18
+
19
+ #-----------------------------------------------------------------------------
20
+ # Property accessors / modifiers
21
+
22
+ def set_connection
23
+ logger.info("Initializing Fog Compute connection to cloud hosting provider")
24
+ logger.debug("Compute settings: #{export.inspect}")
25
+
26
+ ENV['DEBUG'] = 'true' if CORL.log_level == :debug
27
+
28
+ require 'fog'
29
+
30
+ myself.compute = ::Fog::Compute.new(export)
31
+ end
32
+ protected :set_connection
33
+
34
+ #---
35
+
36
+ def compute=compute
37
+ @compute = compute
38
+ end
39
+
40
+ def compute
41
+ set_connection unless @compute
42
+ @compute
43
+ end
44
+
45
+ #---
46
+
47
+ def server=id
48
+ if id.is_a?(String)
49
+ @server = compute.servers.get(id)
50
+ else
51
+ @server = id
52
+ end
53
+
54
+ unless @server.nil?
55
+ myself.name = @server.id
56
+
57
+ node[:id] = name
58
+ node[:hostname] = @server.name
59
+ node[:public_ip] = @server.public_ip_address
60
+ node[:private_ip] = @server.private_ip_address
61
+
62
+ node.machine_type = @server.flavor.id
63
+ node.image = @server.image.id
64
+
65
+ node.user = @server.username unless node.user
66
+
67
+ @server.private_key_path = node.private_key if node.private_key
68
+ @server.public_key_path = node.public_key if node.public_key
69
+ end
70
+ end
71
+
72
+ def server
73
+ compute
74
+ load unless @server
75
+ @server
76
+ end
77
+
78
+ #---
79
+
80
+ def state
81
+ return translate_state(server.state) if server
82
+ nil
83
+ end
84
+
85
+ #---
86
+
87
+ def hostname
88
+ return server.name if server
89
+ nil
90
+ end
91
+
92
+ #---
93
+
94
+ def public_ip
95
+ return server.public_ip_address if server
96
+ nil
97
+ end
98
+
99
+ #---
100
+
101
+ def private_ip
102
+ return server.private_ip_address if server
103
+ nil
104
+ end
105
+
106
+ #---
107
+
108
+ def machine_types
109
+ return compute.flavors if compute
110
+ []
111
+ end
112
+
113
+ #---
114
+
115
+ def machine_type
116
+ return server.flavor.id if server
117
+ nil
118
+ end
119
+
120
+ #---
121
+
122
+ def images
123
+ return compute.images if compute
124
+ []
125
+ end
126
+
127
+ #---
128
+
129
+ def image
130
+ return server.image.id if server
131
+ nil
132
+ end
133
+
134
+ #-----------------------------------------------------------------------------
135
+ # Management
136
+
137
+ def load
138
+ super do
139
+ myself.server = name if compute && ! name.empty?
140
+ server.nil? ? false : true
141
+ end
142
+ end
143
+
144
+ #---
145
+
146
+ def create(options = {})
147
+ super do
148
+ myself.server = compute.servers.bootstrap(Config.ensure(options).export) if compute
149
+ myself.server ? true : false
150
+ end
151
+ end
152
+
153
+ #---
154
+
155
+ def download(remote_path, local_path, options = {})
156
+ super do |config, success|
157
+ logger.debug("Executing SCP download to #{local_path} from #{remote_path} on machine #{name}")
158
+
159
+ begin
160
+ if init_ssh_session
161
+ Util::SSH.download(node.public_ip, node.user, remote_path, local_path, config.export) do |name, received, total|
162
+ yield(name, received, total) if block_given?
163
+ end
164
+ true
165
+ else
166
+ false
167
+ end
168
+ rescue Exception => error
169
+ ui.error(error.message)
170
+ false
171
+ end
172
+ end
173
+ end
174
+
175
+ #---
176
+
177
+ def upload(local_path, remote_path, options = {})
178
+ super do |config, success|
179
+ logger.debug("Executing SCP upload from #{local_path} to #{remote_path} on machine #{name}")
180
+
181
+ begin
182
+ if init_ssh_session
183
+ Util::SSH.upload(node.public_ip, node.user, local_path, remote_path, config.export) do |name, sent, total|
184
+ yield(name, sent, total) if block_given?
185
+ end
186
+ true
187
+ else
188
+ false
189
+ end
190
+ rescue Exception => error
191
+ ui.error(error.message)
192
+ false
193
+ end
194
+ end
195
+ end
196
+
197
+ #---
198
+
199
+ def exec(commands, options = {})
200
+ super do |config, results|
201
+ if commands
202
+ logger.debug("Executing SSH commands ( #{commands.inspect} ) on machine #{name}")
203
+
204
+ if init_ssh_session
205
+ results = Util::SSH.exec(node.public_ip, node.user, commands) do |type, command, data|
206
+ yield(type, command, data) if block_given?
207
+ end
208
+ else
209
+ results = nil
210
+ end
211
+ end
212
+ results
213
+ end
214
+ end
215
+
216
+ #---
217
+
218
+ def start(options = {})
219
+ super do
220
+ if compute
221
+ server_info = compute.servers.create(options)
222
+
223
+ logger.info("Waiting for #{plugin_provider} machine to start")
224
+ ::Fog.wait_for do
225
+ compute.servers.get(server_info.id).ready? ? true : false
226
+ end
227
+
228
+ logger.debug("Setting machine #{server_info.id}")
229
+
230
+ myself.server = compute.servers.get(server_info.id)
231
+ myself.server ? true : false
232
+ else
233
+ false
234
+ end
235
+ end
236
+ end
237
+
238
+ #---
239
+
240
+ def reload(options = {})
241
+ super do
242
+ if server
243
+ logger.debug("Rebooting machine #{name}")
244
+ server.reboot(options)
245
+ else
246
+ false
247
+ end
248
+ end
249
+ end
250
+
251
+ #---
252
+
253
+ def create_image(name, options = {})
254
+ super do
255
+ if server
256
+ logger.debug("Imaging machine #{self.name}")
257
+ image = server.create_image(name, options)
258
+
259
+ if image
260
+ node.image = image.id
261
+ true
262
+ else
263
+ false
264
+ end
265
+ else
266
+ false
267
+ end
268
+ end
269
+ end
270
+
271
+ #---
272
+
273
+ def stop(options = {})
274
+ super do
275
+ success = true
276
+ if image_id = create_image(name)
277
+ logger.info("Waiting for #{plugin_provider} machine to finish creating image: #{image_id}")
278
+ ::Fog.wait_for do
279
+ compute.images.get(image_id).ready? ? true : false
280
+ end
281
+
282
+ logger.debug("Detroying machine #{name}")
283
+ success = server.destroy
284
+ end
285
+ success
286
+ end
287
+ end
288
+
289
+ #---
290
+
291
+ def destroy(options = {})
292
+ super do
293
+ if server
294
+ logger.debug("Destroying machine #{name}")
295
+ server.destroy(options)
296
+ else
297
+ false
298
+ end
299
+ end
300
+ end
301
+
302
+ #-----------------------------------------------------------------------------
303
+ # Utilities
304
+
305
+ def init_ssh_session
306
+ Util::SSH.session(node.public_ip, node.user, node.ssh_port, node.private_key)
307
+ end
308
+ end
309
+ end
310
+ end
@@ -0,0 +1,161 @@
1
+
2
+ module CORL
3
+ module Machine
4
+ class Physical < Plugin::Machine
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Machine plugin interface
8
+
9
+ def normalize
10
+ super
11
+ myself.plugin_name = hostname
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Checks
16
+
17
+ def created?
18
+ true
19
+ end
20
+
21
+ #---
22
+
23
+ def running?
24
+ true
25
+ end
26
+
27
+ #-----------------------------------------------------------------------------
28
+ # Property accessors / modifiers
29
+
30
+ def state
31
+ translate_state('RUNNING')
32
+ end
33
+
34
+ #---
35
+
36
+ def hostname
37
+ fact(:hostname)
38
+ end
39
+
40
+ #---
41
+
42
+ def public_ip
43
+ fact(:ipaddress)
44
+ end
45
+
46
+ #---
47
+
48
+ def private_ip
49
+ nil
50
+ end
51
+
52
+ #---
53
+
54
+ def machine_type
55
+ 'physical'
56
+ end
57
+
58
+ #---
59
+
60
+ def image
61
+ nil
62
+ end
63
+
64
+ #-----------------------------------------------------------------------------
65
+ # Management
66
+
67
+ def load
68
+ super do
69
+ true
70
+ end
71
+ end
72
+
73
+ #---
74
+
75
+ def create(options = {})
76
+ super do
77
+ logger.warn("Damn! We can't create new instances of physical machines")
78
+ true
79
+ end
80
+ end
81
+
82
+ #---
83
+
84
+ def download(remote_path, local_path, options = {})
85
+ super do |config, success|
86
+ logger.debug("Executing SCP downloads not yet supported on physical machines")
87
+ true
88
+ end
89
+ end
90
+
91
+ #---
92
+
93
+ def upload(local_path, remote_path, options = {})
94
+ super do |config, success|
95
+ logger.debug("Executing SCP uploads not yet supported on physical machines")
96
+ true
97
+ end
98
+ end
99
+
100
+ #---
101
+
102
+ def exec(commands, options = {})
103
+ super do |config, results|
104
+ logger.debug("Executing shell commands ( #{commands.inspect} ) on machine #{name}")
105
+
106
+ commands.each do |command|
107
+ result = Util::Shell.connection.exec(command, config) do |op, command_str, data|
108
+ block_given? ? yield(op, command_str, data) : true
109
+ end
110
+ results << result
111
+ end
112
+ results
113
+ end
114
+ end
115
+
116
+ #---
117
+
118
+ def start(options = {})
119
+ super do
120
+ logger.warn("This machine is already running so can not be started")
121
+ true
122
+ end
123
+ end
124
+
125
+ #---
126
+
127
+ def reload(options = {})
128
+ return super do
129
+ logger.warn("Reloading not currently supported on physical machines")
130
+ true
131
+ end
132
+ end
133
+
134
+ #---
135
+
136
+ def create_image(name, options = {})
137
+ super do
138
+ logger.warn("Creating images of local machines not supported yet")
139
+ true
140
+ end
141
+ end
142
+ #---
143
+
144
+ def stop(options = {})
145
+ super do
146
+ logger.warn("Stopping the machine we are operating is not supported right now")
147
+ true
148
+ end
149
+ end
150
+
151
+ #---
152
+
153
+ def destroy(options = {})
154
+ super do
155
+ logger.warn("If you want to destroy your physical machine, grab a hammer")
156
+ true
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,26 @@
1
+
2
+ module CORL
3
+ module Network
4
+ class Default < Plugin::Network
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Cloud plugin interface
8
+
9
+ def normalize
10
+ super
11
+ end
12
+
13
+ #-----------------------------------------------------------------------------
14
+ # Checks
15
+
16
+
17
+ #-----------------------------------------------------------------------------
18
+ # Property accessors / modifiers
19
+
20
+
21
+ #-----------------------------------------------------------------------------
22
+ # Operations
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,90 @@
1
+
2
+ corl_require(File.dirname(__FILE__), :fog)
3
+
4
+ #---
5
+
6
+ module CORL
7
+ module Node
8
+ class Aws < Node::Fog
9
+
10
+ #-----------------------------------------------------------------------------
11
+ # Node plugin interface
12
+
13
+ #-----------------------------------------------------------------------------
14
+ # Checks
15
+
16
+ def usable_image?(image)
17
+ image.state == 'available' && image.name
18
+ end
19
+
20
+ #-----------------------------------------------------------------------------
21
+ # Property accessors / modifiers
22
+
23
+ def regions
24
+ [
25
+ 'us-west-2a',
26
+ 'us-west-2b',
27
+ 'us-west-2c'
28
+ ]
29
+ end
30
+
31
+ #-----------------------------------------------------------------------------
32
+ # Settings groups
33
+
34
+ def machine_config
35
+ super do |config|
36
+ config.import({
37
+ :provider => 'AWS'
38
+ })
39
+
40
+ config[:aws_access_key_id] = api_user if api_user
41
+ config[:aws_secret_access_key] = api_key if api_key
42
+ end
43
+ end
44
+
45
+ #-----------------------------------------------------------------------------
46
+ # Node operations
47
+
48
+ def create(options = {})
49
+ super do |op, config|
50
+ if op == :config
51
+ config[:private_key] = private_key if private_key
52
+ config[:public_key] = public_key if public_key
53
+
54
+ config.defaults({
55
+ :name => hostname,
56
+ :flavor_id => machine_type,
57
+ :image_id => image
58
+ })
59
+ end
60
+ end
61
+ end
62
+
63
+ #-----------------------------------------------------------------------------
64
+ # Utilities
65
+
66
+ def render_machine_type(machine_type)
67
+ sprintf("[ %20s ][ VCPUS: %5.1f ] %-40s ( RAM: %6iMB | DISK: %8iGB ) ( BITS: %2i )",
68
+ machine_type_id(machine_type),
69
+ machine_type.cores,
70
+ machine_type.name,
71
+ machine_type.ram,
72
+ machine_type.disk,
73
+ machine_type.bits
74
+ )
75
+ end
76
+
77
+ #---
78
+
79
+ def render_image(image)
80
+ sprintf("[ %20s ][ %10s ] %10s - %s", image_id(image), image.state, image.architecture, image.name)
81
+ end
82
+
83
+ #---
84
+
85
+ def image_search_text(image)
86
+ sprintf("%s %s %s %s %s", image_id(image), image.name, image.description, image.state, image.architecture)
87
+ end
88
+ end
89
+ end
90
+ end