corl 0.4.1 → 0.4.2

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 (48) hide show
  1. data/.gitmodules +1 -1
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +15 -8
  4. data/VERSION +1 -1
  5. data/bootstrap/os/ubuntu/00_base.sh +10 -1
  6. data/bootstrap/os/ubuntu/05_ruby.sh +6 -0
  7. data/bootstrap/os/ubuntu/06_puppet.sh +6 -6
  8. data/bootstrap/os/ubuntu/09_nucleon.sh +14 -0
  9. data/bootstrap/os/ubuntu/10_corl.sh +7 -2
  10. data/corl.gemspec +16 -9
  11. data/lib/CORL/action/authorize.rb +57 -0
  12. data/lib/CORL/action/bootstrap.rb +5 -0
  13. data/lib/CORL/action/destroy.rb +64 -0
  14. data/lib/CORL/action/exec.rb +9 -0
  15. data/lib/CORL/action/image.rb +39 -7
  16. data/lib/CORL/action/images.rb +4 -3
  17. data/lib/CORL/action/lookup.rb +2 -2
  18. data/lib/CORL/action/regions.rb +51 -0
  19. data/lib/CORL/action/seed.rb +1 -1
  20. data/lib/CORL/action/spawn.rb +8 -9
  21. data/lib/CORL/action/ssh.rb +74 -0
  22. data/lib/CORL/action/start.rb +37 -5
  23. data/lib/CORL/action/stop.rb +37 -5
  24. data/lib/CORL/configuration/file.rb +34 -7
  25. data/lib/CORL/event/puppet.rb +1 -1
  26. data/lib/CORL/machine/aws.rb +153 -0
  27. data/lib/CORL/machine/physical.rb +14 -5
  28. data/lib/CORL/machine/rackspace.rb +58 -0
  29. data/lib/CORL/network/default.rb +1 -1
  30. data/lib/CORL/node/aws.rb +40 -16
  31. data/lib/CORL/node/local.rb +4 -3
  32. data/lib/CORL/node/rackspace.rb +25 -7
  33. data/lib/CORL/provisioner/puppetnode.rb +11 -9
  34. data/lib/core/errors.rb +6 -0
  35. data/lib/core/mod/fog_aws_server.rb +38 -0
  36. data/lib/core/plugin/action.rb +3 -11
  37. data/lib/core/plugin/configuration.rb +20 -2
  38. data/lib/{CORL/machine/fog.rb → core/plugin/fog_machine.rb} +92 -92
  39. data/lib/core/plugin/{fog.rb → fog_node.rb} +20 -7
  40. data/lib/core/plugin/machine.rb +58 -37
  41. data/lib/core/plugin/network.rb +76 -111
  42. data/lib/core/plugin/node.rb +271 -87
  43. data/lib/core/plugin/provisioner.rb +1 -1
  44. data/lib/corl.rb +6 -14
  45. data/locales/en.yml +18 -1
  46. metadata +39 -32
  47. data/lib/CORL/node/google.rb +0 -111
  48. data/lib/core/util/ssh.rb +0 -286
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-23 00:00:00.000000000 Z
12
+ date: 2014-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nucleon
16
- requirement: &4925940 !ruby/object:Gem::Requirement
16
+ requirement: &8964100 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,32 +21,32 @@ dependencies:
21
21
  version: '0.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *4925940
24
+ version_requirements: *8964100
25
25
  - !ruby/object:Gem::Dependency
26
- name: sshkey
27
- requirement: &4948820 !ruby/object:Gem::Requirement
26
+ name: fog
27
+ requirement: &8963100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: '1.6'
32
+ version: '1.20'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *4948820
35
+ version_requirements: *8963100
36
36
  - !ruby/object:Gem::Dependency
37
- name: fog
38
- requirement: &4946120 !ruby/object:Gem::Requirement
37
+ name: unf
38
+ requirement: &8962060 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- version: '1.20'
43
+ version: '0.1'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *4946120
46
+ version_requirements: *8962060
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: facter
49
- requirement: &4943120 !ruby/object:Gem::Requirement
49
+ requirement: &8961060 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '1.7'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *4943120
57
+ version_requirements: *8961060
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: hiera
60
- requirement: &4959260 !ruby/object:Gem::Requirement
60
+ requirement: &8959780 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '1.3'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *4959260
68
+ version_requirements: *8959780
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: puppet
71
- requirement: &4957380 !ruby/object:Gem::Requirement
71
+ requirement: &8957320 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '3.2'
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *4957380
79
+ version_requirements: *8957320
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: bundler
82
- requirement: &4955380 !ruby/object:Gem::Requirement
82
+ requirement: &8954800 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '1.2'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *4955380
90
+ version_requirements: *8954800
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: jeweler
93
- requirement: &4544900 !ruby/object:Gem::Requirement
93
+ requirement: &8952820 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '2.0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *4544900
101
+ version_requirements: *8952820
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rspec
104
- requirement: &4542800 !ruby/object:Gem::Requirement
104
+ requirement: &8951080 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '2.10'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *4542800
112
+ version_requirements: *8951080
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: rdoc
115
- requirement: &4537280 !ruby/object:Gem::Requirement
115
+ requirement: &8944580 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: '3.12'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *4537280
123
+ version_requirements: *8944580
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: yard
126
- requirement: &4657760 !ruby/object:Gem::Requirement
126
+ requirement: &8943360 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ~>
@@ -131,7 +131,7 @@ dependencies:
131
131
  version: '0.8'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *4657760
134
+ version_requirements: *8943360
135
135
  description: Framework that provides a simple foundation for growing organically in
136
136
  the cloud
137
137
  email: adrian.webb@coralnexus.com
@@ -164,45 +164,52 @@ files:
164
164
  - bootstrap/os/ubuntu/01_git.sh
165
165
  - bootstrap/os/ubuntu/05_ruby.sh
166
166
  - bootstrap/os/ubuntu/06_puppet.sh
167
+ - bootstrap/os/ubuntu/09_nucleon.sh
167
168
  - bootstrap/os/ubuntu/10_corl.sh
168
169
  - corl.gemspec
170
+ - lib/CORL/action/authorize.rb
169
171
  - lib/CORL/action/bootstrap.rb
172
+ - lib/CORL/action/destroy.rb
170
173
  - lib/CORL/action/exec.rb
171
174
  - lib/CORL/action/image.rb
172
175
  - lib/CORL/action/images.rb
173
176
  - lib/CORL/action/lookup.rb
174
177
  - lib/CORL/action/machines.rb
175
178
  - lib/CORL/action/provision.rb
179
+ - lib/CORL/action/regions.rb
176
180
  - lib/CORL/action/seed.rb
177
181
  - lib/CORL/action/spawn.rb
182
+ - lib/CORL/action/ssh.rb
178
183
  - lib/CORL/action/start.rb
179
184
  - lib/CORL/action/stop.rb
180
185
  - lib/CORL/configuration/file.rb
181
186
  - lib/CORL/event/puppet.rb
182
187
  - lib/CORL/extension/puppetloader.rb
183
- - lib/CORL/machine/fog.rb
188
+ - lib/CORL/machine/aws.rb
184
189
  - lib/CORL/machine/physical.rb
190
+ - lib/CORL/machine/rackspace.rb
185
191
  - lib/CORL/network/default.rb
186
192
  - lib/CORL/node/aws.rb
187
- - lib/CORL/node/google.rb
188
193
  - lib/CORL/node/local.rb
189
194
  - lib/CORL/node/rackspace.rb
190
195
  - lib/CORL/provisioner/puppetnode.rb
191
196
  - lib/CORL/provisioner/puppetnode/resource.rb
192
197
  - lib/CORL/provisioner/puppetnode/resource_group.rb
193
198
  - lib/CORL/template/environment.rb
199
+ - lib/core/errors.rb
194
200
  - lib/core/facade.rb
195
201
  - lib/core/mixin/action/keypair.rb
196
202
  - lib/core/mixin/lookup.rb
203
+ - lib/core/mod/fog_aws_server.rb
197
204
  - lib/core/mod/hiera_backend.rb
198
205
  - lib/core/plugin/action.rb
199
206
  - lib/core/plugin/configuration.rb
200
- - lib/core/plugin/fog.rb
207
+ - lib/core/plugin/fog_machine.rb
208
+ - lib/core/plugin/fog_node.rb
201
209
  - lib/core/plugin/machine.rb
202
210
  - lib/core/plugin/network.rb
203
211
  - lib/core/plugin/node.rb
204
212
  - lib/core/plugin/provisioner.rb
205
- - lib/core/util/ssh.rb
206
213
  - lib/corl.rb
207
214
  - lib/facter/corl_config_ready.rb
208
215
  - lib/facter/corl_exists.rb
@@ -1,111 +0,0 @@
1
-
2
- module CORL
3
- module Node
4
- class Google < Node::Fog
5
-
6
- #-----------------------------------------------------------------------------
7
- # Node plugin interface
8
-
9
- #-----------------------------------------------------------------------------
10
- # Checks
11
-
12
- def usable_image?(image)
13
- image.status == 'READY' && ! image.description.match(/DEPRECATED/i)
14
- end
15
-
16
- #-----------------------------------------------------------------------------
17
- # Property accessors / modifiers
18
-
19
- def project_name=project_name
20
- myself[:project_name] = project_name
21
- end
22
-
23
- def project_name
24
- myself[:project_name]
25
- end
26
-
27
- #---
28
-
29
- def regions
30
- [
31
- 'us-central1-a',
32
- 'us-central1-b',
33
- 'europe-west1-a',
34
- 'europe-west1-b'
35
- ]
36
- end
37
-
38
- #-----------------------------------------------------------------------------
39
- # Settings groups
40
-
41
- def machine_config
42
- super do |config|
43
- config.import({
44
- :provider => 'google'
45
- })
46
-
47
- config[:google_project] = project_name if project_name
48
- config[:google_client_email] = api_user if api_user
49
- config[:google_key_location] = api_key if api_key
50
- end
51
- end
52
-
53
- #-----------------------------------------------------------------------------
54
- # Node operations
55
-
56
- def create(options = {})
57
- super do |op, config|
58
- if op == :config
59
- config[:private_key_path] = private_key if private_key
60
- config[:public_key_path] = public_key if public_key
61
-
62
- config.defaults({
63
- :name => hostname,
64
- :machine_type => machine_type,
65
- :image_name => image
66
- })
67
- end
68
- end
69
- end
70
-
71
- #-----------------------------------------------------------------------------
72
- # Utilities
73
-
74
- def machine_type_id(machine_type)
75
- machine_type.name
76
- end
77
-
78
- #---
79
-
80
- def render_machine_type(machine_type)
81
- sprintf("[ %20s ][ VCPUS: %2i ] %-55s ( RAM: %6iMB | DISK: %3iGB ) ( MAX DISKS: %2i | MAX STORAGE: %6iGB )",
82
- machine_type_id(machine_type),
83
- machine_type.guest_cpus,
84
- machine_type.description,
85
- machine_type.memory_mb,
86
- machine_type.image_space_gb,
87
- machine_type.maximum_persistent_disks,
88
- machine_type.maximum_persistent_disks_size
89
- )
90
- end
91
-
92
- #---
93
-
94
- def image_id(image)
95
- image.name
96
- end
97
-
98
- #---
99
-
100
- def render_image(image)
101
- sprintf("[ %40s ][ %10s ] %s - %s", image_id(image), image.status, image.description, image.project)
102
- end
103
-
104
- #---
105
-
106
- def image_search_text(image)
107
- sprintf("%s %s %s %s", image.name, image.description, image.status, image.project)
108
- end
109
- end
110
- end
111
- end
data/lib/core/util/ssh.rb DELETED
@@ -1,286 +0,0 @@
1
-
2
- module CORL
3
- module Util
4
- class SSH < Nucleon::Core
5
-
6
- #-----------------------------------------------------------------------------
7
- # User key home
8
-
9
- @@key_path = nil
10
-
11
- #---
12
-
13
- def self.key_path
14
- unless @@key_path
15
- home_path = ( ENV['USER'] == 'root' ? '/root' : ENV['HOME'] ) # In case we are using sudo
16
- @@key_path = File.join(home_path, '.ssh')
17
-
18
- FileUtils.mkdir(@@key_path) unless File.directory?(@@key_path)
19
- end
20
- @@key_path
21
- end
22
-
23
- #-----------------------------------------------------------------------------
24
- # Instance generators
25
-
26
- def self.generate(options = {})
27
- config = Config.ensure(options)
28
-
29
- private_key = config.get(:private_key, nil)
30
- original_key = nil
31
- key_comment = config.get(:comment, '')
32
-
33
- if private_key.nil?
34
- key_type = config.get(:type, "RSA")
35
- key_bits = config.get(:bits, 2048)
36
- passphrase = config.get(:passphrase, nil)
37
-
38
- key_data = SSHKey.generate(
39
- :type => key_type,
40
- :bits => key_bits,
41
- :comment => key_comment,
42
- :passphrase => passphrase
43
- )
44
- is_new = true
45
-
46
- else
47
- if private_key.include?('PRIVATE KEY')
48
- original_key = private_key
49
- else
50
- original_key = Disk.read(private_key)
51
- end
52
-
53
- key_data = SSHKey.new(original_key, :comment => key_comment) if original_key
54
- is_new = false
55
- end
56
-
57
- return nil unless key_data && ! key_data.ssh_public_key.empty?
58
- Keypair.new(key_data, is_new, original_key)
59
- end
60
-
61
- #-----------------------------------------------------------------------------
62
- # Checks
63
-
64
- def self.valid?(public_ssh_key)
65
- SSHKey.valid_ssh_public_key?(public_ssh_key)
66
- end
67
-
68
- #-----------------------------------------------------------------------------
69
- # Keypair interface
70
-
71
- class Keypair
72
- attr_reader :type, :private_key, :encrypted_key, :public_key, :ssh_key
73
-
74
- def initialize(key_data, is_new, original_key)
75
- @type = key_data.type
76
- @private_key = key_data.private_key
77
- @encrypted_key = is_new ? key_data.encrypted_private_key : original_key
78
- @public_key = key_data.public_key
79
- @ssh_key = key_data.ssh_public_key
80
- end
81
-
82
- #---
83
-
84
- def store(key_path = nil, key_base = 'id')
85
- key_path = SSH.key_path if key_path.nil?
86
- private_key_file = File.join(key_path, "#{key_base}_#{type.downcase}")
87
- public_key_file = File.join(key_path, "#{key_base}_#{type.downcase}.pub")
88
-
89
- private_success = Disk.write(private_key_file, encrypted_key)
90
- FileUtils.chmod(0600, private_key_file) if private_success
91
-
92
- public_success = Disk.write(public_key_file, ssh_key)
93
-
94
- if private_success && public_success
95
- return { :private_key => private_key_file, :public_key => public_key_file }
96
- end
97
- false
98
- end
99
- end
100
-
101
- #-----------------------------------------------------------------------------
102
- # SSH Execution interface
103
-
104
- @@sessions = {}
105
-
106
- #---
107
-
108
- def self.session_id(hostname, user)
109
- "#{hostname}-#{user}"
110
- end
111
-
112
- #---
113
-
114
- def self.session(hostname, user, port = 22, private_key = nil, reset = false, options = {})
115
- require 'net/ssh'
116
-
117
- ssh_options = Config.new({
118
- :user_known_hosts_file => [ File.join(key_path, 'known_hosts'), File.join(key_path, 'known_hosts2') ],
119
- :key_data => [],
120
- :keys_only => false,
121
- :auth_methods => [ 'publickey' ],
122
- :paranoid => :very
123
- }).import(options)
124
-
125
- ssh_options[:port] = port
126
- ssh_options[:keys] = private_key.nil? ? [] : [ private_key ]
127
-
128
- session_id = session_id(hostname, user)
129
-
130
- if reset || ! @@sessions.has_key?(session_id)
131
- @@sessions[session_id] = Net::SSH.start(hostname, user, ssh_options.export)
132
- end
133
- yield(@@sessions[session_id]) if block_given? && @@sessions[session_id]
134
- @@sessions[session_id]
135
- end
136
-
137
- def self.init_session(hostname, user, port = 22, private_key = nil, options = {})
138
- session(hostname, user, port, private_key, true, options)
139
- end
140
-
141
- #---
142
-
143
- def self.close(hostname = nil, user = nil)
144
- if hostname && user.nil? # Assume we entered a session id
145
- if @@sessions.has_key?(hostname)
146
- @@sessions[hostname].close
147
- @@sessions.delete(hostname)
148
- end
149
-
150
- elsif hostname && user # Generate session id from args
151
- session_id = session_id(hostname, user)
152
-
153
- if @@sessions.has_key?(session_id)
154
- @@sessions[session_id].close
155
- @@sessions.delete(session_id)
156
- end
157
-
158
- else # Close all connections
159
- @@sessions.keys.each do |id|
160
- @@sessions[id].close
161
- @@sessions.delete(id)
162
- end
163
- end
164
- end
165
-
166
- #---
167
-
168
- def self.exec(hostname, user, commands)
169
- results = []
170
-
171
- begin
172
- session(hostname, user) do |ssh|
173
- Data.array(commands).each do |command|
174
- command = command.flatten.join(' ') if command.is_a?(Array)
175
- command = command.to_s
176
- result = Shell::Result.new(command)
177
-
178
- ssh.open_channel do |ssh_channel|
179
- ssh_channel.request_pty
180
- ssh_channel.exec(command) do |channel, success|
181
- unless success
182
- raise "Could not execute command: #{command.inspect}"
183
- end
184
-
185
- channel.on_data do |ch, data|
186
- result.append_output(data)
187
- yield(:output, command, data) if block_given?
188
- end
189
-
190
- channel.on_extended_data do |ch, type, data|
191
- next unless type == 1
192
- result.append_errors(data)
193
- yield(:error, command, data) if block_given?
194
- end
195
-
196
- channel.on_request('exit-status') do |ch, data|
197
- result.status = data.read_long
198
- end
199
-
200
- channel.on_request('exit-signal') do |ch, data|
201
- result.status = 255
202
- end
203
- end
204
- end
205
- ssh.loop
206
- results << result
207
- end
208
- end
209
- rescue Net::SSH::HostKeyMismatch => error
210
- error.remember_host!
211
- sleep 0.2
212
- retry
213
- end
214
- results
215
- end
216
-
217
- #---
218
-
219
- def self.download(hostname, user, remote_path, local_path, options = {})
220
- config = Config.ensure(options)
221
-
222
- require 'net/scp'
223
-
224
- # Accepted options:
225
- # * :recursive - the +remote+ parameter refers to a remote directory, which
226
- # should be downloaded to a new directory named +local+ on the local
227
- # machine.
228
- # * :preserve - the atime and mtime of the file should be preserved.
229
- # * :verbose - the process should result in verbose output on the server
230
- # end (useful for debugging).
231
- #
232
- config.init(:recursive, true)
233
- config.init(:preserve, true)
234
- config.init(:verbose, true)
235
-
236
- blocking = config.delete(:blocking, true)
237
-
238
- session(hostname, user) do |ssh|
239
- if blocking
240
- ssh.scp.download!(remote_path, local_path, config.export) do |ch, name, received, total|
241
- yield(name, received, total) if block_given?
242
- end
243
- else
244
- ssh.scp.download(remote_path, local_path, config.export)
245
- end
246
- end
247
- end
248
-
249
- #---
250
-
251
- def self.upload(hostname, user, local_path, remote_path, options = {})
252
- config = Config.ensure(options)
253
-
254
- require 'net/scp'
255
-
256
- # Accepted options:
257
- # * :recursive - the +local+ parameter refers to a local directory, which
258
- # should be uploaded to a new directory named +remote+ on the remote
259
- # server.
260
- # * :preserve - the atime and mtime of the file should be preserved.
261
- # * :verbose - the process should result in verbose output on the server
262
- # end (useful for debugging).
263
- # * :chunk_size - the size of each "chunk" that should be sent. Defaults
264
- # to 2048. Changing this value may improve throughput at the expense
265
- # of decreasing interactivity.
266
- #
267
- config.init(:recursive, true)
268
- config.init(:preserve, true)
269
- config.init(:verbose, true)
270
- config.init(:chunk_size, 2048)
271
-
272
- blocking = config.delete(:blocking, true)
273
-
274
- session(hostname, user) do |ssh|
275
- if blocking
276
- ssh.scp.upload!(local_path, remote_path, config.export) do |ch, name, sent, total|
277
- yield(name, sent, total) if block_given?
278
- end
279
- else
280
- ssh.scp.upload(local_path, remote_path, config.export)
281
- end
282
- end
283
- end
284
- end
285
- end
286
- end