corl 0.5.16 → 0.5.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6525066ff89087597683642d763aaf33dc8d4f30
4
- data.tar.gz: 4d6ffa51014c3f8316a118ef6f5b8476da2e0b0b
3
+ metadata.gz: 0987aea3e56e4c6c391769f7a397327470928975
4
+ data.tar.gz: f6ae921e7cfa279434d37dc835a9e49a4f633820
5
5
  SHA512:
6
- metadata.gz: 668c3569ee4d16da744d12da994f72565fa0b01b90c254359b5315fe28c7d5d313d351b8d3e061d45b5cfd3e316aed13522da50812aab605ba2774c6de72dee2
7
- data.tar.gz: b4b76ae9c30d0993a305ce6f872159861bdbd898763f66bb614a20d16def26556e1feb717050834fa13bf63d4cc01f080794f6c3a45acc53b27aafc213ccf636
6
+ metadata.gz: 77bf6dc4495017957515547cf549783c35727342f1f3046f10bb118cdf4f716802c1e5312fb5f670844171bfd8c2adb79ad05286752e4c8d97b9dcf7ce82bb90
7
+ data.tar.gz: 6f1005482750cd2f3f1e328165e16a24b3f31a9101e20adb84b4f481ac6c39af2250cc2862ca1c51929c61b4c2d23e774c2336556cbdaa903cc81830f01ea9e4
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source "http://rubygems.org"
2
2
 
3
3
  gem "nucleon", "~> 0.2", ">= 0.2.2", :github => 'coralnexus/nucleon', :branch => '0.2'
4
4
 
5
+ gem "net-ping", "~> 1.7"
6
+
5
7
  gem "fog", "~> 1.23"
6
8
  gem "unf", "~> 0.1"
7
9
 
data/Gemfile.lock CHANGED
@@ -132,6 +132,7 @@ GEM
132
132
  multi_json (1.10.1)
133
133
  multi_xml (0.5.5)
134
134
  multipart-post (2.0.0)
135
+ net-ping (1.7.7)
135
136
  net-scp (1.2.1)
136
137
  net-ssh (>= 2.6.5)
137
138
  net-ssh (2.9.1)
@@ -198,6 +199,7 @@ DEPENDENCIES
198
199
  github-markup (~> 1.3)
199
200
  hiera (~> 1.3)
200
201
  jeweler (~> 2.0)
202
+ net-ping (~> 1.7)
201
203
  nucleon (~> 0.2, >= 0.2.2)!
202
204
  puppet (~> 3.7)
203
205
  rdoc (~> 3.12)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.16
1
+ 0.5.17
@@ -12,4 +12,14 @@ mkdir -p "/root/.ssh" || exit 11
12
12
  touch "/root/.ssh/known_hosts" || exit 12
13
13
 
14
14
  ssh-keygen -R github.com >/dev/null 2>&1 || exit 13 # No duplicates
15
- ssh-keyscan -H github.com >> "/root/.ssh/known_hosts" 2>/dev/null || exit 14
15
+ ssh-keyscan -H github.com >> "/root/.ssh/known_hosts" 2>/dev/null || exit 14
16
+
17
+ echo "3. Adding default Git configurations"
18
+ if [ -z "`git config --global user.name`" ]
19
+ then
20
+ git config --global user.name "CoralNexus Machine"
21
+ fi
22
+ if [ -z "`git config --global user.email`" ]
23
+ then
24
+ git config --global user.email "admin@coralnexus.com"
25
+ fi
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  #-------------------------------------------------------------------------------
3
3
 
4
- PUPPET_PACKAGE="3.7.4-1puppetlabs1"
4
+ PUPPET_PACKAGE="3.7.5-1puppetlabs1"
5
5
 
6
6
  #---
7
7
 
data/corl.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: corl 0.5.16 ruby lib
5
+ # stub: corl 0.5.17 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "corl"
9
- s.version = "0.5.16"
9
+ s.version = "0.5.17"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Adrian Webb"]
14
- s.date = "2015-02-26"
14
+ s.date = "2015-04-29"
15
15
  s.description = "Framework that provides a simple foundation for growing organically in the cloud"
16
16
  s.email = "adrian.webb@coralnexus.com"
17
17
  s.executables = ["corl"]
@@ -58,11 +58,13 @@ Gem::Specification.new do |s|
58
58
  "lib/CORL/machine/AWS.rb",
59
59
  "lib/CORL/machine/physical.rb",
60
60
  "lib/CORL/machine/rackspace.rb",
61
+ "lib/CORL/machine/raspberrypi.rb",
61
62
  "lib/CORL/machine/vagrant.rb",
62
63
  "lib/CORL/network/CORL.rb",
63
64
  "lib/CORL/node/AWS.rb",
64
65
  "lib/CORL/node/local.rb",
65
66
  "lib/CORL/node/rackspace.rb",
67
+ "lib/CORL/node/raspberrypi.rb",
66
68
  "lib/CORL/node/vagrant.rb",
67
69
  "lib/CORL/provisioner/puppetnode.rb",
68
70
  "lib/core/build.rb",
@@ -106,6 +108,7 @@ Gem::Specification.new do |s|
106
108
  "lib/facter/corl_config_ready.rb",
107
109
  "lib/facter/corl_network.rb",
108
110
  "lib/facter/custom_facts.rb",
111
+ "lib/facter/raspberry_pi.rb",
109
112
  "lib/facter/vagrant_exists.rb",
110
113
  "lib/hiera/corl_logger.rb",
111
114
  "lib/nucleon/action/agent/manager.rb",
@@ -128,6 +131,7 @@ Gem::Specification.new do |s|
128
131
  "lib/nucleon/action/node/build.rb",
129
132
  "lib/nucleon/action/node/cache.rb",
130
133
  "lib/nucleon/action/node/destroy.rb",
134
+ "lib/nucleon/action/node/devkey.rb",
131
135
  "lib/nucleon/action/node/download.rb",
132
136
  "lib/nucleon/action/node/exec.rb",
133
137
  "lib/nucleon/action/node/fact.rb",
@@ -193,6 +197,7 @@ Gem::Specification.new do |s|
193
197
 
194
198
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
195
199
  s.add_runtime_dependency(%q<nucleon>, [">= 0.2.2", "~> 0.2"])
200
+ s.add_runtime_dependency(%q<net-ping>, ["~> 1.7"])
196
201
  s.add_runtime_dependency(%q<fog>, ["~> 1.23"])
197
202
  s.add_runtime_dependency(%q<unf>, ["~> 0.1"])
198
203
  s.add_runtime_dependency(%q<facter>, ["~> 2.3"])
@@ -205,6 +210,7 @@ Gem::Specification.new do |s|
205
210
  s.add_development_dependency(%q<github-markup>, ["~> 1.3"])
206
211
  else
207
212
  s.add_dependency(%q<nucleon>, [">= 0.2.2", "~> 0.2"])
213
+ s.add_dependency(%q<net-ping>, ["~> 1.7"])
208
214
  s.add_dependency(%q<fog>, ["~> 1.23"])
209
215
  s.add_dependency(%q<unf>, ["~> 0.1"])
210
216
  s.add_dependency(%q<facter>, ["~> 2.3"])
@@ -218,6 +224,7 @@ Gem::Specification.new do |s|
218
224
  end
219
225
  else
220
226
  s.add_dependency(%q<nucleon>, [">= 0.2.2", "~> 0.2"])
227
+ s.add_dependency(%q<net-ping>, ["~> 1.7"])
221
228
  s.add_dependency(%q<fog>, ["~> 1.23"])
222
229
  s.add_dependency(%q<unf>, ["~> 0.1"])
223
230
  s.add_dependency(%q<facter>, ["~> 2.3"])
@@ -2,146 +2,146 @@
2
2
  module CORL
3
3
  module Machine
4
4
  class Physical < Nucleon.plugin_class(:CORL, :machine)
5
-
5
+
6
6
  #-----------------------------------------------------------------------------
7
7
  # Machine plugin interface
8
-
8
+
9
9
  def normalize(reload)
10
10
  super
11
11
  myself.plugin_name = hostname
12
12
  end
13
-
13
+
14
14
  #-----------------------------------------------------------------------------
15
15
  # Checks
16
-
16
+
17
17
  def created?
18
18
  true
19
19
  end
20
-
20
+
21
21
  #---
22
-
22
+
23
23
  def running?
24
24
  true
25
25
  end
26
-
26
+
27
27
  #-----------------------------------------------------------------------------
28
28
  # Property accessors / modifiers
29
-
29
+
30
30
  def state
31
31
  translate_state('RUNNING')
32
32
  end
33
-
33
+
34
34
  #---
35
-
35
+
36
36
  def hostname
37
37
  fact(:fqdn)
38
38
  end
39
-
39
+
40
40
  #---
41
-
41
+
42
42
  def public_ip
43
- CORL.public_ip
43
+ CORL.public_ip
44
44
  end
45
-
45
+
46
46
  #---
47
-
47
+
48
48
  def private_ip
49
49
  nil
50
50
  end
51
-
51
+
52
52
  #---
53
-
53
+
54
54
  def machine_type
55
55
  'physical'
56
56
  end
57
-
57
+
58
58
  #---
59
-
59
+
60
60
  def image
61
61
  nil
62
62
  end
63
-
63
+
64
64
  #-----------------------------------------------------------------------------
65
65
  # Management
66
66
 
67
67
  def load
68
68
  super do
69
69
  true
70
- end
70
+ end
71
71
  end
72
-
72
+
73
73
  #---
74
-
74
+
75
75
  def create(options = {})
76
76
  super do
77
77
  logger.warn("Damn! We can't create new instances of physical machines")
78
78
  true
79
79
  end
80
80
  end
81
-
81
+
82
82
  #---
83
-
83
+
84
84
  def download(remote_path, local_path, options = {})
85
85
  super do |config, success|
86
86
  logger.debug("Executing SCP downloads not yet supported on physical machines")
87
87
  true
88
88
  end
89
89
  end
90
-
90
+
91
91
  #---
92
-
92
+
93
93
  def upload(local_path, remote_path, options = {})
94
94
  super do |config, success|
95
95
  logger.debug("Executing SCP uploads not yet supported on physical machines")
96
96
  true
97
97
  end
98
98
  end
99
-
99
+
100
100
  #---
101
-
101
+
102
102
  def exec(commands, options = {}, &code)
103
103
  super do |config, results|
104
104
  logger.debug("Executing shell commands ( #{commands.inspect} ) on machine #{plugin_name}")
105
-
105
+
106
106
  commands.each do |command|
107
107
  result = CORL.cli_run(command, config) do |op, command_str, data|
108
108
  code ? code.call(op, command_str, data) : true
109
- end
109
+ end
110
110
  results << result
111
111
  end
112
112
  results
113
113
  end
114
114
  end
115
-
115
+
116
116
  #---
117
-
117
+
118
118
  def terminal(user, options = {})
119
119
  super do |config|
120
120
  logger.debug("Launching terminals on the local machine is not currently supported")
121
121
  1
122
122
  end
123
123
  end
124
-
124
+
125
125
  #---
126
-
126
+
127
127
  def start(options = {})
128
128
  super do
129
129
  logger.warn("This machine is already running so can not be started")
130
130
  true
131
131
  end
132
132
  end
133
-
133
+
134
134
  #---
135
-
135
+
136
136
  def reload(options = {})
137
- return super do
137
+ super do
138
138
  logger.warn("Reloading not currently supported on physical machines")
139
139
  true
140
140
  end
141
141
  end
142
-
142
+
143
143
  #---
144
-
144
+
145
145
  def create_image(name, options = {})
146
146
  super do
147
147
  logger.warn("Creating images of local machines not supported yet")
@@ -149,20 +149,20 @@ class Physical < Nucleon.plugin_class(:CORL, :machine)
149
149
  end
150
150
  end
151
151
  #---
152
-
152
+
153
153
  def stop(options = {})
154
154
  super do
155
155
  logger.warn("Stopping the machine we are operating is not supported right now")
156
156
  true
157
157
  end
158
158
  end
159
-
159
+
160
160
  #---
161
161
 
162
162
  def destroy(options = {})
163
163
  super do
164
164
  logger.warn("If you want to destroy your physical machine, grab a hammer")
165
- true
165
+ true
166
166
  end
167
167
  end
168
168
  end
@@ -0,0 +1,155 @@
1
+
2
+ module CORL
3
+ module Machine
4
+ class Raspberrypi < Nucleon.plugin_class(:CORL, :machine)
5
+
6
+ include Mixin::Machine::SSH
7
+
8
+ #-----------------------------------------------------------------------------
9
+ # Machine plugin interface
10
+
11
+ def normalize(reload)
12
+ require 'net/ping'
13
+
14
+ super
15
+ myself.plugin_name = node.plugin_name if node
16
+ end
17
+
18
+ #-----------------------------------------------------------------------------
19
+ # Checks
20
+
21
+ def created?
22
+ true
23
+ end
24
+
25
+ #---
26
+
27
+ def running?
28
+ Net::Ping::TCP.new(public_ip, node.ssh_port).ping?
29
+ end
30
+
31
+ #-----------------------------------------------------------------------------
32
+ # Property accessors / modifiers
33
+
34
+ def public_ip
35
+ node[:public_ip]
36
+ end
37
+
38
+ #---
39
+
40
+ def state
41
+ running? ? :running : :not_running
42
+ end
43
+
44
+ #---
45
+
46
+ def machine_type
47
+ 'raspberrypi'
48
+ end
49
+
50
+ #---
51
+
52
+ def image
53
+ nil
54
+ end
55
+
56
+ #-----------------------------------------------------------------------------
57
+ # Management
58
+
59
+ def load
60
+ super do
61
+ true
62
+ end
63
+ end
64
+
65
+ #---
66
+
67
+ def create(options = {})
68
+ super do
69
+ logger.warn("Damn! We can't create new instances of Raspberry Pi machines")
70
+ true
71
+ end
72
+ end
73
+
74
+ #---
75
+
76
+ def download(remote_path, local_path, options = {}, &code)
77
+ super do |config, success|
78
+ ssh_download(remote_path, local_path, config, &code)
79
+ end
80
+ end
81
+
82
+ #---
83
+
84
+ def upload(local_path, remote_path, options = {}, &code)
85
+ super do |config, success|
86
+ ssh_upload(local_path, remote_path, config, &code)
87
+ end
88
+ end
89
+
90
+ #---
91
+
92
+ def exec(commands, options = {}, &code)
93
+ super do |config|
94
+ ssh_exec(commands, config, &code)
95
+ end
96
+ end
97
+
98
+ #---
99
+
100
+ def terminal(user, options = {})
101
+ super do |config|
102
+ ssh_terminal(user, config)
103
+ end
104
+ end
105
+
106
+ #---
107
+
108
+ def reload(options = {})
109
+ super do
110
+ node.command('reboot', { :as_admin => true })
111
+ end
112
+ end
113
+
114
+ #---
115
+
116
+ def create_image(options = {})
117
+ super do
118
+ logger.warn("Creating images of Raspberry Pi machines not supported yet")
119
+ true
120
+ end
121
+ end
122
+
123
+ #---
124
+
125
+ def stop(options = {})
126
+ super do
127
+ logger.warn("Stopping a Raspberry Pi machine is not supported right now")
128
+ true
129
+ end
130
+ end
131
+
132
+ #---
133
+
134
+ def start(options = {})
135
+ super do
136
+ logger.warn("Starting a Raspberry Pi machine is not supported right now")
137
+ true
138
+ end
139
+ end
140
+
141
+ #---
142
+
143
+ def destroy(options = {})
144
+ super do
145
+ logger.warn("If you want to destroy your Raspberry Pi machine, grab a hammer")
146
+ true
147
+ end
148
+ end
149
+
150
+ #-----------------------------------------------------------------------------
151
+ # Utilities
152
+
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module CORL
3
+ module Node
4
+ class Raspberrypi < Nucleon.plugin_class(:CORL, :node)
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Node plugin interface
8
+
9
+ def normalize(reload)
10
+ super
11
+ myself.machine = create_machine(:machine, :raspberrypi, machine_config)
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Checks
16
+
17
+ def local?
18
+ false
19
+ end
20
+
21
+ #-----------------------------------------------------------------------------
22
+ # Property accessors / modifiers
23
+
24
+ #-----------------------------------------------------------------------------
25
+ # Utilities
26
+
27
+ end
28
+ end
29
+ end
@@ -243,19 +243,6 @@ class Vagrant < Nucleon.plugin_class(:CORL, :node)
243
243
  end
244
244
  end
245
245
 
246
- #---
247
-
248
- def filter_output(type, data)
249
- data = super
250
-
251
- if type == :error
252
- if data.include?('stdin: is not a tty') || data.include?('unable to re-open stdin')
253
- data = ''
254
- end
255
- end
256
- data
257
- end
258
-
259
246
  #-----------------------------------------------------------------------------
260
247
  # Machine type utilities
261
248
 
@@ -28,6 +28,9 @@ class Puppetnode < Nucleon.plugin_class(:CORL, :provisioner)
28
28
 
29
29
  def normalize(reload)
30
30
  super do
31
+ require 'puppet'
32
+ require 'puppet/configurer'
33
+
31
34
  if [ :debug, :info, :warn ].include? CORL.log_level
32
35
  Puppet.debug = true
33
36
  end
@@ -86,9 +89,6 @@ class Puppetnode < Nucleon.plugin_class(:CORL, :provisioner)
86
89
  # Puppet initialization
87
90
 
88
91
  def init_puppet(node, profiles)
89
- require 'puppet'
90
- require 'puppet/configurer'
91
-
92
92
  Puppet.initialize_settings
93
93
 
94
94
  apply_environment = nil
data/lib/core/facade.rb CHANGED
@@ -44,6 +44,9 @@ module Facade
44
44
  ip_address = Config.fact(:ipaddress_eth1)
45
45
  ip_address = Config.fact(:ipaddress_eth0) unless ip_address
46
46
  ip_address
47
+ elsif Config.fact(:raspberry_pi)
48
+ ip_address = Config.fact(:ipaddress_eth0)
49
+ ip_address
47
50
  else
48
51
  CORL.ip_address
49
52
  end
@@ -3,10 +3,10 @@ module CORL
3
3
  module Mixin
4
4
  module Action
5
5
  module Keypair
6
-
6
+
7
7
  #-----------------------------------------------------------------------------
8
8
  # Options
9
-
9
+
10
10
  def keypair_config
11
11
  register_str :private_key, nil, 'corl.core.mixin.action.keypair.options.private_key' do |value|
12
12
  success = true
@@ -19,53 +19,53 @@ module Keypair
19
19
  end
20
20
  else
21
21
  warn('corl.core.mixin.action.keypair.errors.private_key_not_found', { :value => file })
22
- success = false
22
+ success = false
23
23
  end
24
24
  end
25
- success
25
+ success
26
26
  end
27
-
27
+
28
28
  register_bool :require_password, false, 'corl.core.mixin.action.keypair.options.require_password'
29
-
29
+
30
30
  register_str :key_type, 'RSA', 'corl.core.mixin.action.keypair.options.key_type' do |value|
31
31
  key_type_choices = [ 'RSA', 'DSA' ]
32
32
  unless key_type_choices.include?(value.to_s.upcase)
33
33
  warn('corl.core.mixin.action.keypair.errors.key_type', { :value => value, :choices => key_type_choices })
34
- next false
34
+ next false
35
35
  end
36
36
  true
37
37
  end
38
38
  register_int :key_bits, 2048, 'corl.core.mixin.action.keypair.options.key_bits' do |value|
39
39
  unless value >= 2048
40
40
  warn('corl.core.mixin.action.keypair.errors.key_bits', { :value => value, :required => 2048 })
41
- next false
41
+ next false
42
42
  end
43
- true
43
+ true
44
44
  end
45
45
  register_str :key_comment, '', 'corl.core.mixin.action.keypair.options.key_comment'
46
-
46
+
47
47
  config_subset(keypair_ignore)
48
48
  end
49
-
49
+
50
50
  #---
51
-
51
+
52
52
  def keypair_ignore
53
53
  [ :require_password, :key_type, :key_bits, :key_comment ]
54
54
  end
55
-
55
+
56
56
  #---
57
-
57
+
58
58
  def keypair_clean
59
- remove(keypair_ignore)
59
+ remove(keypair_ignore)
60
60
  end
61
-
61
+
62
62
  #-----------------------------------------------------------------------------
63
63
  # Properties
64
-
64
+
65
65
  @keypair = nil
66
-
66
+
67
67
  #---
68
-
68
+
69
69
  def keypair=options
70
70
  config = Config.ensure(options).defaults({
71
71
  :type => settings[:key_type].to_s.upcase,
@@ -75,13 +75,13 @@ module Keypair
75
75
  @keypair = Util::SSH.generate(config)
76
76
  settings.import({ :keypair => @keypair })
77
77
  end
78
-
78
+
79
79
  #---
80
-
81
- def keypair(reset = false)
80
+
81
+ def keypair(reset = false, warn = true)
82
82
  if reset || ! @keypair
83
83
  if settings[:private_key]
84
- key_options = { :private_key => private_key }
84
+ key_options = { :private_key => private_key }
85
85
  else
86
86
  key_options = {}
87
87
  if settings[:require_password]
@@ -89,7 +89,7 @@ module Keypair
89
89
  if key_password
90
90
  key_options[:passphrase] = key_password
91
91
  else
92
- warn('no_password')
92
+ warn('no_password') if warn
93
93
  return nil
94
94
  end
95
95
  end
@@ -19,7 +19,8 @@ module SSH
19
19
  ssh_config = Config.new({
20
20
  :keypair => node.keypair,
21
21
  :key_dir => node.network.key_cache_directory,
22
- :key_name => node.plugin_name
22
+ :key_name => node.plugin_name,
23
+ :password => node.password
23
24
  })
24
25
 
25
26
  begin
@@ -70,6 +70,8 @@ class CloudAction < Nucleon.plugin_class(:nucleon, :action)
70
70
  # Settings
71
71
 
72
72
  def node_config
73
+ register_str :user_password, nil, 'corl.core.action.options.user_password'
74
+
73
75
  register_str :net_remote, :edit, 'corl.core.action.options.net_remote'
74
76
  register_network_provider :net_provider, :corl, [ 'corl.core.action.options.net_provider', 'corl.core.action.errors.network_provider' ]
75
77
 
@@ -114,6 +116,8 @@ class CloudAction < Nucleon.plugin_class(:nucleon, :action)
114
116
  def node_exec
115
117
  init_network(settings[:net_provider]) unless network && settings[:net_provider].to_sym == network.plugin_provider
116
118
 
119
+ network.node_password = settings[:user_password] if network && settings[:user_password]
120
+
117
121
  #
118
122
  # A fork in the road...
119
123
  #
@@ -28,7 +28,8 @@ class Configuration < Nucleon.plugin_class(:nucleon, :base)
28
28
  :revision => _delete(:revision),
29
29
  :create => _delete(:create, false),
30
30
  :pull => true,
31
- :internal_ip => CORL.public_ip, # Needed for seeding Vagrant VMs
31
+ :external_ip => _delete(:external_ip, nil),
32
+ :internal_ip => _delete(:internal_ip, CORL.public_ip), # Needed for seeding Vagrant VMs
32
33
  :manage_ignore => _delete(:manage_ignore, true),
33
34
  :new => true
34
35
  }), _delete(:project_provider, nil)) unless reload
@@ -220,16 +220,6 @@ class FogBase < Nucleon.plugin_class(:CORL, :node)
220
220
  #-----------------------------------------------------------------------------
221
221
  # Utilities
222
222
 
223
- def filter_output(type, data)
224
- data = super
225
-
226
- if type == :error
227
- if data.include?('stdin: is not a tty') || data.include?('unable to re-open stdin')
228
- data = ''
229
- end
230
- end
231
- data
232
- end
233
223
  end
234
224
  end
235
225
  end
@@ -131,6 +131,16 @@ class Network < Nucleon.plugin_class(:nucleon, :base)
131
131
 
132
132
  #---
133
133
 
134
+ def node_password=password
135
+ @node_password = password
136
+ end
137
+
138
+ def node_password
139
+ @node_password
140
+ end
141
+
142
+ #---
143
+
134
144
  def node_groups
135
145
  groups = {}
136
146
 
@@ -229,6 +239,8 @@ class Network < Nucleon.plugin_class(:nucleon, :base)
229
239
  local_node.normalize(true)
230
240
  local_node.localize
231
241
  end
242
+
243
+ local_node.password = node_password
232
244
  local_node
233
245
  end
234
246
 
@@ -480,6 +492,7 @@ class Network < Nucleon.plugin_class(:nucleon, :base)
480
492
  if CORL.parallel? && parallel
481
493
  values = []
482
494
  nodes.each do |node|
495
+ node.password = node_password
483
496
  if ! running || node.running?
484
497
  values << Celluloid::Future.new(node, &code)
485
498
  end
@@ -488,6 +501,7 @@ class Network < Nucleon.plugin_class(:nucleon, :base)
488
501
  success = false if values.include?(false)
489
502
  else
490
503
  nodes.each do |node|
504
+ node.password = node_password
491
505
  if ! running || node.running?
492
506
  proc_success = code.call(node)
493
507
  if proc_success == false
@@ -174,6 +174,16 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
174
174
 
175
175
  #---
176
176
 
177
+ def password=password
178
+ @password = password
179
+ end
180
+
181
+ def password
182
+ @password
183
+ end
184
+
185
+ #---
186
+
177
187
  def ssh_port=ssh_port
178
188
  myself[:ssh_port] = ssh_port
179
189
  machine.init_ssh(ssh_port) if machine
@@ -643,9 +653,10 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
643
653
  :message => "Updating SSH keys for node #{plugin_provider} (#{plugin_name})"
644
654
  }
645
655
 
646
- active = machine && machine.running?
647
- result = run.authorize({ :public_key => keypair.ssh_key }) if active
648
- success = false
656
+ active = machine && machine.running?
657
+ ssh_user = user ? user : 'root'
658
+ result = run.node_authorize({ :public_key => keypair.ssh_key, :ssh_user => ssh_user }) if active
659
+ success = false
649
660
 
650
661
  if ! active || result.status == code.success
651
662
  private_key = network.attach_data(:keys, "#{base_name}-id_#{keypair.type}", keypair.encrypted_key)
@@ -944,7 +955,10 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
944
955
 
945
956
  admin_command = ''
946
957
  if as_admin
947
- admin_command = config.delete(:admin_command, 'sudo -i')
958
+ admin_options = config.delete(:admin_options, '-i')
959
+ default_admin_command = password ? "echo '#{password}' | sudo -S #{admin_options}" : "sudo #{admin_options}"
960
+
961
+ admin_command = config.delete(:admin_command, default_admin_command)
948
962
  admin_command = extension_set(:admin_command, admin_command, config)
949
963
  else
950
964
  config.delete(:admin_command)
@@ -988,7 +1002,13 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
988
1002
  command_base = "NUCLEON_NO_PARALLEL=1 #{command_base}" unless parallel
989
1003
  command_base = "NUCLEON_NO_COLOR=1 #{command_base}" if action_agent
990
1004
 
991
- result = command(command_base, { :subcommand => action_config, :as_admin => true, :quiet => quiet }) do |op, data|
1005
+ result = command(command_base, Util::Data.clean({
1006
+ :subcommand => action_config,
1007
+ :as_admin => true,
1008
+ :admin_options => config.get(:admin_options, nil),
1009
+ :admin_command => config.get(:admin_command, nil),
1010
+ :quiet => quiet
1011
+ })) do |op, data|
992
1012
  yield(op, data) if block_given?
993
1013
  end
994
1014
 
@@ -1024,6 +1044,8 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
1024
1044
  active_machine = machine
1025
1045
  end
1026
1046
 
1047
+ config[:key_dir] = network.key_cache_directory
1048
+ config[:key_name] = plugin_name
1027
1049
  config[:private_keys] = private_key
1028
1050
  config[:port] = ssh_port
1029
1051
 
@@ -1087,7 +1109,7 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
1087
1109
  auth_files = package_files.collect { |path| "'#{path}'"}
1088
1110
  root_home_path = config.get(:root_home, '/root')
1089
1111
 
1090
- result = command("cp #{auth_files.join(' ')} #{root_home_path}", { :as_admin => true, :admin_command => 'sudo' })
1112
+ result = command("cp #{auth_files.join(' ')} #{root_home_path}", { :as_admin => true, :admin_options => '' })
1091
1113
  myself.status = code.root_auth_copy_failure unless result.status == code.success
1092
1114
  end
1093
1115
 
@@ -1448,8 +1470,11 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
1448
1470
  data = ''
1449
1471
  end
1450
1472
  elsif type == :error
1451
- # Hide Rubinius SAFE warning
1452
- if data == 'WARNING: $SAFE is not supported on Rubinius.'
1473
+ if data.include?('stdin: is not a tty') ||
1474
+ data.include?('unable to re-open stdin') ||
1475
+ data.include?('[sudo] password for') ||
1476
+ data.include?('sudo: unable to resolve host') ||
1477
+ data == 'WARNING: $SAFE is not supported on Rubinius.'
1453
1478
  data = ''
1454
1479
  end
1455
1480
  end
@@ -0,0 +1,14 @@
1
+
2
+ Facter.add(:raspberry_pi) do
3
+ confine :kernel => :linux
4
+
5
+ setcode do
6
+ raspberry_pi = nil
7
+ begin
8
+ raspberry_pi = true if File.exist?('/usr/lib/raspberrypi')
9
+
10
+ rescue # Prevent abortions.
11
+ end
12
+ raspberry_pi
13
+ end
14
+ end
@@ -3,53 +3,55 @@ module Nucleon
3
3
  module Action
4
4
  module Node
5
5
  class Authorize < Nucleon.plugin_class(:nucleon, :cloud_action)
6
-
6
+
7
7
  #-----------------------------------------------------------------------------
8
8
  # Info
9
-
9
+
10
10
  def self.describe
11
11
  super(:node, :authorize, 555)
12
12
  end
13
-
13
+
14
14
  #-----------------------------------------------------------------------------
15
15
  # Settings
16
-
16
+
17
17
  def configure
18
18
  super do
19
19
  codes :key_store_failure
20
-
21
- register :reset, :bool, false
22
- register :public_key, :str, nil
20
+
21
+ register_bool :reset, false
22
+ register_str :public_key, nil
23
+ register_str :ssh_user, ''
23
24
  end
24
25
  end
25
-
26
+
26
27
  #---
27
-
28
+
28
29
  def arguments
29
- [ :public_key ]
30
+ [ :public_key, :ssh_user ]
30
31
  end
31
32
 
32
33
  #-----------------------------------------------------------------------------
33
34
  # Operations
34
-
35
+
35
36
  def execute
36
37
  super do |node|
37
- info('corl.actions.authorize.start')
38
-
38
+ info('start', { :public_key => settings[:public_key] })
39
+
39
40
  ensure_node(node) do
40
- ssh_path = Util::SSH.key_path
41
- authorized_keys = File.join(ssh_path, 'authorized_keys')
41
+ ssh_user = settings[:ssh_user].empty? ? nil : settings[:ssh_user]
42
+ ssh_path = Util::SSH.key_path(ssh_user)
43
+ authorized_keys = File.join(ssh_path, 'authorized_keys')
42
44
  public_key = settings[:public_key].strip
43
45
  key_found = false
44
-
46
+
45
47
  File.delete(authorized_keys) if settings[:reset]
46
-
48
+
47
49
  if File.exists?(authorized_keys)
48
50
  Util::Disk.read(authorized_keys).split("\n").each do |line|
49
51
  if line.strip.include?(public_key)
50
52
  key_found = true
51
- break
52
- end
53
+ break
54
+ end
53
55
  end
54
56
  end
55
57
  unless key_found
@@ -0,0 +1,87 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Node
5
+ class Devkey < Nucleon.plugin_class(:nucleon, :cloud_action)
6
+
7
+ include Mixin::Action::Keypair
8
+
9
+ #-----------------------------------------------------------------------------
10
+ # Info
11
+
12
+ def self.describe
13
+ super(:node, :devkey, 530)
14
+ end
15
+
16
+ #-----------------------------------------------------------------------------
17
+ # Settings
18
+
19
+ def configure
20
+ super do
21
+ codes :no_password_given
22
+
23
+ keypair_config
24
+ config[:require_password].default = true
25
+
26
+ register_array :key_nodes, nil do |values|
27
+ if values.nil?
28
+ warn('key_nodes_empty')
29
+ next false
30
+ end
31
+
32
+ node_plugins = CORL.loaded_plugins(:CORL, :node)
33
+ success = true
34
+
35
+ values.each do |value|
36
+ if info = CORL.plugin_class(:CORL, :node).translate_reference(value)
37
+ if ! node_plugins.keys.include?(info[:provider].to_sym) || info[:name].empty?
38
+ warn('key_nodes', { :value => value, :node_provider => info[:provider], :name => info[:name] })
39
+ success = false
40
+ end
41
+ end
42
+ end
43
+ success
44
+ end
45
+ end
46
+ end
47
+
48
+ #---
49
+
50
+ def ignore
51
+ [ :nodes, :parallel ]
52
+ end
53
+
54
+ def arguments
55
+ [ :key_nodes ]
56
+ end
57
+
58
+ #-----------------------------------------------------------------------------
59
+ # Operations
60
+
61
+ def execute
62
+ super do |local_node|
63
+ ensure_network do
64
+ keypair = keypair(true, false)
65
+
66
+ if keypair.nil?
67
+ myself.status = code.no_password_given
68
+ else
69
+ batch_success = network.batch(settings[:key_nodes], settings[:node_provider], false) do |node|
70
+ render_options = { :id => node.id, :hostname => node.hostname }
71
+
72
+ info('start', render_options)
73
+ node.attach_keys(keypair)
74
+ end
75
+ if batch_success
76
+ network.save({ :push => true, :remote => :edit })
77
+ else
78
+ myself.status = code.batch_error
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -50,7 +50,7 @@ class Download < Nucleon.plugin_class(:nucleon, :cloud_action)
50
50
  end
51
51
 
52
52
  def arguments
53
- [ :remote_path, :local_path, :upload_nodes ]
53
+ [ :remote_path, :local_path, :download_nodes ]
54
54
  end
55
55
 
56
56
  #-----------------------------------------------------------------------------
data/locales/en.yml CHANGED
@@ -16,6 +16,8 @@ en:
16
16
  Default to using a specific node provider but individual node references can override (default %{default_value})
17
17
  nodes: |-
18
18
  Optional nodes on which to execute this action
19
+ user_password: |-
20
+ Optional user password for SSH login and password required sudo operations
19
21
  errors:
20
22
  network_provider: |-
21
23
  Network plugin provider %{value} is not loaded >> Pick from the following: %{choices}
@@ -712,9 +714,18 @@ en:
712
714
  authorize:
713
715
  description: |-
714
716
  Authorize a public key for node access
717
+ info:
718
+ start: |-
719
+ Authorizing public SSH key: %{public_key}
715
720
  revoke:
716
721
  description: |-
717
722
  Revoke a public keys access to nodes
723
+ devkey:
724
+ description: |-
725
+ Generate a new development SSH keypair and authorize on servers
726
+ info:
727
+ start: |-
728
+ Generating and authorizing keypair for machine %{hostname} (%{id})
718
729
  keypair:
719
730
  description: |-
720
731
  Generate a new SSH keypair
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.16
4
+ version: 0.5.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Webb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-26 00:00:00.000000000 Z
11
+ date: 2015-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nucleon
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '0.2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: net-ping
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.7'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.7'
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: fog
35
49
  requirement: !ruby/object:Gem::Requirement
@@ -218,11 +232,13 @@ files:
218
232
  - lib/CORL/machine/AWS.rb
219
233
  - lib/CORL/machine/physical.rb
220
234
  - lib/CORL/machine/rackspace.rb
235
+ - lib/CORL/machine/raspberrypi.rb
221
236
  - lib/CORL/machine/vagrant.rb
222
237
  - lib/CORL/network/CORL.rb
223
238
  - lib/CORL/node/AWS.rb
224
239
  - lib/CORL/node/local.rb
225
240
  - lib/CORL/node/rackspace.rb
241
+ - lib/CORL/node/raspberrypi.rb
226
242
  - lib/CORL/node/vagrant.rb
227
243
  - lib/CORL/provisioner/puppetnode.rb
228
244
  - lib/core/build.rb
@@ -266,6 +282,7 @@ files:
266
282
  - lib/facter/corl_config_ready.rb
267
283
  - lib/facter/corl_network.rb
268
284
  - lib/facter/custom_facts.rb
285
+ - lib/facter/raspberry_pi.rb
269
286
  - lib/facter/vagrant_exists.rb
270
287
  - lib/hiera/corl_logger.rb
271
288
  - lib/nucleon/action/agent/manager.rb
@@ -288,6 +305,7 @@ files:
288
305
  - lib/nucleon/action/node/build.rb
289
306
  - lib/nucleon/action/node/cache.rb
290
307
  - lib/nucleon/action/node/destroy.rb
308
+ - lib/nucleon/action/node/devkey.rb
291
309
  - lib/nucleon/action/node/download.rb
292
310
  - lib/nucleon/action/node/exec.rb
293
311
  - lib/nucleon/action/node/fact.rb