knife-cloud 1.0.0.rc.0
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 +15 -0
- data/.gitignore +33 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +11 -0
- data/CONTRIBUTING.md +5 -0
- data/Gemfile +9 -0
- data/LICENSE +201 -0
- data/README.md +420 -0
- data/Rakefile +35 -0
- data/knife-cloud.gemspec +27 -0
- data/lib/chef/knife/cloud/chefbootstrap/bootstrap_distribution.rb +31 -0
- data/lib/chef/knife/cloud/chefbootstrap/bootstrap_options.rb +191 -0
- data/lib/chef/knife/cloud/chefbootstrap/bootstrap_protocol.rb +69 -0
- data/lib/chef/knife/cloud/chefbootstrap/bootstrapper.rb +78 -0
- data/lib/chef/knife/cloud/chefbootstrap/ssh_bootstrap_protocol.rb +179 -0
- data/lib/chef/knife/cloud/chefbootstrap/unix_distribution.rb +31 -0
- data/lib/chef/knife/cloud/chefbootstrap/windows_distribution.rb +32 -0
- data/lib/chef/knife/cloud/chefbootstrap/winrm_bootstrap_protocol.rb +85 -0
- data/lib/chef/knife/cloud/command.rb +101 -0
- data/lib/chef/knife/cloud/exceptions.rb +38 -0
- data/lib/chef/knife/cloud/fog/options.rb +29 -0
- data/lib/chef/knife/cloud/fog/service.rb +200 -0
- data/lib/chef/knife/cloud/helpers.rb +39 -0
- data/lib/chef/knife/cloud/list_resource_command.rb +97 -0
- data/lib/chef/knife/cloud/list_resource_options.rb +21 -0
- data/lib/chef/knife/cloud/server/create_command.rb +165 -0
- data/lib/chef/knife/cloud/server/create_options.rb +80 -0
- data/lib/chef/knife/cloud/server/delete_command.rb +68 -0
- data/lib/chef/knife/cloud/server/delete_options.rb +42 -0
- data/lib/chef/knife/cloud/server/list_command.rb +84 -0
- data/lib/chef/knife/cloud/server/list_options.rb +43 -0
- data/lib/chef/knife/cloud/server/options.rb +39 -0
- data/lib/chef/knife/cloud/server/show_command.rb +55 -0
- data/lib/chef/knife/cloud/server/show_options.rb +36 -0
- data/lib/chef/knife/cloud/service.rb +91 -0
- data/lib/knife-cloud/version.rb +6 -0
- data/lib/test/fixtures/knife.rb +9 -0
- data/lib/test/fixtures/validation.pem +27 -0
- data/lib/test/knife-utils/helper.rb +39 -0
- data/lib/test/knife-utils/knife_test_utils.rb +40 -0
- data/lib/test/knife-utils/matchers.rb +29 -0
- data/lib/test/knife-utils/test_bed.rb +56 -0
- data/lib/test/templates/chef-full-chef-zero.erb +67 -0
- data/lib/test/templates/windows-chef-client-msi.erb +231 -0
- data/lib/test/templates/windows-shell.erb +77 -0
- data/spec/resource_spec_helper.rb +49 -0
- data/spec/server_command_common_spec_helper.rb +48 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/shared_examples_for_command.rb +35 -0
- data/spec/support/shared_examples_for_servercreatecommand.rb +144 -0
- data/spec/support/shared_examples_for_serverdeletecommand.rb +77 -0
- data/spec/support/shared_examples_for_service.rb +85 -0
- data/spec/unit/bootstrap_protocol_spec.rb +70 -0
- data/spec/unit/bootstrapper_spec.rb +171 -0
- data/spec/unit/cloud_command_spec.rb +35 -0
- data/spec/unit/command_spec.rb +49 -0
- data/spec/unit/fog_service_spec.rb +138 -0
- data/spec/unit/list_resource_command_spec.rb +136 -0
- data/spec/unit/server_create_command_spec.rb +198 -0
- data/spec/unit/server_delete_command_spec.rb +25 -0
- data/spec/unit/server_list_command_spec.rb +119 -0
- data/spec/unit/server_show_command_spec.rb +64 -0
- data/spec/unit/service_spec.rb +46 -0
- data/spec/unit/ssh_bootstrap_protocol_spec.rb +116 -0
- data/spec/unit/unix_distribution_spec.rb +37 -0
- data/spec/unit/windows_distribution_spec.rb +37 -0
- data/spec/unit/winrm_bootstrap_protocol_spec.rb +106 -0
- metadata +248 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
|
3
|
+
# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
|
4
|
+
# Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
20
|
+
require 'chef/knife/cloud/fog/service'
|
21
|
+
require 'support/shared_examples_for_service'
|
22
|
+
|
23
|
+
describe Chef::Knife::Cloud::FogService do
|
24
|
+
|
25
|
+
it_behaves_like Chef::Knife::Cloud::Service, Chef::Knife::Cloud::FogService.new
|
26
|
+
|
27
|
+
let (:instance) { Chef::Knife::Cloud::FogService.new({:auth_params => {:provider => 'Any Cloud Provider'}}) }
|
28
|
+
|
29
|
+
context "connection" do
|
30
|
+
before do
|
31
|
+
allow(instance).to receive(:exit)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "creates a connection to fog service with the provided auth params." do
|
35
|
+
expect(instance).to receive(:add_api_endpoint)
|
36
|
+
expect(Fog::Compute).to receive(:new).with({:provider => 'Any Cloud Provider'})
|
37
|
+
instance.connection
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "network" do
|
42
|
+
it "creates a connection to fog network with the provided auth params." do
|
43
|
+
expect(Fog::Network).to receive(:new).with({:provider => 'Any Cloud Provider'})
|
44
|
+
instance.network
|
45
|
+
end
|
46
|
+
|
47
|
+
context "connection to fog" do
|
48
|
+
before do
|
49
|
+
allow(instance).to receive(:exit)
|
50
|
+
allow(instance).to receive(:ui).and_return(Object.new)
|
51
|
+
expect(instance.ui).to receive(:fatal)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "handles Unauthorized exception." do
|
55
|
+
expect(Fog::Network).to receive(:new).with({:provider => 'Any Cloud Provider'}).and_raise Excon::Errors::Unauthorized.new("Unauthorized")
|
56
|
+
expect {instance.network}.to raise_error(Chef::Knife::Cloud::CloudExceptions::ServiceConnectionError)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "handles SocketError or any other connection exception." do
|
60
|
+
socket_error = Excon::Errors::SocketError.new(Exception.new "Mock Error")
|
61
|
+
expect(Fog::Network).to receive(:new).with({:provider => 'Any Cloud Provider'}).and_raise socket_error
|
62
|
+
expect {instance.network}.to raise_error(Chef::Knife::Cloud::CloudExceptions::ServiceConnectionError)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "handles NetworkNotFoundError exception." do
|
66
|
+
expect(Fog::Network).to receive(:new).with({:provider => 'Any Cloud Provider'}).and_raise Fog::Errors::NotFound.new("NotFound")
|
67
|
+
expect {instance.network}.to raise_error(Chef::Knife::Cloud::CloudExceptions::NetworkNotFoundError)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "add_custom_attributes" do
|
73
|
+
before(:each) do
|
74
|
+
Chef::Config[:knife][:custom_attributes] = [{"state"=>"Inactive"}]
|
75
|
+
@server_def = {:name=>"vm-1", :image_ref=>"123",:flavor_ref=>"2", :key_name=>"key"}
|
76
|
+
instance.add_custom_attributes(@server_def)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "adds the custom attributes provided to server_def" do
|
80
|
+
expect(@server_def.include?(:state)).to be true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "sets the provided attributes with supplied values" do
|
84
|
+
expect(@server_def[:state] == "Inactive").to be true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
["servers", "images", "networks"].each do |resource_type|
|
89
|
+
resource = case resource_type
|
90
|
+
when "networks"
|
91
|
+
:network
|
92
|
+
else
|
93
|
+
:connection
|
94
|
+
end
|
95
|
+
context "list #{resource_type}" do
|
96
|
+
|
97
|
+
it "lists #{resource_type} of the current cloud service provider account." do
|
98
|
+
allow(instance).to receive_message_chain(resource.to_sym, "#{resource_type}".to_sym, :all)
|
99
|
+
instance.method("list_#{resource_type}").call
|
100
|
+
end
|
101
|
+
|
102
|
+
it "handles Excon::Errors::BadRequest exception." do
|
103
|
+
allow(instance).to receive(:ui).and_return(Object.new)
|
104
|
+
allow(instance.ui).to receive(:fatal)
|
105
|
+
allow(instance).to receive_message_chain(resource.to_sym, "#{resource_type}".to_sym, :all).and_raise Excon::Errors::BadRequest.new("Invalid Resource")
|
106
|
+
expect {instance.method("list_#{resource_type}").call}.to raise_error(Chef::Knife::Cloud::CloudExceptions::CloudAPIException)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "#delete_server" do
|
112
|
+
before(:each) do
|
113
|
+
@server = TestResource.new({:id => "test-server1"})
|
114
|
+
@server.define_singleton_method(:destroy){}
|
115
|
+
end
|
116
|
+
|
117
|
+
it "delete instance successfully" do
|
118
|
+
server_name = "test-server1"
|
119
|
+
instance.ui = double
|
120
|
+
expect(instance).to receive(:get_server).and_return(@server)
|
121
|
+
expect(instance).to receive(:get_server_name).and_return(server_name)
|
122
|
+
expect(instance).to receive(:msg_pair).with("Instance Name", server_name)
|
123
|
+
expect(instance).to receive(:msg_pair).with("Instance ID", @server.id)
|
124
|
+
expect(instance.ui).to receive(:confirm)
|
125
|
+
expect(@server).to receive(:destroy)
|
126
|
+
instance.delete_server(server_name)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "raise_error on non existence server delete " do
|
130
|
+
server_name = "test-server1"
|
131
|
+
instance.ui = double
|
132
|
+
error_message = "Could not locate server '#{server_name}'."
|
133
|
+
expect(instance).to receive(:get_server).and_return(nil)
|
134
|
+
expect(instance.ui).to receive(:error).with(error_message)
|
135
|
+
expect { instance.delete_server(server_name) }.to raise_error(Chef::Knife::Cloud::CloudExceptions::ServerDeleteError, error_message)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
|
3
|
+
# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
|
4
|
+
# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
|
5
|
+
# Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
|
6
|
+
# License:: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
|
20
|
+
require 'spec_helper'
|
21
|
+
require 'chef/knife/cloud/list_resource_command'
|
22
|
+
require 'support/shared_examples_for_command'
|
23
|
+
require 'excon/errors'
|
24
|
+
|
25
|
+
describe Chef::Knife::Cloud::ResourceListCommand do
|
26
|
+
it_behaves_like Chef::Knife::Cloud::Command, Chef::Knife::Cloud::ResourceListCommand.new
|
27
|
+
|
28
|
+
let (:instance) {Chef::Knife::Cloud::ResourceListCommand.new}
|
29
|
+
let (:resources) {[ TestResource.new({:id => "resource-1", :os => "ubuntu"}),
|
30
|
+
TestResource.new({:id => "resource-2", :os => "windows"})]}
|
31
|
+
|
32
|
+
context "Basic tests:" do
|
33
|
+
it "raises exception to override #query_resource method" do
|
34
|
+
allow(instance).to receive(:create_service_instance).and_return(Chef::Knife::Cloud::Service.new)
|
35
|
+
expect {instance.run}.to raise_error(Chef::Exceptions::Override, "You must override query_resource in #{instance.to_s} to return resources.")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "responds to #list method" do
|
39
|
+
allow(instance).to receive(:query_resource)
|
40
|
+
expect(instance).to respond_to(:list)
|
41
|
+
end
|
42
|
+
|
43
|
+
context "responds to #list method" do
|
44
|
+
let(:test_resource) { "test" }
|
45
|
+
before(:each) do
|
46
|
+
expect(instance.ui).to receive(:fatal)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "handle generic exception" do
|
50
|
+
allow(test_resource).to receive(:sort_by).and_raise StandardError
|
51
|
+
expect {instance.list(test_resource)}.to raise_error(StandardError)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "handle Excon::Errors::BadRequest exception." do
|
55
|
+
allow(test_resource).to receive(:sort_by).and_raise Excon::Errors::BadRequest.new("excon error message")
|
56
|
+
expect {instance.list(test_resource)}.to raise_error(Excon::Errors::BadRequest)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "Without columns_with_info parameter in #list:" do
|
62
|
+
before do
|
63
|
+
allow(instance).to receive(:query_resource).and_return(resources)
|
64
|
+
allow(instance).to receive(:create_service_instance).and_return(Chef::Knife::Cloud::Service.new)
|
65
|
+
allow(instance).to receive(:puts)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "lists resources in json format when columns_with_info parameter is empty" do
|
69
|
+
expect(instance).to receive(:puts).with(resources[0].to_json)
|
70
|
+
expect(instance).to receive(:puts).with(resources[1].to_json)
|
71
|
+
expect(instance).to receive(:puts).with("\n").twice
|
72
|
+
instance.run
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "With columns_with_info parameter in #list:" do
|
77
|
+
context "#value_callback not specified in columns_with_info" do
|
78
|
+
before do
|
79
|
+
class Derived < Chef::Knife::Cloud::ResourceListCommand
|
80
|
+
attr_accessor :resource_filters
|
81
|
+
def before_exec_command
|
82
|
+
@columns_with_info = [ { :key => 'id', :label => 'Instance ID' },
|
83
|
+
{ :key => 'os', :label => 'Operating system' } ]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
@derived_instance = Derived.new
|
88
|
+
allow(@derived_instance).to receive(:query_resource).and_return(resources)
|
89
|
+
allow(@derived_instance).to receive(:puts)
|
90
|
+
allow(@derived_instance).to receive(:create_service_instance).and_return(Chef::Knife::Cloud::Service.new)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "lists all resources" do
|
94
|
+
expect(@derived_instance.ui).to receive(:list).with(["Instance ID", "Operating system", "resource-1", "ubuntu", "resource-2", "windows"], :uneven_columns_across, 2)
|
95
|
+
@derived_instance.run
|
96
|
+
end
|
97
|
+
|
98
|
+
it "excludes resource when filter is specified" do
|
99
|
+
@derived_instance.resource_filters = [{:attribute => 'id', :regex => /^resource-1$/}]
|
100
|
+
expect(@derived_instance.ui).to receive(:list).with(["Instance ID", "Operating system", "resource-2", "windows"], :uneven_columns_across, 2)
|
101
|
+
@derived_instance.run
|
102
|
+
end
|
103
|
+
|
104
|
+
it "lists all resources when disable filter" do
|
105
|
+
@derived_instance.config[:disable_filter] = true
|
106
|
+
@derived_instance.resource_filters = [{:attribute => 'id', :regex => /^resource-1$/}]
|
107
|
+
expect(@derived_instance.ui).to receive(:list).with(["Instance ID", "Operating system", "resource-1", "ubuntu", "resource-2", "windows"], :uneven_columns_across, 2)
|
108
|
+
@derived_instance.run
|
109
|
+
end
|
110
|
+
end
|
111
|
+
context "#value_callback specified in columns_with_info" do
|
112
|
+
before do
|
113
|
+
class Derived < Chef::Knife::Cloud::ResourceListCommand
|
114
|
+
attr_accessor :resource_filters
|
115
|
+
def before_exec_command
|
116
|
+
@columns_with_info = [ { :key => 'id', :label => 'Instance ID' },
|
117
|
+
{ :key => 'os', :label => 'Operating system', :value_callback => method(:format_os) } ]
|
118
|
+
end
|
119
|
+
def format_os(os)
|
120
|
+
(os == 'ubuntu') ? "ubuntu - operating system with Linux kernel" : os
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
@derived_instance = Derived.new
|
125
|
+
allow(@derived_instance).to receive(:query_resource).and_return(resources)
|
126
|
+
allow(@derived_instance).to receive(:puts)
|
127
|
+
allow(@derived_instance).to receive(:create_service_instance).and_return(Chef::Knife::Cloud::Service.new)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "lists formatted list of resources" do
|
131
|
+
expect(@derived_instance.ui).to receive(:list).with(["Instance ID", "Operating system", "resource-1", "ubuntu - operating system with Linux kernel", "resource-2", "windows"], :uneven_columns_across, 2)
|
132
|
+
@derived_instance.run
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Mukta Aphale (<mukta.aphale@clogeny.com>)
|
3
|
+
# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
|
4
|
+
# Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'support/shared_examples_for_command'
|
20
|
+
require 'support/shared_examples_for_servercreatecommand'
|
21
|
+
require 'net/ssh'
|
22
|
+
require 'chef/knife/cloud/server/create_options'
|
23
|
+
|
24
|
+
describe Chef::Knife::Cloud::ServerCreateCommand do
|
25
|
+
it_behaves_like Chef::Knife::Cloud::Command, Chef::Knife::Cloud::ServerCreateCommand.new
|
26
|
+
it_behaves_like Chef::Knife::Cloud::ServerCreateCommand, Chef::Knife::Cloud::ServerCreateCommand.new
|
27
|
+
|
28
|
+
describe "#validate_params!" do
|
29
|
+
before(:each) do
|
30
|
+
@instance = Chef::Knife::Cloud::ServerCreateCommand.new
|
31
|
+
allow(@instance.ui).to receive(:error)
|
32
|
+
Chef::Config[:knife][:bootstrap_protocol] = "ssh"
|
33
|
+
Chef::Config[:knife][:identity_file] = "identity_file"
|
34
|
+
Chef::Config[:knife][:ssh_password] = "ssh_password"
|
35
|
+
Chef::Config[:knife][:chef_node_name] = "chef_node_name"
|
36
|
+
Chef::Config[:knife][:winrm_password] = "winrm_password"
|
37
|
+
end
|
38
|
+
after(:all) do
|
39
|
+
Chef::Config[:knife].delete(:bootstrap_protocol)
|
40
|
+
Chef::Config[:knife].delete(:identity_file)
|
41
|
+
Chef::Config[:knife].delete(:chef_node_name)
|
42
|
+
Chef::Config[:knife].delete(:ssh_password)
|
43
|
+
Chef::Config[:knife].delete(:winrm_password)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "run sucessfully on all params exist" do
|
47
|
+
expect { @instance.validate_params! }.to_not raise_error
|
48
|
+
expect(@instance.config[:chef_node_name]).to eq(Chef::Config[:knife][:chef_node_name])
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when bootstrap_protocol ssh" do
|
52
|
+
it "raise error on ssh_password and identity_file are missing" do
|
53
|
+
Chef::Config[:knife].delete(:identity_file)
|
54
|
+
Chef::Config[:knife].delete(:ssh_password)
|
55
|
+
expect { @instance.validate_params! }.to raise_error(Chef::Knife::Cloud::CloudExceptions::ValidationError, " You must provide either Identity file or SSH Password..")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when bootstrap_protocol winrm" do
|
60
|
+
it "raise error on winrm_password is missing" do
|
61
|
+
Chef::Config[:knife][:bootstrap_protocol] = "winrm"
|
62
|
+
Chef::Config[:knife].delete(:winrm_password)
|
63
|
+
expect { @instance.validate_params! }.to raise_error(Chef::Knife::Cloud::CloudExceptions::ValidationError, " You must provide Winrm Password..")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#after_exec_command" do
|
69
|
+
it "calls bootstrap" do
|
70
|
+
instance = Chef::Knife::Cloud::ServerCreateCommand.new
|
71
|
+
expect(instance).to receive(:bootstrap)
|
72
|
+
instance.after_exec_command
|
73
|
+
end
|
74
|
+
|
75
|
+
it "delete server on bootstrap failure" do
|
76
|
+
instance = Chef::Knife::Cloud::ServerCreateCommand.new
|
77
|
+
instance.service = Chef::Knife::Cloud::Service.new
|
78
|
+
allow(instance).to receive(:raise)
|
79
|
+
allow(instance.ui).to receive(:fatal)
|
80
|
+
instance.config[:delete_server_on_failure] = true
|
81
|
+
allow(instance).to receive(:bootstrap).and_raise(Chef::Knife::Cloud::CloudExceptions::BootstrapError)
|
82
|
+
expect(instance.service).to receive(:delete_server_dependencies)
|
83
|
+
expect(instance.service).to receive(:delete_server_on_failure)
|
84
|
+
instance.after_exec_command
|
85
|
+
end
|
86
|
+
|
87
|
+
# Currently the RangeError is occured when image_os_type is set to linux and bootstrap-protocol is set to ssh before windows server bootstrap.
|
88
|
+
it "raise error message when bootstrap fails due to image_os_type not exist" do
|
89
|
+
instance = Chef::Knife::Cloud::ServerCreateCommand.new
|
90
|
+
instance.service = Chef::Knife::Cloud::Service.new
|
91
|
+
allow(instance.ui).to receive(:fatal)
|
92
|
+
instance.config[:delete_server_on_failure] = true
|
93
|
+
allow(instance).to receive(:bootstrap).and_raise(RangeError)
|
94
|
+
expect(instance.service).to receive(:delete_server_dependencies)
|
95
|
+
expect(instance.service).to receive(:delete_server_on_failure)
|
96
|
+
expect { instance.after_exec_command }.to raise_error(RangeError, "Check if --bootstrap-protocol and --image-os-type is correct. RangeError")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#set_default_config" do
|
101
|
+
it "set valid image os type" do
|
102
|
+
instance = Chef::Knife::Cloud::ServerCreateCommand.new
|
103
|
+
instance.config[:bootstrap_protocol] = 'winrm'
|
104
|
+
instance.set_default_config
|
105
|
+
expect(instance.config[:image_os_type]).to eq('windows')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class ServerCreate < Chef::Knife::Cloud::ServerCreateCommand
|
110
|
+
include Chef::Knife::Cloud::ServerCreateOptions
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#bootstrap options" do
|
114
|
+
|
115
|
+
it "set chef config knife options" do
|
116
|
+
instance = ServerCreate.new
|
117
|
+
bootstrap_url = "bootstrap_url"
|
118
|
+
bootstrap_install_command = "bootstrap_install_command"
|
119
|
+
bootstrap_wget_options = "bootstrap_wget_options"
|
120
|
+
bootstrap_curl_options = "bootstrap_curl_options"
|
121
|
+
bootstrap_no_proxy = "bootstrap_no_proxy"
|
122
|
+
|
123
|
+
instance.options[:bootstrap_url][:proc].call bootstrap_url
|
124
|
+
expect(Chef::Config[:knife][:bootstrap_url]).to eq(bootstrap_url)
|
125
|
+
|
126
|
+
instance.options[:bootstrap_install_command][:proc].call bootstrap_install_command
|
127
|
+
expect(Chef::Config[:knife][:bootstrap_install_command]).to eq(bootstrap_install_command)
|
128
|
+
|
129
|
+
instance.options[:bootstrap_wget_options][:proc].call bootstrap_wget_options
|
130
|
+
expect(Chef::Config[:knife][:bootstrap_wget_options]).to eq(bootstrap_wget_options)
|
131
|
+
|
132
|
+
instance.options[:bootstrap_curl_options][:proc].call bootstrap_curl_options
|
133
|
+
expect(Chef::Config[:knife][:bootstrap_curl_options]).to eq(bootstrap_curl_options)
|
134
|
+
|
135
|
+
instance.options[:bootstrap_no_proxy][:proc].call bootstrap_no_proxy
|
136
|
+
expect(Chef::Config[:knife][:bootstrap_no_proxy]).to eq(bootstrap_no_proxy)
|
137
|
+
|
138
|
+
expect(instance.options[:auth_timeout][:default]).to eq(25)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#before_bootstrap" do
|
143
|
+
|
144
|
+
before(:all) { @instance = ServerCreate.new }
|
145
|
+
|
146
|
+
context "bootstrap_protocol shh" do
|
147
|
+
before {@instance.config[:bootstrap_protocol] = "ssh"}
|
148
|
+
|
149
|
+
it "set ssh_user value by using -x option for ssh bootstrap protocol or linux image" do
|
150
|
+
# Currently -x option set config[:winrm_user]
|
151
|
+
# default value of config[:ssh_user] is root
|
152
|
+
@instance.config[:winrm_user] = "ubuntu"
|
153
|
+
@instance.config[:ssh_user] = "root"
|
154
|
+
|
155
|
+
@instance.before_bootstrap
|
156
|
+
expect(@instance.config[:ssh_user]).to eq("ubuntu")
|
157
|
+
end
|
158
|
+
|
159
|
+
it "set ssh_password value by using -P option for ssh bootstrap protocol or linux image" do
|
160
|
+
# Currently -P option set config[:winrm_password]
|
161
|
+
# default value of config[:ssh_password] is nil
|
162
|
+
@instance.config[:winrm_password] = "winrm_password"
|
163
|
+
@instance.config[:ssh_password] = nil
|
164
|
+
|
165
|
+
@instance.before_bootstrap
|
166
|
+
expect(@instance.config[:ssh_password]).to eq("winrm_password")
|
167
|
+
end
|
168
|
+
|
169
|
+
it "set ssh_port value by using -p option for ssh bootstrap protocol or linux image" do
|
170
|
+
# Currently -p option set config[:winrm_port]
|
171
|
+
# default value of config[:ssh_port] is 22
|
172
|
+
@instance.config[:winrm_port] = "1234"
|
173
|
+
@instance.config[:ssh_port] = "22"
|
174
|
+
|
175
|
+
@instance.before_bootstrap
|
176
|
+
expect(@instance.config[:ssh_port]).to eq("1234")
|
177
|
+
end
|
178
|
+
|
179
|
+
it "set identity_file value by using -i option for ssh bootstrap protocol or linux image" do
|
180
|
+
# Currently -i option set config[:kerberos_keytab_file]
|
181
|
+
# default value of config[:identity_file] is nil
|
182
|
+
@instance.config[:kerberos_keytab_file] = "kerberos_keytab_file"
|
183
|
+
@instance.config[:identity_file] = nil
|
184
|
+
|
185
|
+
@instance.before_bootstrap
|
186
|
+
expect(@instance.config[:identity_file]).to eq("kerberos_keytab_file")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "bootstrap_protocol winrm" do
|
191
|
+
it "skip ssh_override_winrm" do
|
192
|
+
@instance.config[:bootstrap_protocol] = "winrm"
|
193
|
+
expect(@instance).to_not receive(:ssh_override_winrm)
|
194
|
+
@instance.before_bootstrap
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Chef Software, Inc.
|
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
|
+
require 'spec_helper'
|
19
|
+
require 'support/shared_examples_for_command'
|
20
|
+
require 'support/shared_examples_for_serverdeletecommand'
|
21
|
+
|
22
|
+
describe Chef::Knife::Cloud::ServerDeleteCommand do
|
23
|
+
it_behaves_like Chef::Knife::Cloud::Command, Chef::Knife::Cloud::ServerDeleteCommand.new
|
24
|
+
it_behaves_like Chef::Knife::Cloud::ServerDeleteCommand, Chef::Knife::Cloud::ServerDeleteCommand.new
|
25
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
|
3
|
+
# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
|
4
|
+
# Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
|
19
|
+
require 'spec_helper'
|
20
|
+
require 'support/shared_examples_for_command'
|
21
|
+
require 'chef/knife/cloud/server/list_command'
|
22
|
+
require 'chef/node'
|
23
|
+
|
24
|
+
describe Chef::Knife::Cloud::ServerListCommand do
|
25
|
+
it_behaves_like Chef::Knife::Cloud::Command, Chef::Knife::Cloud::ServerListCommand.new
|
26
|
+
|
27
|
+
describe "#before_exec_command" do
|
28
|
+
it "set chef data columns info on chef data options" do
|
29
|
+
instance = Chef::Knife::Cloud::ServerListCommand.new
|
30
|
+
instance.config[:chef_data] = true
|
31
|
+
expect(Chef::Node).to receive(:list).with(true)
|
32
|
+
expect(instance.before_exec_command).to include({:label => "Chef Node Name", :key => "name"})
|
33
|
+
end
|
34
|
+
|
35
|
+
it "set chef data columns info on chef-data and chef-node-attribute options" do
|
36
|
+
chef_node_attribute = "platform_family"
|
37
|
+
instance = Chef::Knife::Cloud::ServerListCommand.new
|
38
|
+
instance.config[:chef_data] = true
|
39
|
+
instance.config[:chef_node_attribute] = chef_node_attribute
|
40
|
+
expect(Chef::Node).to receive(:list).with(true)
|
41
|
+
expect(instance.before_exec_command).to include({:label => chef_node_attribute, :key => chef_node_attribute})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "not set chef data columns info if chef-data option is not set" do
|
45
|
+
instance = Chef::Knife::Cloud::ServerListCommand.new
|
46
|
+
expect(Chef::Node).to_not receive(:list).with(true)
|
47
|
+
expect(instance.before_exec_command).to be(nil)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "not set chef data columns info on chef-node-attribute option set but chef-data option is not set" do
|
51
|
+
instance = Chef::Knife::Cloud::ServerListCommand.new
|
52
|
+
instance.config[:chef_node_attribute] = "platform_family"
|
53
|
+
expect(Chef::Node).to_not receive(:list).with(true)
|
54
|
+
expect(instance.before_exec_command).to be(nil)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#get_resource_col_val" do
|
59
|
+
let (:resources) {[ TestResource.new({:id => "server-1", :name => "server-1", :os => "ubuntu"})]}
|
60
|
+
before do
|
61
|
+
class DerivedServerList < Chef::Knife::Cloud::ServerListCommand
|
62
|
+
attr_accessor :node
|
63
|
+
def before_exec_command
|
64
|
+
@columns_with_info = [ { :key => 'id', :label => 'Instance ID' }, {:label => 'Environment', :key => 'chef_environment'}, {:label => 'platform_family', :key => 'platform_family'} ]
|
65
|
+
@chef_data_col_info = [ {:label => 'Environment', :key => 'chef_environment'}, {:label => 'platform_family', :key => 'platform_family'} ]
|
66
|
+
@node = TestResource.new({:id => "server-1", :name => "server-1",
|
67
|
+
:chef_environment => "_default", :platform_family => "debian"})
|
68
|
+
@node.define_singleton_method(:attribute?) do |attribute|
|
69
|
+
end
|
70
|
+
@node_list = {"server-1" => @node}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@derived_instance = DerivedServerList.new
|
74
|
+
@derived_instance.config[:chef_data] = true
|
75
|
+
@derived_instance.config[:chef_node_attribute] = "platform_family"
|
76
|
+
@derived_instance.before_exec_command
|
77
|
+
@derived_instance.service = double Chef::Knife::Cloud::Service.new
|
78
|
+
allow(@derived_instance.service).to receive(:get_server_name).with(resources.first).and_return("server-1")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "return columns_with_info values" do
|
82
|
+
expect(@derived_instance.node).to receive(:attribute?).with("platform_family").and_return(true)
|
83
|
+
expect(@derived_instance.get_resource_col_val(resources.first)).to eq(["server-1", "_default", "debian"])
|
84
|
+
end
|
85
|
+
|
86
|
+
it "raise error on invalide chef_node_attribute" do
|
87
|
+
allow(@derived_instance.ui).to receive(:error)
|
88
|
+
expect(@derived_instance.node).to receive(:attribute?).with("platform_family").and_return(false)
|
89
|
+
expect { @derived_instance.get_resource_col_val(resources.first) }.to raise_error(Chef::Knife::Cloud::CloudExceptions::CloudAPIException, "The Node does not have a platform_family attribute.")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#format_server_state" do
|
94
|
+
before(:each) do
|
95
|
+
@instance = Chef::Knife::Cloud::ServerListCommand.new
|
96
|
+
end
|
97
|
+
|
98
|
+
%w{ shutting-down terminated stopping stopped error shutoff }.each do |state|
|
99
|
+
it "set state color red on server state is in #{state}" do
|
100
|
+
expect(@instance.ui).to receive(:color).with(state, :red)
|
101
|
+
@instance.format_server_state(state)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
%w{ pending build paused suspended hard_reboot }.each do |state|
|
106
|
+
it "set state color yellow on server state is in #{state}" do
|
107
|
+
expect(@instance.ui).to receive(:color).with(state, :yellow)
|
108
|
+
@instance.format_server_state(state)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
%w{ running }.each do |state|
|
113
|
+
it "set state color green on server state is #{state}" do
|
114
|
+
expect(@instance.ui).to receive(:color).with(state, :green)
|
115
|
+
@instance.format_server_state(state)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013-2014 Chef Software, Inc.
|
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
|
+
require 'support/shared_examples_for_command'
|
19
|
+
require 'chef/knife/cloud/server/show_command'
|
20
|
+
|
21
|
+
describe Chef::Knife::Cloud::ServerShowCommand do
|
22
|
+
it_behaves_like Chef::Knife::Cloud::Command, Chef::Knife::Cloud::ServerShowCommand.new
|
23
|
+
|
24
|
+
describe "#validate_params!" do
|
25
|
+
before(:each) do
|
26
|
+
@instance = Chef::Knife::Cloud::ServerShowCommand.new
|
27
|
+
allow(@instance.ui).to receive(:error)
|
28
|
+
Chef::Config[:knife][:instance_id] = "instance_id"
|
29
|
+
end
|
30
|
+
after(:all) do
|
31
|
+
Chef::Config[:knife].delete(:instance_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "run sucessfully on all params exist" do
|
35
|
+
expect { @instance.validate_params! }.to_not raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it "raise error on missing instance_id param" do
|
39
|
+
Chef::Config[:knife].delete(:instance_id)
|
40
|
+
expect { @instance.validate_params! }.to raise_error(Chef::Knife::Cloud::CloudExceptions::ValidationError, " You must provide a valid Instance Id.")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#execute_command" do
|
45
|
+
it "show server summary" do
|
46
|
+
instance = Chef::Knife::Cloud::ServerShowCommand.new
|
47
|
+
instance.service = Chef::Knife::Cloud::Service.new
|
48
|
+
server = Object.new
|
49
|
+
expect(instance.service).to receive(:get_server).and_return(server)
|
50
|
+
expect(instance.service).to receive(:server_summary)
|
51
|
+
instance.execute_command
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raise error on invalid instance id" do
|
55
|
+
instance = Chef::Knife::Cloud::ServerShowCommand.new
|
56
|
+
instance.service = Chef::Knife::Cloud::Service.new
|
57
|
+
Chef::Config[:knife][:instance_id] = "invalid_id"
|
58
|
+
allow(instance.ui).to receive(:error)
|
59
|
+
expect(instance.service).to receive(:get_server).and_return(nil)
|
60
|
+
expect(instance.service).to_not receive(:server_summary)
|
61
|
+
expect { instance.execute_command }.to raise_error(Chef::Knife::Cloud::CloudExceptions::ServerShowError, "Server doesn't exists for this invalid_id instance id.")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|