knife-rightscale 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, 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
+ # -*- encoding: utf-8 -*-
20
+ lib = File.expand_path('../lib', __FILE__)
21
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
22
+ require 'knife-rightscale/version'
23
+
24
+ Gem::Specification.new do |gem|
25
+ gem.name = "knife-rightscale"
26
+ gem.version = Knife::Rightscale::VERSION
27
+ gem.authors = ["Cary Penniman"]
28
+ gem.email = ["cary@rightscale.com"]
29
+ gem.description = %q{One plugin to provision them all! This plugin allows the Chef developer to provision Chef clients on all major clouds using the RightScale platform.}
30
+ gem.summary = %q{RightScale plugin for Knife}
31
+ gem.homepage = "http://github.com/caryp/knife-rightscale"
32
+
33
+ gem.files = `git ls-files`.split($/)
34
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
35
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
36
+ gem.require_paths = ["lib"]
37
+ end
@@ -0,0 +1,113 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # This file is modified from the knife-ec2 plugin project code
7
+ # That project is located at https://github.com/opscode/knife-ec2
8
+ # Author:: Seth Chisamore <schisamo@opscode.com>
9
+ # Copyright:: Copyright (c) 2011 Opscode, Inc.
10
+ # License:: Apache License, Version 2.0
11
+ #
12
+ # Licensed under the Apache License, Version 2.0 (the "License");
13
+ # you may not use this file except in compliance with the License.
14
+ # You may obtain a copy of the License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the License is distributed on an "AS IS" BASIS,
20
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ # See the License for the specific language governing permissions and
22
+ # limitations under the License.
23
+ #
24
+ require 'chef/knife'
25
+ require 'right_api_provision/provisioner'
26
+ require 'right_api_provision/api15'
27
+
28
+ class Chef
29
+ class Knife
30
+ module RightscaleBase
31
+
32
+ # :nodoc:
33
+ # Would prefer to do this in a rational way, but can't be done b/c of
34
+ # Mixlib::CLI's design :(
35
+ def self.included(includer)
36
+ includer.class_eval do
37
+
38
+ deps do
39
+ require 'right_api_client'
40
+ end
41
+
42
+ option :rightscale_user,
43
+ :short => "-U USER",
44
+ :long => "--rightscale-user USER",
45
+ :description => "Your RightScale User Email",
46
+ :proc => Proc.new { |key| Chef::Config[:knife][:rightscale_user] = key }
47
+
48
+ option :rightscale_password,
49
+ :short => "-P PASSWORD",
50
+ :long => "--rightscale-password PASSWORD",
51
+ :description => "Your RightScale password",
52
+ :proc => Proc.new { |key| Chef::Config[:knife][:rightscale_password] = key }
53
+
54
+ option :rightscale_account_id,
55
+ :short => "-A ID",
56
+ :long => "--rightscale-account-id ID",
57
+ :description => "Your RightScale account ID",
58
+ :proc => Proc.new { |key| Chef::Config[:knife][:rightscale_account_id] = key }
59
+
60
+ option :rightscale_api_url,
61
+ :short => "-L API_URL",
62
+ :long => "--rightscale-api-url API_URL",
63
+ :description => "The API URL (defaults to my.rightscale.com)",
64
+ :default => "https://my.rightscale.com",
65
+ :proc => Proc.new { |key| Chef::Config[:knife][:rightscale_api_url] = key }
66
+
67
+ end
68
+ end
69
+
70
+ def connection
71
+ @connection ||= begin
72
+ client = ::RightApiProvision::API15.new
73
+ client.connection(
74
+ Chef::Config[:knife][:rightscale_user],
75
+ Chef::Config[:knife][:rightscale_password],
76
+ Chef::Config[:knife][:rightscale_account_id],
77
+ Chef::Config[:knife][:rightscale_api_url]
78
+ )
79
+ client
80
+ end
81
+ end
82
+
83
+ def locate_config_value(key)
84
+ key = key.to_sym
85
+ config[key] || Chef::Config[:knife][key]
86
+ end
87
+
88
+ def msg_pair(label, value, color=:cyan)
89
+ if value && !value.to_s.empty?
90
+ puts "#{ui.color(label, color)}: #{value}"
91
+ end
92
+ end
93
+
94
+ def validate!(keys=[:rightscale_user, :rightscale_password, :rightscale_account_id])
95
+ errors = []
96
+
97
+ keys.each do |k|
98
+ pretty_key = k.to_s.gsub(/_/, ' ').gsub(/\w+/){ |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize }
99
+ if Chef::Config[:knife][k].nil?
100
+ errors << "You did not provide a valid '#{pretty_key}' value."
101
+ end
102
+ end
103
+
104
+ if errors.each{|e| ui.error(e)}.any?
105
+ exit 1
106
+ end
107
+ end
108
+
109
+ end
110
+ end
111
+ end
112
+
113
+
@@ -0,0 +1,72 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, 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/rightscale_base'
20
+
21
+ class Chef
22
+ class Knife
23
+ class RightscaleCloudList < Knife
24
+
25
+ include Knife::RightscaleBase
26
+
27
+ deps do
28
+ require 'right_api_client'
29
+ require 'timeout'
30
+ end
31
+
32
+ banner "knife rightscale cloud list (options)"
33
+
34
+ option :cloud_name,
35
+ :short => "-n CLOUD_NAME",
36
+ :long => "--name CLOUD_NAME",
37
+ :description => "The name of the cloud to search for",
38
+ :proc => Proc.new { |i| Chef::Config[:knife][:cloud_name] = i }
39
+
40
+ def run
41
+ $stdout.sync = true
42
+
43
+ validate!
44
+
45
+ # query clouds
46
+ @clouds = connection.list_clouds(:by_name, config[:cloud_name])
47
+
48
+ cloud_list = [
49
+ ui.color('Name', :bold),
50
+ ui.color('Description', :bold)
51
+ ].flatten.compact
52
+
53
+ output_column_count = cloud_list.length
54
+
55
+ @clouds.each do |cloud|
56
+ cloud_list << cloud.name
57
+ cloud_list << cloud.description
58
+ end
59
+
60
+ puts ui.list(cloud_list, :uneven_columns_across, output_column_count)
61
+
62
+ end
63
+
64
+ private
65
+
66
+ def validate!
67
+ super([:rightscale_user, :rightscale_password, :rightscale_account_id])
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,70 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, 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/rightscale_base'
20
+
21
+ class Chef
22
+ class Knife
23
+ class RightscaleDeploymentList < Knife
24
+
25
+ include Knife::RightscaleBase
26
+
27
+ deps do
28
+ require 'right_api_client'
29
+ end
30
+
31
+ option :deployment_name,
32
+ :short => "-n DEPLOYMENTNAME",
33
+ :long => "--name DEPLOYMENTNAME",
34
+ :description => "The name of the deployment to search for",
35
+ :proc => Proc.new { |i| Chef::Config[:knife][:deployment_name] = i }
36
+
37
+ banner "knife rightscale deployment list (options)"
38
+
39
+ def run
40
+ $stdout.sync = true
41
+
42
+ validate!
43
+
44
+ @deployments = connection.list_deployments(:by_name, config[:deployment_name])
45
+
46
+ deployment_list = [
47
+ ui.color('Name', :bold),
48
+ ui.color('Description', :bold)
49
+ ].flatten.compact
50
+
51
+ output_column_count = deployment_list.length
52
+
53
+ @deployments.each do |deployment|
54
+ deployment_list << deployment.name
55
+ deployment_list << deployment.description
56
+ end
57
+
58
+ puts ui.list(deployment_list, :uneven_columns_across, output_column_count)
59
+
60
+ end
61
+
62
+ private
63
+
64
+ def validate!
65
+ super([:rightscale_user, :rightscale_password, :rightscale_account_id])
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,116 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, 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/rightscale_base'
20
+
21
+ class Chef
22
+ class Knife
23
+ class RightscaleImageList < Knife
24
+
25
+ include Knife::RightscaleBase
26
+
27
+ deps do
28
+ require 'right_api_client'
29
+ end
30
+
31
+ option :server_template,
32
+ :short => "-s SERVER_TEMPLATE",
33
+ :long => "--server-template SERVER_TEMPLATE",
34
+ :description => "The name of the ServerTemplate or ID to use for the server",
35
+ :proc => Proc.new { |i| Chef::Config[:knife][:server_template] = i },
36
+ :required => true
37
+
38
+ option :cloud_name,
39
+ :short => "-c CLOUD",
40
+ :long => "--cloud CLOUD",
41
+ :description => "The cloud you plan to run on.",
42
+ :proc => Proc.new { |f| Chef::Config[:knife][:cloud_name] = f },
43
+ :required => true
44
+
45
+ option :image_name,
46
+ :short => "-n IMAGE_NAME",
47
+ :long => "--name IMAGE_NAME",
48
+ :description => "The partial name of the image to search for",
49
+ :proc => Proc.new { |i| Chef::Config[:knife][:image_name] = i }
50
+
51
+ banner "knife rightscale image list (options)"
52
+
53
+ def run
54
+ $stdout.sync = true
55
+
56
+ validate!
57
+
58
+ # fail if the requested cloud is not registered with RightScale account
59
+ puts(ui.color('Looking up cloud...', :magenta))
60
+ @cloud = connection.find_cloud_by_name(config[:cloud_name])
61
+ raise "ERROR: cannot find a cloud named: '#{config[:cloud_name]}'. " +
62
+ "See 'knife rightscale cloud list' command for a list of clouds" +
63
+ " registered with your RightScale account" unless @cloud
64
+
65
+ puts(ui.color('Looking up ServerTemplate...', :magenta))
66
+ @st = connection.find_servertemplate(config[:server_template])
67
+ raise "ERROR: cannot find ServerTemplate '#{config[:server_template]}'. Did you import it?\n" +
68
+ "Visit http://bit.ly/VnOiA7 for more info.\n\n" unless @st
69
+
70
+ image_list = [
71
+ ui.color('Image', :bold),
72
+ ui.color('Instance Type (default)', :bold)
73
+ ].flatten.compact
74
+
75
+ output_column_count = image_list.length
76
+
77
+ puts(ui.color('Looking up supported multi-cloud images...', :magenta))
78
+ @multi_cloud_images = connection.list_multi_cloud_images(@st, :by_name, config[:image_name])
79
+
80
+ print(ui.color('Inspecting ServerTemplate images...', :magenta))
81
+ @multi_cloud_images.each do |multi_cloud_image|
82
+ multi_cloud_image.settings.index.each do |cloud_setting|
83
+ print(ui.color(".", :magenta))
84
+ STDOUT.flush
85
+ next unless registered_cloud?(cloud_setting.cloud)
86
+ image_list << multi_cloud_image.name
87
+ image_list << instance_type(cloud_setting.show)
88
+ end
89
+ end
90
+ puts
91
+ puts ui.list(image_list, :uneven_columns_across, output_column_count)
92
+ end
93
+
94
+ private
95
+
96
+ def instance_type(setting)
97
+ type = "n/a"
98
+ type = setting.instance_type.show.name if instance_type?(setting)
99
+ type
100
+ end
101
+
102
+ def instance_type?(setting)
103
+ setting.respond_to?(:instance_type)
104
+ end
105
+
106
+ def registered_cloud?(cloud)
107
+ cloud.href == @cloud.href
108
+ end
109
+
110
+ def validate!
111
+ super([:rightscale_user, :rightscale_password, :rightscale_account_id])
112
+ end
113
+
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,78 @@
1
+ #
2
+ # Author:: Cary Penniman (<cary@rightscale.com>)
3
+ # Copyright:: Copyright (c) 2013 RightScale, 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/rightscale_base'
20
+
21
+ class Chef
22
+ class Knife
23
+ class RightscaleSecuritygroupList < Knife
24
+
25
+ include Knife::RightscaleBase
26
+
27
+ deps do
28
+ require 'right_api_client'
29
+ end
30
+
31
+ option :security_group_name,
32
+ :short => "-n SECURITYGROUP_NAME",
33
+ :long => "--name SECURITYGROUP_NAME",
34
+ :description => "The partial name of the security group to search for",
35
+ :proc => Proc.new { |i| Chef::Config[:knife][:security_group_name] = i }
36
+
37
+ option :cloud_name,
38
+ :short => "-C CLOUD_NAME",
39
+ :long => "--cloud CLOUD_NAME",
40
+ :description => "The partial name of the cloud to search for",
41
+ :proc => Proc.new { |i| Chef::Config[:knife][:cloud_name] = i }
42
+
43
+ banner "knife rightscale securitygroup list (options)"
44
+
45
+ def run
46
+ $stdout.sync = true
47
+
48
+ validate!
49
+ @clouds = connection.list_clouds(:by_name, config[:cloud_name])
50
+ count = @clouds.size
51
+ puts ui.color("Querying #{count} clouds for security groups. Could take a minute...", :magenta) if count > 1
52
+ security_group_list = [
53
+ ui.color('Cloud', :bold),
54
+ ui.color('Name', :bold),
55
+ ui.color('Resource UID', :bold)
56
+ ].flatten.compact
57
+
58
+ output_column_count = security_group_list.length
59
+ @clouds.each do |cloud|
60
+ @security_groups = connection.list_security_groups(cloud, :by_name, config[:security_group_name])
61
+ @security_groups.each do |security_group|
62
+ security_group_list << cloud.name
63
+ security_group_list << security_group.name
64
+ security_group_list << security_group.resource_uid
65
+ end
66
+ end
67
+ puts ui.list(security_group_list, :uneven_columns_across, output_column_count)
68
+ end
69
+
70
+ private
71
+
72
+ def validate!
73
+ super([:rightscale_user, :rightscale_password, :rightscale_account_id])
74
+ end
75
+
76
+ end
77
+ end
78
+ end