knife-server 0.2.1 → 0.2.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.
data/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
- ## 0.2.2.dev (unreleased)
1
+ ## 0.2.3.dev (unreleased)
2
+
3
+
4
+ ## 0.2.2 (July 4, 2012)
5
+
6
+ ### New features
7
+
8
+ * Add `knife server bootstrap standalone` subcommand to setup any server
9
+ accessible via SSH. ([@fnichol][])
10
+
11
+ ### Improvements
12
+
13
+ * Add Code Climate badge to README. ([@fnichol][])
2
14
 
3
15
 
4
16
  ## 0.2.1 (July 3, 2012)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # <a name="title"></a> Knife::Server [![Build Status](https://secure.travis-ci.org/fnichol/knife-server.png?branch=master)](http://travis-ci.org/fnichol/knife-server) [![Dependency Status](https://gemnasium.com/fnichol/knife-server.png)](https://gemnasium.com/fnichol/knife-server)
1
+ # <a name="title"></a> Knife::Server [![Build Status](https://secure.travis-ci.org/fnichol/knife-server.png?branch=master)](http://travis-ci.org/fnichol/knife-server) [![Dependency Status](https://gemnasium.com/fnichol/knife-server.png)](https://gemnasium.com/fnichol/knife-server) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/fnichol/knife-server)
2
2
 
3
3
  An Opscode Chef knife plugin to manage Chef Servers. Bootstrapping new Chef
4
4
  Servers (currently on Amazon's EC2) and node data backup is supported.
@@ -13,6 +13,22 @@ $ knife server bootstrap ec2 --ssh-user ubuntu \
13
13
  --node-name chefapalooza.example.com
14
14
  ```
15
15
 
16
+ Or maybe you want to try out a Chef Server using [Vagrant][vagrant_site]?
17
+
18
+ ```bash
19
+ $ cat <<VAGRANTFILE > Vagrantfile
20
+ Vagrant::Config.run do |config|
21
+ config.vm.box = "precise64"
22
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
23
+ config.vm.network :hostonly, "192.168.33.11"
24
+ config.vm.customize ["modifyvm", :id, "--memory", 2048]
25
+ end
26
+ VAGRANTFILE
27
+ $ vagrant up
28
+ $ knife server bootstrap standalone --ssh-user vagrant \
29
+ --node-name chefapalooza.example.com --host 192.168.33.11
30
+ ```
31
+
16
32
  Taking a backup of all node, role, data bag, and environment data is also a
17
33
  snap:
18
34
 
@@ -251,6 +267,21 @@ The size of the EBS volume in GB, for EBS-backed instances.
251
267
 
252
268
  Do not delete EBS volumn on instance termination.
253
269
 
270
+ ### <a name="knife-server-bootstrap-standalone"></a> knife server bootstrap standalone
271
+ Provisions a standalone server that is reachable on the network and sets up
272
+ an Open Source Chef Server as described [above](#knife-server-bootstrap). You
273
+ are responsible for providing the server so it could be a physical machine,
274
+ Vagrant VM with host-only or bridged networking, or a cloud server instance
275
+ with a known IP address or host name.
276
+
277
+ #### Configuration
278
+
279
+ ##### --host FQDN_OR_IP (-H)
280
+
281
+ Host name or IP address of the host to bootstrap.
282
+
283
+ This option is **required**.
284
+
254
285
  ### <a name="knife-server-backup"></a> knife server backup
255
286
 
256
287
  Pulls Chef data primitives from a Chef Server as JSON for backup. Backups can
@@ -304,6 +335,13 @@ chef_server_url = "https://api.opscode.com/organizations/coolinc"
304
335
  then a backup directory of
305
336
  `/var/chef/backups/api.opscode.com_20120401T084711-0000` would be created.
306
337
 
338
+ ##### --ssh-password PASSWORD (-P)
339
+
340
+ The SSH password used (if needed) when bootstrapping the Chef Server node. If
341
+ this option is not explicitly set and key based authentication fails, you will
342
+ be prompted to enter a password in an interactive prompt. In other words,
343
+ you may omit typing your password on the command line and defer to a prompt.
344
+
307
345
  ## <a name="roadmap"></a> Roadmap
308
346
 
309
347
  * Support for other platforms (alternative bootstrap templates)
@@ -349,4 +387,5 @@ Apache License, Version 2.0 (see [LICENSE][license])
349
387
  [jtimberman]: https://github.com/jtimberman
350
388
  [knife-ec2]: https://github.com/opscode/knife-ec2
351
389
  [stevendanna]: https://github.com/stevendanna
390
+ [vagrant_site]: http://vagrantup.com/
352
391
  [wiki_knife]: http://wiki.opscode.com/display/chef/Knife#Knife-Knifeconfiguration
@@ -0,0 +1,119 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+
21
+ class Chef
22
+ class Knife
23
+ module ServerBootstrapBase
24
+
25
+ def self.included(included_class)
26
+ included_class.class_eval do
27
+
28
+ deps do
29
+ require 'chef/knife/ssh'
30
+ require 'net/ssh'
31
+ end
32
+
33
+ option :chef_node_name,
34
+ :short => "-N NAME",
35
+ :long => "--node-name NAME",
36
+ :description => "The name of your new Chef Server"
37
+
38
+ option :platform,
39
+ :short => "-P PLATFORM",
40
+ :long => "--platform PLATFORM",
41
+ :description => "The platform type that will be bootstrapped (debian)",
42
+ :default => "debian"
43
+
44
+ option :ssh_user,
45
+ :short => "-x USERNAME",
46
+ :long => "--ssh-user USERNAME",
47
+ :description => "The ssh username",
48
+ :default => "root"
49
+
50
+ option :ssh_port,
51
+ :short => "-p PORT",
52
+ :long => "--ssh-port PORT",
53
+ :description => "The ssh port",
54
+ :default => "22",
55
+ :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
56
+
57
+ option :identity_file,
58
+ :short => "-i IDENTITY_FILE",
59
+ :long => "--identity-file IDENTITY_FILE",
60
+ :description => "The SSH identity file used for authentication"
61
+
62
+ option :prerelease,
63
+ :long => "--prerelease",
64
+ :description => "Install the pre-release chef gem"
65
+
66
+ option :bootstrap_version,
67
+ :long => "--bootstrap-version VERSION",
68
+ :description => "The version of Chef to install",
69
+ :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
70
+
71
+ option :template_file,
72
+ :long => "--template-file TEMPLATE",
73
+ :description => "Full path to location of template to use",
74
+ :proc => Proc.new { |t| Chef::Config[:knife][:template_file] = t },
75
+ :default => false
76
+
77
+ option :distro,
78
+ :short => "-d DISTRO",
79
+ :long => "--distro DISTRO",
80
+ :description => "Bootstrap a distro using a template; default is 'chef-server-<platform>'"
81
+
82
+ option :webui_password,
83
+ :long => "--webui-password SECRET",
84
+ :description => "Initial password for WebUI admin account, default is 'chefchef'",
85
+ :default => "chefchef"
86
+
87
+ option :amqp_password,
88
+ :long => "--amqp-password SECRET",
89
+ :description => "Initial password for AMQP, default is 'chefchef'",
90
+ :default => "chefchef"
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def fetch_validation_key
97
+ credentials_client.install_validation_key
98
+ end
99
+
100
+ def install_client_key
101
+ credentials_client.install_client_key(
102
+ Chef::Config[:node_name], Chef::Config[:client_key])
103
+ end
104
+
105
+ def create_root_client
106
+ ui.msg(credentials_client.create_root_client)
107
+ end
108
+
109
+ def bootstrap_distro
110
+ config[:distro] || "chef-server-#{config[:platform]}"
111
+ end
112
+
113
+ def credentials_client
114
+ @credentials_client ||= ::Knife::Server::Credentials.new(
115
+ ssh_connection, Chef::Config[:validation_key])
116
+ end
117
+ end
118
+ end
119
+ end
@@ -16,85 +16,25 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'chef/knife'
19
+ require 'chef/knife/server_bootstrap_base'
20
20
 
21
21
  class Chef
22
22
  class Knife
23
23
  class ServerBootstrapEc2 < Knife
24
24
 
25
+ include Knife::ServerBootstrapBase
26
+
25
27
  deps do
26
- require 'knife/server/ec2_security_group'
27
28
  require 'knife/server/ssh'
28
29
  require 'knife/server/credentials'
30
+ require 'knife/server/ec2_security_group'
29
31
  require 'chef/knife/ec2_server_create'
30
32
  require 'fog'
31
- require 'net/ssh'
32
33
  Chef::Knife::Ec2ServerCreate.load_deps
33
34
  end
34
35
 
35
36
  banner "knife server bootstrap ec2 (options)"
36
37
 
37
- option :chef_node_name,
38
- :short => "-N NAME",
39
- :long => "--node-name NAME",
40
- :description => "The name of your new Chef Server"
41
-
42
- option :platform,
43
- :short => "-P PLATFORM",
44
- :long => "--platform PLATFORM",
45
- :description => "The platform type that will be bootstrapped (debian)",
46
- :default => "debian"
47
-
48
- option :ssh_user,
49
- :short => "-x USERNAME",
50
- :long => "--ssh-user USERNAME",
51
- :description => "The ssh username",
52
- :default => "root"
53
-
54
- option :ssh_port,
55
- :short => "-p PORT",
56
- :long => "--ssh-port PORT",
57
- :description => "The ssh port",
58
- :default => "22",
59
- :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
60
-
61
- option :identity_file,
62
- :short => "-i IDENTITY_FILE",
63
- :long => "--identity-file IDENTITY_FILE",
64
- :description => "The SSH identity file used for authentication"
65
-
66
- option :prerelease,
67
- :long => "--prerelease",
68
- :description => "Install the pre-release chef gem"
69
-
70
- option :bootstrap_version,
71
- :long => "--bootstrap-version VERSION",
72
- :description => "The version of Chef to install",
73
- :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
74
-
75
- option :template_file,
76
- :long => "--template-file TEMPLATE",
77
- :description => "Full path to location of template to use",
78
- :proc => Proc.new { |t| Chef::Config[:knife][:template_file] = t },
79
- :default => false
80
-
81
- option :distro,
82
- :short => "-d DISTRO",
83
- :long => "--distro DISTRO",
84
- :description => "Bootstrap a distro using a template; default is 'chef-server-<platform>'"
85
-
86
- option :webui_password,
87
- :long => "--webui-password SECRET",
88
- :description => "Initial password for WebUI admin account, default is 'chefchef'",
89
- :default => "chefchef"
90
-
91
- option :amqp_password,
92
- :long => "--amqp-password SECRET",
93
- :description => "Initial password for AMQP, default is 'chefchef'",
94
- :default => "chefchef"
95
-
96
- # aws/ec2 options
97
-
98
38
  option :aws_access_key_id,
99
39
  :short => "-A ID",
100
40
  :long => "--aws-access-key-id KEY",
@@ -106,7 +46,6 @@ class Chef
106
46
  :long => "--aws-secret-access-key SECRET",
107
47
  :description => "Your AWS API Secret Access Key",
108
48
  :proc => Proc.new { |key| Chef::Config[:knife][:aws_secret_access_key] = key }
109
-
110
49
  option :region,
111
50
  :long => "--region REGION",
112
51
  :description => "Your AWS region",
@@ -219,28 +158,6 @@ class Chef
219
158
  merge({"Role" => "chef_server"}).map { |k,v| "#{k}=#{v}" }
220
159
  end
221
160
 
222
- def bootstrap_distro
223
- config[:distro] || "chef-server-#{config[:platform]}"
224
- end
225
-
226
- def credentials_client
227
- @credentials_client ||= ::Knife::Server::Credentials.new(
228
- ssh_connection, Chef::Config[:validation_key])
229
- end
230
-
231
- def fetch_validation_key
232
- credentials_client.install_validation_key
233
- end
234
-
235
- def install_client_key
236
- credentials_client.install_client_key(
237
- Chef::Config[:node_name], Chef::Config[:client_key])
238
- end
239
-
240
- def create_root_client
241
- ui.msg(credentials_client.create_root_client)
242
- end
243
-
244
161
  def ssh_connection
245
162
  ::Knife::Server::SSH.new(
246
163
  :host => server_dns_name,
@@ -0,0 +1,100 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife/server_bootstrap_base'
20
+
21
+ class Chef
22
+ class Knife
23
+ class ServerBootstrapStandalone < Knife
24
+
25
+ include Knife::ServerBootstrapBase
26
+
27
+ deps do
28
+ require 'knife/server/ssh'
29
+ require 'knife/server/credentials'
30
+ require 'chef/knife/bootstrap'
31
+ Chef::Knife::Bootstrap.load_deps
32
+ end
33
+
34
+ banner "knife server bootstrap standalone (options)"
35
+
36
+ option :host,
37
+ :short => "-H FQDN_OR_IP",
38
+ :long => "--host FQDN_OR_IP",
39
+ :description => "Hostname or IP address of host to bootstrap"
40
+
41
+ option :ssh_password,
42
+ :short => "-P PASSWORD",
43
+ :long => "--ssh-password PASSWORD",
44
+ :description => "The ssh password"
45
+
46
+ def run
47
+ validate!
48
+ check_ssh_connection
49
+ standalone_bootstrap.run
50
+ fetch_validation_key
51
+ create_root_client
52
+ install_client_key
53
+ end
54
+
55
+ def standalone_bootstrap
56
+ ENV['WEBUI_PASSWORD'] = config[:webui_password]
57
+ ENV['AMQP_PASSWORD'] = config[:amqp_password]
58
+ bootstrap = Chef::Knife::Bootstrap.new
59
+ bootstrap.name_args = [ config[:host] ]
60
+ [ :chef_node_name, :ssh_user, :ssh_password, :ssh_port, :identity_file
61
+ ].each { |attr| bootstrap.config[attr] = config[attr] }
62
+ bootstrap.config[:distro] = bootstrap_distro
63
+ bootstrap.config[:use_sudo] = true unless config[:ssh_user] == "root"
64
+ bootstrap
65
+ end
66
+
67
+ private
68
+
69
+ def validate!
70
+ if config[:chef_node_name].nil?
71
+ ui.error "You did not provide a valid --node-name value."
72
+ exit 1
73
+ end
74
+ if config[:host].nil?
75
+ ui.error "You did not provide a valid --host value."
76
+ exit 1
77
+ end
78
+ end
79
+
80
+ def check_ssh_connection
81
+ ssh_connection.exec! "hostname -f"
82
+ rescue Net::SSH::AuthenticationFailed
83
+ ui.warn("Failed to authenticate #{config[:ssh_user]} - " +
84
+ "trying password auth")
85
+ config[:ssh_password] = ui.ask(
86
+ "Enter password for #{config[:ssh_user]}@#{config[:host]}: "
87
+ ) { |q| q.echo = false }
88
+ end
89
+
90
+ def ssh_connection
91
+ ::Knife::Server::SSH.new(
92
+ :host => config[:host],
93
+ :user => config[:ssh_user],
94
+ :password => config[:ssh_password],
95
+ :port => config[:ssh_port]
96
+ )
97
+ end
98
+ end
99
+ end
100
+ end
@@ -18,6 +18,6 @@
18
18
 
19
19
  module Knife
20
20
  module Server
21
- VERSION = "0.2.1"
21
+ VERSION = "0.2.2"
22
22
  end
23
23
  end
@@ -17,10 +17,10 @@
17
17
  #
18
18
 
19
19
  require 'chef/knife/server_bootstrap_ec2'
20
- require 'chef/knife/ec2_server_create'
21
- require 'fog'
22
- require 'net/ssh'
20
+ require 'chef/knife/ssh'
23
21
  require 'fakefs/spec_helpers'
22
+ require 'net/ssh'
23
+ Chef::Knife::ServerBootstrapEc2.load_deps
24
24
 
25
25
  describe Chef::Knife::ServerBootstrapEc2 do
26
26
  include FakeFS::SpecHelpers
@@ -0,0 +1,251 @@
1
+ #
2
+ # Author:: Fletcher Nichol (<fnichol@nichol.ca>)
3
+ # Copyright:: Copyright (c) 2012 Fletcher Nichol
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife/server_bootstrap_standalone'
20
+ require 'chef/knife/ssh'
21
+ require 'fakefs/spec_helpers'
22
+ require 'net/ssh'
23
+ Chef::Knife::ServerBootstrapStandalone.load_deps
24
+
25
+ describe Chef::Knife::ServerBootstrapStandalone do
26
+ include FakeFS::SpecHelpers
27
+
28
+ before do
29
+ Chef::Log.logger = Logger.new(StringIO.new)
30
+ @knife = Chef::Knife::ServerBootstrapStandalone.new
31
+ @stdout = StringIO.new
32
+ @knife.ui.stub!(:stdout).and_return(@stdout)
33
+ @stderr = StringIO.new
34
+ @knife.ui.stub!(:stderr).and_return(@stderr)
35
+ @knife.config[:chef_node_name] = "yakky"
36
+ end
37
+
38
+ describe "#standalone_bootstrap" do
39
+ before do
40
+ @knife.config[:host] = "172.0.10.21"
41
+ @knife.config[:chef_node_name] = "shave.yak"
42
+ @knife.config[:ssh_user] = "jdoe"
43
+ @knife.config[:ssh_password] = "nevereverguess"
44
+ @knife.config[:ssh_port] = "2222"
45
+ @knife.config[:identity_file] = "~/.ssh/mykey_dsa"
46
+ @knife.config[:security_groups] = %w{x y z}
47
+ @knife.config[:tags] = %w{tag1=val1 tag2=val2}
48
+ @knife.config[:distro] = "distro-praha"
49
+ @knife.config[:ebs_size] = "42"
50
+ @knife.config[:webui_password] = "daweb"
51
+ @knife.config[:amqp_password] = "queueitup"
52
+
53
+ ENV['_SPEC_WEBUI_PASSWORD'] = ENV['WEBUI_PASSWORD']
54
+ ENV['_SPEC_AMQP_PASSWORD'] = ENV['AMQP_PASSWORD']
55
+ end
56
+
57
+ after do
58
+ ENV['WEBUI_PASSWORD'] = ENV.delete('_SPEC_WEBUI_PASSWORD')
59
+ ENV['AMQP_PASSWORD'] = ENV.delete('_SPEC_AMQP_PASSWORD')
60
+ end
61
+
62
+ let(:bootstrap) { @knife.standalone_bootstrap }
63
+
64
+ it "returns a Bootstrap instance" do
65
+ bootstrap.should be_a(Chef::Knife::Bootstrap)
66
+ end
67
+
68
+ it "configs the bootstrap's chef_node_name" do
69
+ bootstrap.config[:chef_node_name].should eq("shave.yak")
70
+ end
71
+
72
+ it "configs the bootstrap's ssh_user" do
73
+ bootstrap.config[:ssh_user].should eq("jdoe")
74
+ end
75
+
76
+ it "configs the bootstrap's ssh_password" do
77
+ bootstrap.config[:ssh_password].should eq("nevereverguess")
78
+ end
79
+
80
+ it "does not config the bootstrap's ssh_password if not given" do
81
+ @knife.config.delete(:ssh_password)
82
+
83
+ bootstrap.config[:ssh_password].should be_nil
84
+ end
85
+
86
+ it "configs the bootstrap's ssh_port" do
87
+ bootstrap.config[:ssh_port].should eq("2222")
88
+ end
89
+
90
+ it "configs the bootstrap's identity_file" do
91
+ bootstrap.config[:identity_file].should eq("~/.ssh/mykey_dsa")
92
+ end
93
+
94
+ it "configs the bootstrap's distro" do
95
+ bootstrap.config[:distro].should eq("distro-praha")
96
+ end
97
+
98
+ it "configs the bootstrap's distro to chef-server-debian by default" do
99
+ @knife.config.delete(:distro)
100
+
101
+ bootstrap.config[:distro].should eq("chef-server-debian")
102
+ end
103
+
104
+ it "configs the bootstrap's distro value driven off platform value" do
105
+ @knife.config.delete(:distro)
106
+ @knife.config[:platform] = "freebsd"
107
+
108
+ bootstrap.config[:distro].should eq("chef-server-freebsd")
109
+ end
110
+
111
+ it "configs the bootstrap's ENV with the webui password" do
112
+ bootstrap
113
+ ENV['WEBUI_PASSWORD'].should eq("daweb")
114
+ end
115
+
116
+ it "configs the bootstrap's ENV with the amqp password" do
117
+ bootstrap
118
+ ENV['AMQP_PASSWORD'].should eq("queueitup")
119
+ end
120
+
121
+ it "configs the bootstrap's name_args with the host" do
122
+ bootstrap.name_args.should eq([ "172.0.10.21" ])
123
+ end
124
+
125
+ it "configs the bootstrap's use_sudo to true if ssh-user is not root" do
126
+ bootstrap.config[:use_sudo].should be_true
127
+ end
128
+
129
+ it "configs the bootstrap's use_sudo to false if ssh-user is root" do
130
+ @knife.config[:ssh_user] = "root"
131
+
132
+ bootstrap.config[:use_sudo].should_not be_true
133
+ end
134
+ end
135
+
136
+ describe "#run" do
137
+ before do
138
+ @before_config = Hash.new
139
+ [:node_name, :client_key].each do |attr|
140
+ @before_config[attr] = Chef::Config[attr]
141
+ end
142
+ Chef::Config[:node_name] = "smithers"
143
+ Chef::Config[:client_key] = "/var/tmp/myclientkey.pem"
144
+
145
+ @knife.config[:host] = "192.168.0.1"
146
+ @knife.config[:ssh_port] = "2345"
147
+ Chef::Knife::Bootstrap.stub(:new) { bootstrap }
148
+ Knife::Server::SSH.stub(:new) { ssh }
149
+ Knife::Server::Credentials.stub(:new) { credentials }
150
+ credentials.stub(:install_validation_key)
151
+ credentials.stub(:create_root_client)
152
+ end
153
+
154
+ after do
155
+ [:node_name, :client_key].each do |attr|
156
+ Chef::Config[attr] = @before_config[attr]
157
+ end
158
+ end
159
+
160
+ let(:bootstrap) do
161
+ stub(:run => true, :config => Hash.new, :name_args= => true)
162
+ end
163
+
164
+ let(:ssh) { stub(:exec! => true) }
165
+ let(:credentials) { stub.as_null_object }
166
+
167
+ it "exits if node_name option is missing" do
168
+ @knife.config.delete(:chef_node_name)
169
+
170
+ expect { @knife.run }.to raise_error SystemExit
171
+ end
172
+
173
+ it "exits if host option is missing" do
174
+ @knife.config.delete(:host)
175
+
176
+ expect { @knife.run }.to raise_error SystemExit
177
+ end
178
+
179
+ it "bootstraps a standalone server" do
180
+ bootstrap.should_receive(:run)
181
+ @knife.run
182
+ end
183
+
184
+ it "create a root client key" do
185
+ credentials.should_receive(:create_root_client)
186
+
187
+ @knife.run
188
+ end
189
+
190
+ it "installs a client key" do
191
+ credentials.should_receive(:install_client_key).
192
+ with("smithers", "/var/tmp/myclientkey.pem")
193
+
194
+ @knife.run
195
+ end
196
+
197
+ it "installs a new validation.pem key from the server" do
198
+ Knife::Server::Credentials.should_receive(:new).
199
+ with(ssh, "/etc/chef/validation.pem")
200
+ credentials.should_receive(:install_validation_key)
201
+
202
+ @knife.run
203
+ end
204
+
205
+ context "when an ssh password is missing" do
206
+ it "creates an SSH connection without a password" do
207
+ Knife::Server::SSH.should_receive(:new).with({
208
+ :host => "192.168.0.1", :port => "2345",
209
+ :user => "root", :password => nil
210
+ })
211
+
212
+ @knife.run
213
+ end
214
+ end
215
+
216
+ context "when an ssh password is provided" do
217
+ before do
218
+ @knife.config[:ssh_password] = "snoopy"
219
+ end
220
+
221
+ it "creates an SSH connection with a password" do
222
+ Knife::Server::SSH.should_receive(:new).with({
223
+ :host => "192.168.0.1", :port => "2345",
224
+ :user => "root", :password => "snoopy"
225
+ })
226
+
227
+ @knife.run
228
+ end
229
+ end
230
+
231
+ context "when key-based ssh authentication fails" do
232
+ before do
233
+ ssh.stub(:exec!).
234
+ with("hostname -f") { raise ::Net::SSH::AuthenticationFailed }
235
+ @knife.ui.stub(:ask) { "hellacool" }
236
+ end
237
+
238
+ it "sends a authentication failure message" do
239
+ @knife.ui.should_receive(:warn).with(/Failed to authenticate/i)
240
+
241
+ @knife.run
242
+ end
243
+
244
+ it "sets the :ssh_password config from user input" do
245
+ @knife.run
246
+
247
+ @knife.config[:ssh_password].should eq("hellacool")
248
+ end
249
+ end
250
+ end
251
+ end
@@ -43,7 +43,8 @@ describe Knife::Server::SSH do
43
43
 
44
44
  it "sets default user to root" do
45
45
  ssh_options.delete(:user)
46
- Net::SSH.should_receive(:start).with(anything, "root", anything)
46
+ Net::SSH.should_receive(:start).
47
+ with(anything, "root", anything)
47
48
 
48
49
  Knife::Server::SSH.new(ssh_options).exec!("wat")
49
50
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.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: 2012-07-04 00:00:00.000000000 Z
12
+ date: 2012-07-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
16
- requirement: &2156639540 !ruby/object:Gem::Requirement
16
+ requirement: &2164645740 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.3'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2156639540
24
+ version_requirements: *2164645740
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: net-ssh
27
- requirement: &2156638860 !ruby/object:Gem::Requirement
27
+ requirement: &2164645080 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2156638860
35
+ version_requirements: *2164645080
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: chef
38
- requirement: &2156637980 !ruby/object:Gem::Requirement
38
+ requirement: &2164644240 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.10.10
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2156637980
46
+ version_requirements: *2164644240
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: knife-ec2
49
- requirement: &2156637180 !ruby/object:Gem::Requirement
49
+ requirement: &2164643440 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.5.12
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2156637180
57
+ version_requirements: *2164643440
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &2156636480 !ruby/object:Gem::Requirement
60
+ requirement: &2164642700 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '2.10'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2156636480
68
+ version_requirements: *2164642700
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: fakefs
71
- requirement: &2156635860 !ruby/object:Gem::Requirement
71
+ requirement: &2164642100 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.4.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2156635860
79
+ version_requirements: *2164642100
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: timecop
82
- requirement: &2156635340 !ruby/object:Gem::Requirement
82
+ requirement: &2164641600 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: 0.3.5
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2156635340
90
+ version_requirements: *2164641600
91
91
  description: Chef Knife plugin to bootstrap Chef Servers
92
92
  email:
93
93
  - fnichol@nichol.ca
@@ -106,7 +106,9 @@ files:
106
106
  - knife-server.gemspec
107
107
  - lib/chef/knife/bootstrap/chef-server-debian.erb
108
108
  - lib/chef/knife/server_backup.rb
109
+ - lib/chef/knife/server_bootstrap_base.rb
109
110
  - lib/chef/knife/server_bootstrap_ec2.rb
111
+ - lib/chef/knife/server_bootstrap_standalone.rb
110
112
  - lib/knife-server.rb
111
113
  - lib/knife/server/credentials.rb
112
114
  - lib/knife/server/ec2_security_group.rb
@@ -114,6 +116,7 @@ files:
114
116
  - lib/knife/server/version.rb
115
117
  - spec/chef/knife/server_backup_spec.rb
116
118
  - spec/chef/knife/server_bootstrap_ec2_spec.rb
119
+ - spec/chef/knife/server_bootstrap_standalone_spec.rb
117
120
  - spec/knife/server/credientials_spec.rb
118
121
  - spec/knife/server/ec2_security_group_spec.rb
119
122
  - spec/knife/server/ssh_spec.rb
@@ -144,6 +147,7 @@ summary: Chef Knife plugin to bootstrap Chef Servers
144
147
  test_files:
145
148
  - spec/chef/knife/server_backup_spec.rb
146
149
  - spec/chef/knife/server_bootstrap_ec2_spec.rb
150
+ - spec/chef/knife/server_bootstrap_standalone_spec.rb
147
151
  - spec/knife/server/credientials_spec.rb
148
152
  - spec/knife/server/ec2_security_group_spec.rb
149
153
  - spec/knife/server/ssh_spec.rb