knife-cloud 1.0.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +33 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +11 -0
  5. data/CONTRIBUTING.md +5 -0
  6. data/Gemfile +9 -0
  7. data/LICENSE +201 -0
  8. data/README.md +420 -0
  9. data/Rakefile +35 -0
  10. data/knife-cloud.gemspec +27 -0
  11. data/lib/chef/knife/cloud/chefbootstrap/bootstrap_distribution.rb +31 -0
  12. data/lib/chef/knife/cloud/chefbootstrap/bootstrap_options.rb +191 -0
  13. data/lib/chef/knife/cloud/chefbootstrap/bootstrap_protocol.rb +69 -0
  14. data/lib/chef/knife/cloud/chefbootstrap/bootstrapper.rb +78 -0
  15. data/lib/chef/knife/cloud/chefbootstrap/ssh_bootstrap_protocol.rb +179 -0
  16. data/lib/chef/knife/cloud/chefbootstrap/unix_distribution.rb +31 -0
  17. data/lib/chef/knife/cloud/chefbootstrap/windows_distribution.rb +32 -0
  18. data/lib/chef/knife/cloud/chefbootstrap/winrm_bootstrap_protocol.rb +85 -0
  19. data/lib/chef/knife/cloud/command.rb +101 -0
  20. data/lib/chef/knife/cloud/exceptions.rb +38 -0
  21. data/lib/chef/knife/cloud/fog/options.rb +29 -0
  22. data/lib/chef/knife/cloud/fog/service.rb +200 -0
  23. data/lib/chef/knife/cloud/helpers.rb +39 -0
  24. data/lib/chef/knife/cloud/list_resource_command.rb +97 -0
  25. data/lib/chef/knife/cloud/list_resource_options.rb +21 -0
  26. data/lib/chef/knife/cloud/server/create_command.rb +165 -0
  27. data/lib/chef/knife/cloud/server/create_options.rb +80 -0
  28. data/lib/chef/knife/cloud/server/delete_command.rb +68 -0
  29. data/lib/chef/knife/cloud/server/delete_options.rb +42 -0
  30. data/lib/chef/knife/cloud/server/list_command.rb +84 -0
  31. data/lib/chef/knife/cloud/server/list_options.rb +43 -0
  32. data/lib/chef/knife/cloud/server/options.rb +39 -0
  33. data/lib/chef/knife/cloud/server/show_command.rb +55 -0
  34. data/lib/chef/knife/cloud/server/show_options.rb +36 -0
  35. data/lib/chef/knife/cloud/service.rb +91 -0
  36. data/lib/knife-cloud/version.rb +6 -0
  37. data/lib/test/fixtures/knife.rb +9 -0
  38. data/lib/test/fixtures/validation.pem +27 -0
  39. data/lib/test/knife-utils/helper.rb +39 -0
  40. data/lib/test/knife-utils/knife_test_utils.rb +40 -0
  41. data/lib/test/knife-utils/matchers.rb +29 -0
  42. data/lib/test/knife-utils/test_bed.rb +56 -0
  43. data/lib/test/templates/chef-full-chef-zero.erb +67 -0
  44. data/lib/test/templates/windows-chef-client-msi.erb +231 -0
  45. data/lib/test/templates/windows-shell.erb +77 -0
  46. data/spec/resource_spec_helper.rb +49 -0
  47. data/spec/server_command_common_spec_helper.rb +48 -0
  48. data/spec/spec_helper.rb +25 -0
  49. data/spec/support/shared_examples_for_command.rb +35 -0
  50. data/spec/support/shared_examples_for_servercreatecommand.rb +144 -0
  51. data/spec/support/shared_examples_for_serverdeletecommand.rb +77 -0
  52. data/spec/support/shared_examples_for_service.rb +85 -0
  53. data/spec/unit/bootstrap_protocol_spec.rb +70 -0
  54. data/spec/unit/bootstrapper_spec.rb +171 -0
  55. data/spec/unit/cloud_command_spec.rb +35 -0
  56. data/spec/unit/command_spec.rb +49 -0
  57. data/spec/unit/fog_service_spec.rb +138 -0
  58. data/spec/unit/list_resource_command_spec.rb +136 -0
  59. data/spec/unit/server_create_command_spec.rb +198 -0
  60. data/spec/unit/server_delete_command_spec.rb +25 -0
  61. data/spec/unit/server_list_command_spec.rb +119 -0
  62. data/spec/unit/server_show_command_spec.rb +64 -0
  63. data/spec/unit/service_spec.rb +46 -0
  64. data/spec/unit/ssh_bootstrap_protocol_spec.rb +116 -0
  65. data/spec/unit/unix_distribution_spec.rb +37 -0
  66. data/spec/unit/windows_distribution_spec.rb +37 -0
  67. data/spec/unit/winrm_bootstrap_protocol_spec.rb +106 -0
  68. 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