corl 0.4.0

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