corl 0.5.16 → 0.5.17

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.
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