corl 0.4.1 → 0.4.2

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