knife-cloud 1.0.0.rc.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,80 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef/knife/cloud/chefbootstrap/bootstrap_options'
|
19
|
+
require 'chef/knife/cloud/server/options'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class Cloud
|
24
|
+
module ServerCreateOptions
|
25
|
+
|
26
|
+
def self.included(includer)
|
27
|
+
includer.class_eval do
|
28
|
+
include ServerOptions
|
29
|
+
include BootstrapOptions
|
30
|
+
option :image,
|
31
|
+
:short => "-I IMAGE",
|
32
|
+
:long => "--image IMAGE",
|
33
|
+
:description => "A regexp matching an image name or an image ID for the server",
|
34
|
+
:proc => Proc.new { |i| Chef::Config[:knife][:image] = i }
|
35
|
+
|
36
|
+
option :image_os_type,
|
37
|
+
:short => "-T IMAGE_OS_TYPE",
|
38
|
+
:long => "--image-os-type IMAGE_OS_TYPE",
|
39
|
+
:description => "The image os type. options [windows/linux]. Only required when cloud does not provide a way to identify image os",
|
40
|
+
:default => "linux",
|
41
|
+
:proc => Proc.new { |i| Chef::Config[:knife][:image_os_type] = i }
|
42
|
+
|
43
|
+
option :flavor,
|
44
|
+
:short => "-f FLAVOR_ID",
|
45
|
+
:long => "--flavor FLAVOR_ID",
|
46
|
+
:description => "The flavor name or ID of server",
|
47
|
+
:proc => Proc.new { |f| Chef::Config[:knife][:flavor] = f }
|
48
|
+
|
49
|
+
option :bootstrap_protocol,
|
50
|
+
:long => "--bootstrap-protocol protocol",
|
51
|
+
:description => "Protocol to bootstrap servers. options: winrm/ssh. For linux servers always use ssh.",
|
52
|
+
:default => 'ssh',
|
53
|
+
:proc => Proc.new { |b| Chef::Config[:knife][:bootstrap_protocol] = b}
|
54
|
+
|
55
|
+
option :server_create_timeout,
|
56
|
+
:long => "--server-create-timeout timeout",
|
57
|
+
:description => "How long to wait until the server is ready; default is 600 seconds",
|
58
|
+
:default => 600,
|
59
|
+
:proc => Proc.new { |v| Chef::Config[:knife][:server_create_timeout] = v}
|
60
|
+
|
61
|
+
option :delete_server_on_failure,
|
62
|
+
:long => "--delete-server-on-failure",
|
63
|
+
:boolean => true,
|
64
|
+
:default => false,
|
65
|
+
:description => "Destroy corresponding server in case of failure"
|
66
|
+
|
67
|
+
option :chef_node_name_prefix,
|
68
|
+
:long => "--chef-node-name-prefix PREFIX_FOR_NODE_NAME",
|
69
|
+
:description => "The prefix for chef node name",
|
70
|
+
:default => includer.snake_case_name.split('_').first,
|
71
|
+
:proc => Proc.new { |key| Chef::Config[:knife][:chef_node_name_prefix] = key }
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end # module end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, 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
|
+
|
19
|
+
require 'chef/knife/cloud/command'
|
20
|
+
# These two are needed for the '--purge' deletion case
|
21
|
+
require 'chef/node'
|
22
|
+
require 'chef/api_client'
|
23
|
+
|
24
|
+
class Chef
|
25
|
+
class Knife
|
26
|
+
class Cloud
|
27
|
+
class ServerDeleteCommand < Command
|
28
|
+
|
29
|
+
def execute_command
|
30
|
+
@name_args.each do |server_name|
|
31
|
+
service.delete_server(server_name)
|
32
|
+
delete_from_chef(server_name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_from_chef(server_name)
|
37
|
+
# delete the node from Chef if purge requested.
|
38
|
+
if config[:purge]
|
39
|
+
thing_to_delete = config[:chef_node_name] || server_name
|
40
|
+
destroy_item(Chef::Node, thing_to_delete, "node")
|
41
|
+
destroy_item(Chef::ApiClient, thing_to_delete, "client")
|
42
|
+
else
|
43
|
+
ui.warn("Corresponding node and client for the #{server_name} server were not deleted and remain registered with the Chef Server")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Extracted from Chef::Knife.delete_object, because it has a
|
48
|
+
# confirmation step built in... By specifying the '--purge'
|
49
|
+
# flag (and also explicitly confirming the server destruction!)
|
50
|
+
# the user is already making their intent known. It is not
|
51
|
+
# necessary to make them confirm two more times.
|
52
|
+
def destroy_item(klass, name, type_name)
|
53
|
+
begin
|
54
|
+
object = klass.load(name)
|
55
|
+
object.destroy
|
56
|
+
ui.warn("Deleted #{type_name} #{name}")
|
57
|
+
rescue Net::HTTPServerException => e
|
58
|
+
error_message = "#{e.message}. Could not find a #{type_name} named #{name} to delete!"
|
59
|
+
ui.warn(error_message)
|
60
|
+
raise CloudExceptions::ServerDeleteError, error_message
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end # class ServerDeleteCommand
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, 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
|
+
|
19
|
+
require 'chef/knife/cloud/server/options'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class Cloud
|
24
|
+
module ServerDeleteOptions
|
25
|
+
def self.included(includer)
|
26
|
+
includer.class_eval do
|
27
|
+
include ServerOptions
|
28
|
+
|
29
|
+
option :purge,
|
30
|
+
:short => "-P",
|
31
|
+
:long => "--purge",
|
32
|
+
:boolean => true,
|
33
|
+
:default => false,
|
34
|
+
:description => "Destroy corresponding node and client on the Chef Server, in addition to destroying the Cloud node itself. Assumes node and client have the same name as the server (if not, add the '--node-name' option)."
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'chef/knife/cloud/list_resource_command'
|
2
|
+
require 'chef/knife/cloud/exceptions'
|
3
|
+
|
4
|
+
class Chef
|
5
|
+
class Knife
|
6
|
+
class Cloud
|
7
|
+
class ServerListCommand < ResourceListCommand
|
8
|
+
|
9
|
+
def before_exec_command
|
10
|
+
if config[:chef_data]
|
11
|
+
begin
|
12
|
+
# Chef::Node.list(inflate = true) to use Solr search.
|
13
|
+
@node_list = Chef::Node.list(true)
|
14
|
+
rescue Errno::ECONNREFUSED => e
|
15
|
+
error_message = "Connection error with Chef server. #{e}"
|
16
|
+
ui.warn(error_message)
|
17
|
+
raise CloudExceptions::ChefServerError, error_message
|
18
|
+
end
|
19
|
+
|
20
|
+
@chef_data_col_info = [
|
21
|
+
{:label => 'Chef Node Name', :key => 'name'},
|
22
|
+
{:label => 'Environment', :key => 'chef_environment'},
|
23
|
+
{:label => 'FQDN', :key => 'fqdn'},
|
24
|
+
{:label => 'Runlist', :key => 'run_list'},
|
25
|
+
{:label => 'Tags', :key => 'tags'},
|
26
|
+
{:label => 'Platform', :key => 'platform'},
|
27
|
+
]
|
28
|
+
|
29
|
+
if config[:chef_node_attribute]
|
30
|
+
@chef_data_col_info << {:label => "#{config[:chef_node_attribute]}", :key => "#{config[:chef_node_attribute]}"}
|
31
|
+
end
|
32
|
+
@columns_with_info.concat(@chef_data_col_info)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Override from base to display chef node data along with server list display.
|
37
|
+
def get_resource_col_val(server)
|
38
|
+
list = []
|
39
|
+
@columns_with_info.each do |col_info|
|
40
|
+
if config[:chef_data] && @chef_data_col_info.include?(col_info)
|
41
|
+
server_name = service.get_server_name(server)
|
42
|
+
if @node_list.include?(server_name)
|
43
|
+
node = @node_list[server_name]
|
44
|
+
# Raise serverlisting error on invalid chef_node_attribute.
|
45
|
+
if col_info[:key] == config[:chef_node_attribute] && ! node.attribute?(col_info[:key])
|
46
|
+
error_message = "The Node does not have a #{col_info[:key]} attribute."
|
47
|
+
ui.error(error_message)
|
48
|
+
raise CloudExceptions::CloudAPIException, error_message
|
49
|
+
else
|
50
|
+
value = (col_info[:value_callback].nil? ? node.send(col_info[:key]).to_s : col_info[:value_callback].call(node.send(col_info[:key])))
|
51
|
+
end
|
52
|
+
else
|
53
|
+
# Set chef data value for those server which is not part chef server.
|
54
|
+
value = ""
|
55
|
+
end
|
56
|
+
else
|
57
|
+
value = (col_info[:value_callback].nil? ? server.send(col_info[:key]).to_s : col_info[:value_callback].call(server.send(col_info[:key])))
|
58
|
+
end
|
59
|
+
list << value
|
60
|
+
end
|
61
|
+
list
|
62
|
+
end
|
63
|
+
|
64
|
+
def query_resource
|
65
|
+
@service.list_servers
|
66
|
+
end
|
67
|
+
|
68
|
+
def format_server_state(state)
|
69
|
+
state = state.to_s.downcase
|
70
|
+
state_color = case state
|
71
|
+
when 'shutting-down','terminated','stopping','stopped','error','shutoff'
|
72
|
+
:red
|
73
|
+
when 'pending','build','paused','suspended','hard_reboot'
|
74
|
+
:yellow
|
75
|
+
else
|
76
|
+
:green
|
77
|
+
end
|
78
|
+
ui.color(state, state_color)
|
79
|
+
end
|
80
|
+
|
81
|
+
end # class ServerListCommand
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Siddheshwar More (<siddheshwar.more@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, 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
|
+
|
19
|
+
class Chef
|
20
|
+
class Knife
|
21
|
+
class Cloud
|
22
|
+
module ServerListOptions
|
23
|
+
def self.included(includer)
|
24
|
+
includer.class_eval do
|
25
|
+
|
26
|
+
option :chef_data,
|
27
|
+
:long => "--chef-data",
|
28
|
+
:boolean => true,
|
29
|
+
:default => false,
|
30
|
+
:description => "Display chef node data which include chef node name, environment name, fqdn, platform, runlist and tags."
|
31
|
+
|
32
|
+
option :chef_node_attribute,
|
33
|
+
:long => "--chef-node-attribute CHEF_NODE_ATTRIBUTE_NAME",
|
34
|
+
:description => "Used with --chef-data option. It display node attributes details by adding new column in server list display.",
|
35
|
+
:proc => Proc.new { |i| Chef::Config[:knife][:chef_node_attribute] = i }
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, 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
|
+
|
19
|
+
class Chef
|
20
|
+
class Knife
|
21
|
+
class Cloud
|
22
|
+
module ServerOptions
|
23
|
+
def self.included(includer)
|
24
|
+
includer.class_eval do
|
25
|
+
option :chef_node_name,
|
26
|
+
:short => "-N NAME",
|
27
|
+
:long => "--node-name NAME",
|
28
|
+
:description => "The name of the node and client to delete, if it differs from the server name. Only has meaning when used with the '--purge' option."
|
29
|
+
|
30
|
+
option :custom_attributes,
|
31
|
+
:long => "--custom-attributes CUSTOM_ATTRIBUTES",
|
32
|
+
:description => "Custom attributes to be passed to Fog.",
|
33
|
+
:proc => Proc.new {|args| Chef::Config[:knife][:custom_attributes] = args.split(';').map{|keys| keys.split('=')}.map{|j| Hash[*j.map{|k| k.strip}]}}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
require 'chef/knife/cloud/command'
|
19
|
+
require 'chef/knife/cloud/exceptions'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class Cloud
|
24
|
+
class ServerShowCommand < Command
|
25
|
+
|
26
|
+
def initialize(argv=[])
|
27
|
+
super argv
|
28
|
+
# columns_with_info is array of hash with label, key and attribute extraction callback, ex [{:label => "Label text", :key => 'key', value_callback => callback_method to extract/format the required value}, ...]
|
29
|
+
@columns_with_info = []
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_params!
|
33
|
+
errors = []
|
34
|
+
config[:instance_id] = @name_args.first
|
35
|
+
if locate_config_value(:instance_id).nil?
|
36
|
+
errors << "You must provide a valid Instance Id"
|
37
|
+
end
|
38
|
+
error_message = ""
|
39
|
+
raise CloudExceptions::ValidationError, error_message if errors.each{|e| ui.error(e); error_message = "#{error_message} #{e}."}.any?
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute_command
|
43
|
+
server = service.get_server(locate_config_value(:instance_id))
|
44
|
+
if server.nil?
|
45
|
+
error_message = "Server doesn't exists for this #{locate_config_value(:instance_id)} instance id."
|
46
|
+
ui.error(error_message)
|
47
|
+
raise CloudExceptions::ServerShowError, error_message
|
48
|
+
else
|
49
|
+
service.server_summary(server, @columns_with_info)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2013 Opscode, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
#
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class Knife
|
20
|
+
class Cloud
|
21
|
+
module ServerShowOptions
|
22
|
+
def self.included(includer)
|
23
|
+
includer.class_eval do
|
24
|
+
|
25
|
+
option :instance_id,
|
26
|
+
:long => "--instance-id INSTANCE_ID",
|
27
|
+
:description => "Required. Instance Id of Server",
|
28
|
+
:proc => Proc.new { |i| Chef::Config[:knife][:instance_id] = i }
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Kaustubh Deorukhkar (<kaustubh@clogeny.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Opscode, 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
|
+
|
19
|
+
require 'chef/knife/cloud/exceptions'
|
20
|
+
require "chef/knife/cloud/helpers"
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class Knife
|
24
|
+
class Cloud
|
25
|
+
class Service
|
26
|
+
include Cloud::Helpers
|
27
|
+
attr_accessor :ui
|
28
|
+
|
29
|
+
def initialize(options = {})
|
30
|
+
@auth_params = options[:auth_params]
|
31
|
+
end
|
32
|
+
|
33
|
+
def connection
|
34
|
+
# Fog or cloud specific connection object must be created in derived.
|
35
|
+
raise Chef::Exceptions::Override, "You must override connection in #{self.to_s}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# override in cloud specific derived classes
|
39
|
+
def list_resource_allocations
|
40
|
+
end
|
41
|
+
|
42
|
+
# Do nothing or override in cloud specific derived classes for pre-vm-creation setup steps
|
43
|
+
def create_server_dependencies
|
44
|
+
end
|
45
|
+
|
46
|
+
# Do nothing or override in cloud specific derived classes for pre-vm-creation setup steps
|
47
|
+
def delete_server_dependencies
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete_server_on_failure(server = nil)
|
51
|
+
raise Chef::Exceptions::Override, "You must override delete_server_on_failure in #{self.to_s} to delete server"
|
52
|
+
end
|
53
|
+
|
54
|
+
# cloud server specific implementation methods for commands.
|
55
|
+
def create_server(options = {})
|
56
|
+
raise Chef::Exceptions::Override, "You must override create_server in #{self.to_s}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_server(server_name)
|
60
|
+
raise Chef::Exceptions::Override, "You must override delete_server in #{self.to_s}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def list_servers
|
64
|
+
raise Chef::Exceptions::Override, "You must override list_servers in #{self.to_s}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def list_images(image_filters)
|
68
|
+
raise Chef::Exceptions::Override, "You must override list_images in #{self.to_s}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def list_resource_configurations
|
72
|
+
raise Chef::Exceptions::Override, "You must override list_resource_configurations in #{self.to_s}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_server(server_name)
|
76
|
+
raise Chef::Exceptions::Override, "You must override get_server in #{self.to_s}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def server_summary(server, columns_with_info = [])
|
80
|
+
raise Chef::Exceptions::Override, "You must override server_summary in #{self.to_s}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_custom_attributes(server_def)
|
84
|
+
Chef::Config[:knife][:custom_attributes].map{|args| args.map{|k,v| server_def.merge!(k.to_sym => v)}} unless Chef::Config[:knife][:custom_attributes].nil?
|
85
|
+
end
|
86
|
+
|
87
|
+
end # class service
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
current_dir = File.dirname(__FILE__)
|
2
|
+
node_name "chef0"
|
3
|
+
client_key "#{current_dir}/validation.pem"
|
4
|
+
validation_client_name "validation"
|
5
|
+
validation_key "#{current_dir}/validation.pem"
|
6
|
+
chef_server_url "http://localhost:8889"
|
7
|
+
cache_type 'BasicFile'
|
8
|
+
cache_options( :path => "#{ENV['HOME']}/.chef/checksums" )
|
9
|
+
cookbook_path ["#{current_dir}/chef-repo/cookbooks"]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEogIBAAKCAQEA7TfhToresZudM5gaBfzM/eHrGuJtN8uMaG51fLk9rNVwOxIw
|
3
|
+
eb9AmWJSQgftRj4AJSnt8Jv+QyAafjg79rEmCpd2K+toN1fXiVsf/ld/VdMI5vCd
|
4
|
+
usJc8aC4OFIVrLetm9eq+joXiCSLfEYP1w4d1gc9wqr54rnGVgQdWv31NhqXX7Tl
|
5
|
+
2bHRoEsfIFM7Vr5zC9Rv6XEtrwezSpzQ+ru707UOCOHNnH1TDxNDz+L71xJnGXD6
|
6
|
+
uh596hVm2GiXJ8lyCVJTs/RZ+HKtRuxYOJztdCQAXbd6DDjTBax/cCEzzoxK/LMc
|
7
|
+
1K/zWCKN8yM/XpiFqNuBB0yrqS5Y4zlROY0ssQIDAQABAoIBAQDmC1HYvD1YGePq
|
8
|
+
O+/IrK8S6jr4WGq4OBIS2EPhTzbrXBU5g9s0xe7ckIfa9xr4CnpTkATqWCzMZd6r
|
9
|
+
Vtd31bVhgh6cWu829F3WG2O8YJfg4AX7B46+pWxC+qyMGbZhR8L5pb1ualWVtnL6
|
10
|
+
cms8D7mJbH5NQUeRwrz/f4AEVNGuw165PhglXnRq3zxs97jdNH6av0na1VLAmUeR
|
11
|
+
vmYToLoIsK5yLeNzMfRRrQkq4ndUvad2ahqsz+p/xUjfYneBz4uujE/PcCgi423Q
|
12
|
+
FMH1NtPpzmuZuABU53wUMW4BXsSGv+34UMhRTazcBPRBYjKT6l6F7Tt9wPFxrtVn
|
13
|
+
KYI9dI0tAoGBAPzBwLsUuyEJtSd2zW63f7EhhG/2rSBm1g9Bcs1sHZtXIX3JN51X
|
14
|
+
hd+ckXQcLgQYn8syGW1+WcuaHGyp7v3G0yr6b38FWwEnmD85Mq5da1dyio2udBdK
|
15
|
+
Xm8MfY94yP8qSH3bUDKEl+cV9X5rtzbQAorMXb/Qkc4vErWfABVBKeLPAoGBAPBD
|
16
|
+
FjGxER9YU4hFV2vn5qElfxa799Vl0uSvao0lSkTpA/sHFxAkRQc/mo1PBClaH0ba
|
17
|
+
Hqr141o5pGUDgLqpO3kEY5vYBOaFXLFdFCcL+1YUR6t0bX+WCHuq21Cs6Gu4+qNA
|
18
|
+
D4dpsSPDXfatyXWM5PF2d4FwO2XnL25Yt+rg6dh/AoGAbEfk9UCQWjr6bImswH3E
|
19
|
+
KnIddonK6VKk6aw0LmTe2imdo3GMbc+M/prohUF9RSv3aOlxk0LJ3TuMadDzHa0L
|
20
|
+
0iGvmk8FCZ2Yz50FZUWIMtJTIRdXjJLDmfdT4x7vnMDUhXZrCPlcyhbSMPKcbtL2
|
21
|
+
A9hBYWdMz3PDJCOVuYVNGGkCgYEAhSxKUwTYfs1Qj8oPqOoDdfL4vLs3pfsoqEVr
|
22
|
+
BA1VW1jlMfE+IV5ZPKlOm2De56TijT09nnloqYwlyS/l3JENPAjoxWs5XCUzucPj
|
23
|
+
9bi4eYAIMcr5Hq0kypdrtQ4CTiNcGbzaXq6A11fk72RotFWCWSzXFNIGuncoXTuj
|
24
|
+
xfcg5zUCf3TQrwpcBB1Hf9hm6lUVpptvUZJAQtkWoaWXUPRY0CjcVdDc5ak4xqL2
|
25
|
+
FcAuJwV95b3qLyPESJ8zUBLOg3DcT1X9mrvRuKgC/Ie6k4R+oxU/nXi4vsPXlvg4
|
26
|
+
yap6MUYSjPOa7eCrhg2zFZiqO6VLEogPc1nsjb9Zl2UWLLYyCVz=
|
27
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/knife_test_utils')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/matchers')
|
6
|
+
|
7
|
+
module KnifeTestHelper
|
8
|
+
extend RSpec::KnifeTestUtils
|
9
|
+
def temp_dir
|
10
|
+
@_temp_dir ||= Dir.mktmpdir
|
11
|
+
end
|
12
|
+
|
13
|
+
def match_status(test_run_expect)
|
14
|
+
if "#{test_run_expect}" == "should fail"
|
15
|
+
should_not have_outcome :status => 0
|
16
|
+
elsif "#{test_run_expect}" == "should succeed"
|
17
|
+
should have_outcome :status => 0
|
18
|
+
elsif "#{test_run_expect}" == "should return empty list"
|
19
|
+
should have_outcome :status => 0
|
20
|
+
else
|
21
|
+
should have_outcome :status => 0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def match_stdout(test_run_expect)
|
26
|
+
should have_outcome :stdout => test_run_expect
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_file(file_dir, file_name, data_to_write_file_path)
|
30
|
+
puts "Creating: #{file_name}"
|
31
|
+
begin
|
32
|
+
data_to_write = File.read(File.expand_path("#{data_to_write_file_path}", __FILE__))
|
33
|
+
File.open("#{file_dir}/#{file_name}", 'w') {|f| f.write(data_to_write)}
|
34
|
+
rescue
|
35
|
+
puts "Error while creating file - #{file_name}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'mixlib/shellout'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module KnifeTestUtils
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
subject { knife_run }
|
9
|
+
let(:knife_run) { run command }
|
10
|
+
let(:command) { fail 'Define let(:command) in the spec' }
|
11
|
+
let(:cmd_output) { @op }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Convenience method for actually running a knife command in our
|
16
|
+
# testing repository. Returns the Mixlib::Shellout object ready for
|
17
|
+
# inspection.
|
18
|
+
def run(command_line)
|
19
|
+
shell_out = Mixlib::ShellOut.new("#{command_line}")
|
20
|
+
shell_out.timeout = 3000
|
21
|
+
shell_out.tap(&:run_command)
|
22
|
+
@op = shell_out.exitstatus == 1 ? shell_out.stderr : shell_out.stdout
|
23
|
+
return shell_out
|
24
|
+
end
|
25
|
+
|
26
|
+
def knife(knife_command)
|
27
|
+
run "knife #{knife_command}"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Convenience function for grabbing a hash of several important
|
31
|
+
# Mixlib::Shellout command configuration parameters.
|
32
|
+
def self.command_setting(shellout_command)
|
33
|
+
keys = [:cwd, :user, :group, :umask, :timeout, :valid_exit_codes, :environment]
|
34
|
+
keys.inject({}) do |hash, attr|
|
35
|
+
hash[attr] = shellout_command.send(attr)
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|