knife-rightscale 0.0.3 → 0.1.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.
data/CHANGELOG CHANGED
@@ -1,4 +1,6 @@
1
1
  v0.0.2
2
2
  * initial release
3
3
  v0.0.3
4
- * Updated Gemspec with right_api_client dependency. by kevinkarwaski
4
+ * Updated Gemspec with right_api_client dependency. by kevinkarwaski
5
+ v0.0.4
6
+ * retrofit to use right_api_provision client gem
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem "right_api_provision"
4
+
3
5
  # Specify your gem's dependencies in knife-rightscale.gemspec
4
6
  gemspec
data/README.md CHANGED
@@ -1,60 +1,54 @@
1
1
  # Knife RightScale
2
2
 
3
- This is a Knife plugin for RightScale. This plugin gives knife the ability to
4
- provision servers on clouds managed by the RightScale platform. It is expected
5
- that you already have a Chef Server running or are using a hosted Chef solution
3
+ This is a Knife plugin for RightScale. This plugin gives knife the ability to
4
+ provision servers on clouds managed by the RightScale platform. It is expected
5
+ that you already have a Chef Server running or are using a hosted Chef solution
6
6
  from OpsCode.
7
7
 
8
8
  NOTE: this plugin is currently under development and subject to change
9
9
 
10
10
  ## REQUIREMENTS:
11
11
 
12
- You will need a RightScale account with at least one cloud registered. You can
13
- sign up for a free trial account [here](https://www.rightscale.com).
14
-
15
- I was lazy and only added support for the RightScale API 1.5 (since API 1.0 is
16
- EC2 only and deprecated). As such, this plugin cannot currently provision
17
- servers on EC2. If you need this capability and would like to part in a private
18
- beta to enable that functionality, please contact support@rightscale.com and
19
- they will hook you up. If you have any problems, please send me an email
20
- directly.
12
+ You will need a RightScale account with at least one cloud registered. You can
13
+ sign up for a free trial account [here](https://www.rightscale.com).
21
14
 
22
15
  You will also need a running Chef Server. If you don't already have one you can
23
16
  sign up for a free trial of Hosted Chef from Opscode [here](http://www.opscode.com/hosted-chef/).
24
17
 
18
+ If you have an existing account and want to provision on EC2 clouds, you may need to migrate your account to the Unified Cloud Platform. Please see [here](http://support.rightscale.com/Announcements/2013-09-20_Unified_Cloud_Platform_Migration_Details) for more info on UCP.
25
19
 
26
20
  ## INSTALLATION:
27
21
 
28
22
  Be sure you are running the latest version Chef 10. Versions earlier than 0.10.0
29
23
  don't support plugins. This has not yet been tested with Chef 11.
30
24
 
31
- gem install chef -v 10.24.0
25
+ gem install chef -v 10.26.0
32
26
 
33
27
  This plugin is distributed as a Ruby Gem. To install it, run:
34
28
 
35
29
  gem install knife-rightscale
36
30
 
37
- Depending on your system's configuration, you may need to run this command with
31
+ Depending on your system's configuration, you may need to run this command with
38
32
  root privileges.
39
33
 
40
34
  ## CONFIGURATION:
41
35
 
42
- In order to communicate with the RightScale API you will have to tell Knife
43
- about your RightScale account information. The easiest way to accomplish this
36
+ In order to communicate with the RightScale API you will have to tell Knife
37
+ about your RightScale account information. The easiest way to accomplish this
44
38
  is to create some entries in your <tt>knife.rb</tt> file:
45
39
 
46
40
  knife[:rightscale_user] = "you@yourdomain.com"
47
41
  knife[:rightscale_password] = "supersecretpassword"
48
42
  knife[:rightscale_account_id] = "1234"
49
43
 
50
- If your knife.rb file will be checked into a SCM system (ie readable by others)
44
+ If your knife.rb file will be checked into a SCM system (i.e. readable by others)
51
45
  you may want to read the values from environment variables:
52
46
 
53
47
  knife[:rightscale_user] = "#{ENV['RIGHTSCALE_EMAIL']}"
54
48
  knife[:rightscale_password] = "#{ENV['RIGHTSCALE_PASSWORD']}"
55
49
 
56
- You also have the option of passing your RightScale credentials into the
57
- individual knife subcommands using the <tt>-A</tt> (or <tt>--rightscale-account-id</tt>),
50
+ You also have the option of passing your RightScale credentials into the
51
+ individual knife subcommands using the <tt>-A</tt> (or <tt>--rightscale-account-id</tt>),
58
52
  <tt>-U</tt> (or <tt>--rightscale-user</tt>), <tt>-P</tt> (or <tt>--rightscale-password</tt>) command options
59
53
 
60
54
  ## Provision a Server
@@ -72,18 +66,18 @@ to filter by partial name match use ```-n``` or ```--name``` option
72
66
  List the ServerTemplates available in your account. Typically you will just want to find a Chef Client template. For example:
73
67
 
74
68
  knife rightscale servertemplate list --name "Chef Client"
75
-
69
+
76
70
  ### Launch a server
77
71
  To provision a new server, supply ServerTemplate choice and target cloud as options:
78
72
 
79
73
  knife rightscale server create \
80
74
  --cloud "Rackspace Open Cloud - Chicago" \
81
75
  --server-template "Chef Client (v13.4)" \
82
- --deployment "CKP: My Sandbox" \
83
- --name "CKP:ChefClient" \
76
+ --deployment "CP: My Sandbox" \
77
+ --name "CP:ChefClient" \
84
78
  --input "chef/client/server_url":"text:https://api.opscode.com/organizations/kindsol" \
85
- --input "chef/client/validation_name":"cred:CKP: validation_client_name" \
86
- --input "chef/client/validator_pem":"cred:CKP:validator.pem" \
79
+ --input "chef/client/validation_name":"cred:CP: validation_client_name" \
80
+ --input "chef/client/validator_pem":"cred:CP:validator.pem" \
87
81
  --input "chef/client/node_name":"text:MyChefClient" \
88
82
  --input "chef/client/roles":"text:hello_world"
89
83
 
@@ -105,15 +99,15 @@ use the ```--yes``` option to bypass confirmation.
105
99
 
106
100
  ## OTHER SUBCOMMANDS:
107
101
 
108
- Some other subcommands that can be useful for provisioning servers are listed
109
- below. These are intended to query possible options that you can pass to the
110
- server create command.
102
+ Some other subcommands that can be useful for provisioning servers are listed
103
+ below. These are intended to query possible options that you can pass to the
104
+ server create command.
111
105
 
112
106
  All supported command options can be found by invoking:
113
107
 
114
- knife rightscale --help
108
+ knife rightscale --help
115
109
 
116
- Specific details for each command can be found by passing the ```--help```
110
+ Specific details for each command can be found by passing the ```--help```
117
111
  option the the subcommand. For example:
118
112
 
119
113
  knife rightscale <subcommand> --help
@@ -127,7 +121,7 @@ List the supported images for a given ServerTemplate and target cloud
127
121
  --cloud "Rackspace Open Cloud - Chicago"
128
122
 
129
123
  This will also indicate the default Instance Type or flavor for each image.
130
-
124
+ 
131
125
 
132
126
  ### List Deployments
133
127
  To list all the deployments available in your RightScale account:
@@ -142,7 +136,7 @@ To list all the Security Groups available per cloud:
142
136
 
143
137
  knife rightscale securitygroup list
144
138
 
145
- to filter by partial name match use the ```--name``` option or narrow the
139
+ to filter by partial name match use the ```--name``` option or narrow the
146
140
  results using the ```--cloud``` option
147
141
 
148
142
 
@@ -153,6 +147,22 @@ To list all the servers in your RightScale account:
153
147
 
154
148
  to filter by partial name match use the ```--name``` option
155
149
 
150
+ ## DEVELOPMENT
151
+
152
+ You can develop this plugin with out installing it using the bundler gem. First clone this repository, change to the working directory and run:
153
+
154
+ bundle
155
+
156
+ Verify the unit test pass:
157
+
158
+ bundle exec rake spec
159
+
160
+ Once those are passing you can run the plugin using `bundle exec`. For example, to view the help message run:
161
+
162
+ bundle exec knife rightscale --help
163
+
164
+ Happy hacking!
165
+
156
166
 
157
167
  ## FUTURE FEATURES
158
168
  * create action
@@ -163,11 +173,11 @@ to filter by partial name match use the ```--name``` option
163
173
  ** Private beta
164
174
  * display audit entry when server strands
165
175
  * ability to add server tags on create
166
- * server array create action
167
- * add timeout for operational
176
+ * server array create action
177
+ * add timeout for operational
168
178
  * credentials list action (waiting for new API release)
169
179
  * add VPC support to create action
170
-
180
+
171
181
 
172
182
  ## LICENSE:
173
183
 
@@ -176,7 +186,7 @@ Copyright:: Copyright (c) 2013 RightScale, Inc.
176
186
  License:: Apache License, Version 2.0
177
187
  See attribution notice in README.md
178
188
 
179
- This readme is modified from the knife-ec2 plugin project code
189
+ This readme is modified from the knife-ec2 plugin project code
180
190
  That project is located at https://github.com/opscode/knife-ec2
181
191
  Author:: Adam Jacob (<adam@opscode.com>)
182
192
  Copyright:: Copyright (c) 2009-2011 Opscode, Inc.
data/Rakefile CHANGED
@@ -1,5 +1,3 @@
1
- require "bundler/gem_tasks"
2
-
3
1
  #
4
2
  # Author:: Cary Penniman (<cary@rightscale.com>)
5
3
  # Copyright:: Copyright (c) 2013 RightScale, Inc.
@@ -17,6 +15,20 @@ require "bundler/gem_tasks"
17
15
  # See the License for the specific language governing permissions and
18
16
  # limitations under the License.
19
17
  #
18
+ require "bundler/gem_tasks"
19
+ require "rdoc/task"
20
+ require "yard"
21
+
22
+ YARD::Rake::YardocTask.new do |t|
23
+ t.files = ['lib/**/*.rb']
24
+ end
25
+
26
+ Rake::RDocTask.new(:rdoc) do |rd|
27
+ rd.main = "README.doc"
28
+ rd.rdoc_files.include("README.md", "lib/**/*.rb")
29
+ rd.options << "--all"
30
+ end
31
+
20
32
  require 'rspec/core/rake_task'
21
33
 
22
34
  desc "Run all specs in spec directory"
@@ -33,7 +33,11 @@ Gem::Specification.new do |gem|
33
33
  gem.files = `git ls-files`.split($/)
34
34
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
35
35
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
36
- gem.add_dependency "right_api_client", "~> 1.5"
36
+ gem.add_dependency "right_api_helper", ">= 1.1.2"
37
+ gem.add_dependency "rake"
38
+ gem.add_dependency "yard"
39
+ gem.add_dependency "rspec"
40
+ gem.add_dependency "chef"
37
41
 
38
42
  gem.require_paths = ["lib"]
39
43
  end
@@ -3,7 +3,7 @@
3
3
  # Copyright:: Copyright (c) 2013 RightScale, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
- # This file is modified from the knife-ec2 plugin project code
6
+ # This file is modified from the knife-ec2 plugin project code
7
7
  # That project is located at https://github.com/opscode/knife-ec2
8
8
  # Author:: Seth Chisamore <schisamo@opscode.com>
9
9
  # Copyright:: Copyright (c) 2011 Opscode, Inc.
@@ -22,8 +22,7 @@
22
22
  # limitations under the License.
23
23
  #
24
24
  require 'chef/knife'
25
- require 'right_api_provision/provisioner'
26
- require 'right_api_provision/api15'
25
+ require 'right_api_helper'
27
26
 
28
27
  class Chef
29
28
  class Knife
@@ -36,7 +35,7 @@ class Chef
36
35
  includer.class_eval do
37
36
 
38
37
  deps do
39
- require 'right_api_client'
38
+ require 'right_api_helper'
40
39
  end
41
40
 
42
41
  option :rightscale_user,
@@ -69,17 +68,31 @@ class Chef
69
68
 
70
69
  def connection
71
70
  @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
71
+ api_shim = RightApiHelper::API15.new(right_api_client)
72
+ set_log_level(api_shim)
73
+ api_shim
80
74
  end
81
75
  end
82
76
 
77
+ def right_api_client
78
+ @right_api_client ||= begin
79
+ session = RightApiHelper::Session.new
80
+ set_log_level(session)
81
+ right_api_client = session.create_client(
82
+ Chef::Config[:knife][:rightscale_user],
83
+ Chef::Config[:knife][:rightscale_password],
84
+ Chef::Config[:knife][:rightscale_account_id],
85
+ Chef::Config[:knife][:rightscale_api_url]
86
+ )
87
+ right_api_client
88
+ end
89
+ end
90
+
91
+ def set_log_level(obj)
92
+ log_level = (config[:verbosity] >= 1) ? Logger::DEBUG : Logger::INFO
93
+ obj.log_level(log_level)
94
+ end
95
+
83
96
  def locate_config_value(key)
84
97
  key = key.to_sym
85
98
  config[key] || Chef::Config[:knife][key]
@@ -96,7 +109,7 @@ class Chef
96
109
 
97
110
  keys.each do |k|
98
111
  pretty_key = k.to_s.gsub(/_/, ' ').gsub(/\w+/){ |w| (w =~ /(ssh)|(aws)/i) ? w.upcase : w.capitalize }
99
- if Chef::Config[:knife][k].nil?
112
+ if Chef::Config[:knife][k].nil? && config[k].nil?
100
113
  errors << "You did not provide a valid '#{pretty_key}' value."
101
114
  end
102
115
  end
@@ -25,7 +25,7 @@ class Chef
25
25
  include Knife::RightscaleBase
26
26
 
27
27
  deps do
28
- require 'right_api_client'
28
+ require 'right_api_helper'
29
29
  require 'timeout'
30
30
  end
31
31
 
@@ -25,7 +25,7 @@ class Chef
25
25
  include Knife::RightscaleBase
26
26
 
27
27
  deps do
28
- require 'right_api_client'
28
+ require 'right_api_helper'
29
29
  end
30
30
 
31
31
  option :deployment_name,
@@ -25,7 +25,7 @@ class Chef
25
25
  include Knife::RightscaleBase
26
26
 
27
27
  deps do
28
- require 'right_api_client'
28
+ require 'right_api_helper'
29
29
  end
30
30
 
31
31
  option :server_template,
@@ -25,15 +25,15 @@ class Chef
25
25
  include Knife::RightscaleBase
26
26
 
27
27
  deps do
28
- require 'right_api_client'
28
+ require 'right_api_helper'
29
29
  end
30
-
30
+
31
31
  option :security_group_name,
32
32
  :short => "-n SECURITYGROUP_NAME",
33
33
  :long => "--name SECURITYGROUP_NAME",
34
34
  :description => "The partial name of the security group to search for",
35
35
  :proc => Proc.new { |i| Chef::Config[:knife][:security_group_name] = i }
36
-
36
+
37
37
  option :cloud_name,
38
38
  :short => "-C CLOUD_NAME",
39
39
  :long => "--cloud CLOUD_NAME",
@@ -54,9 +54,10 @@ class Chef
54
54
  ui.color('Name', :bold),
55
55
  ui.color('Resource UID', :bold)
56
56
  ].flatten.compact
57
-
57
+
58
58
  output_column_count = security_group_list.length
59
59
  @clouds.each do |cloud|
60
+ next unless connection.requires_security_groups?(cloud)
60
61
  @security_groups = connection.list_security_groups(cloud, :by_name, config[:security_group_name])
61
62
  @security_groups.each do |security_group|
62
63
  security_group_list << cloud.name
@@ -66,13 +67,13 @@ class Chef
66
67
  end
67
68
  puts ui.list(security_group_list, :uneven_columns_across, output_column_count)
68
69
  end
69
-
70
+
70
71
  private
71
72
 
72
73
  def validate!
73
74
  super([:rightscale_user, :rightscale_password, :rightscale_account_id])
74
75
  end
75
-
76
+
76
77
  end
77
78
  end
78
79
  end
@@ -3,7 +3,7 @@
3
3
  # Copyright:: Copyright (c) 2013 RightScale, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
- # This file is modified from the knife-ec2 plugin project code
6
+ # This file is modified from the knife-ec2 plugin project code
7
7
  # That project is located at https://github.com/opscode/knife-ec2
8
8
  # Author:: Adam Jacob (<adam@opscode.com>)
9
9
  # Author:: Seth Chisamore (<schisamo@opscode.com>)
@@ -32,7 +32,7 @@ class Chef
32
32
  include Knife::RightscaleBase
33
33
 
34
34
  deps do
35
- require 'right_api_client'
35
+ require 'right_api_helper'
36
36
  end
37
37
 
38
38
  banner "knife rightscale server create (options)"
@@ -50,8 +50,7 @@ class Chef
50
50
  :short => "-s NAME",
51
51
  :long => "--server-template NAME",
52
52
  :description => "The name of the ServerTemplate or ID to use for the server",
53
- :proc => Proc.new { |i| Chef::Config[:knife][:server_template] = i },
54
- :required => true
53
+ :proc => Proc.new { |i| Chef::Config[:knife][:server_template] = i }
55
54
 
56
55
  option :server_name,
57
56
  :short => "-n SERVERNAME",
@@ -78,20 +77,20 @@ class Chef
78
77
  :long => "--input NAME:VALUE",
79
78
  :description => "An input name and value",
80
79
  :proc => lambda { |o| k,v=o.split(":",2); @@inputs[k]=v }
81
-
80
+
82
81
  option :ssh_key_name,
83
82
  :short => "-S KEY_UUID",
84
83
  :long => "--ssh-key KEY_UUID",
85
84
  :description => "The AWS SSH key resource UUIS",
86
85
  :proc => Proc.new { |key| Chef::Config[:knife][:ssh_key_uuid] = key }
87
-
86
+
88
87
  # Gets applied to chef/client/roles input of ServerTemplate, if it exists
89
88
  # option :run_list,
90
89
  # :short => "-r RUN_LIST",
91
90
  # :long => "--run-list RUN_LIST",
92
91
  # :description => "Comma separated list of roles/recipes to apply.",
93
92
  # :proc => lambda { |o| o.split(/[\s,]+/) }
94
- #
93
+ #
95
94
  # option :json_attributes,
96
95
  # :short => "-j JSON",
97
96
  # :long => "--json-attributes JSON",
@@ -102,7 +101,7 @@ class Chef
102
101
  # :long => "--bootstrap-version VERSION",
103
102
  # :description => "The version of Chef to install",
104
103
  # :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
105
- #
104
+ #
106
105
  # option :chef_node_name,
107
106
  # :short => "-N NAME",
108
107
  # :long => "--node-name NAME",
@@ -114,19 +113,25 @@ class Chef
114
113
  # :long => "--flavor FLAVOR",
115
114
  # :description => "The flavor of server (m1.small, m1.medium, etc)",
116
115
  # :proc => Proc.new { |f| Chef::Config[:knife][:flavor] = f }
117
- #
116
+ #
118
117
  # option :image,
119
118
  # :short => "-I IMAGE",
120
119
  # :long => "--image IMAGE",
121
120
  # :description => "The AMI for the server",
122
121
  # :proc => Proc.new { |i| Chef::Config[:knife][:image] = i }
123
- #
122
+ #
124
123
  option :security_groups,
125
124
  :short => "-G X,Y,Z",
126
125
  :long => "--groups X,Y,Z",
127
126
  :description => "The security groups for this server; not allowed when using VPC",
128
127
  :proc => Proc.new { |groups| groups.split(',') }
129
128
 
129
+ option :wait_for_operational,
130
+ :long => "--[no-]block",
131
+ :description => "Exit after server launch -- don't wait for operational. (non-blocking)",
132
+ :boolean => true,
133
+ :default => true
134
+
130
135
  def run
131
136
  $stdout.sync = true
132
137
 
@@ -139,27 +144,34 @@ class Chef
139
144
  print "\n#{ui.color("Cloud:", :magenta)} #{config[:cloud_name]}"
140
145
  print "\n#{ui.color("Deployment name:", :magenta)} #{config[:deployment_name]}"
141
146
  print "\n#{ui.color("Inputs:", :magenta)} #{@@inputs}"
147
+ print "\n#{ui.color("Wait for Operational:", :magenta)} FALSE" if config[:no_wait]
142
148
  print "\n"
143
-
144
- rightscale = ::RightApiProvision::Provisioner.new(connection)
149
+
150
+ rightscale = get_rightscale_provisioner
145
151
  rightscale.provision(
146
- config[:server_template],
147
- config[:server_name],
148
- config[:cloud_name],
149
- config[:deployment_name],
150
- @@inputs,
151
- config[:ssh_key_name],
152
- config[:security_groups]
153
- )
154
-
152
+ config[:server_name],
153
+ config[:server_template],
154
+ config[:cloud_name],
155
+ config[:deployment_name],
156
+ @@inputs,
157
+ nil, # MCI not yet supported
158
+ config[:ssh_key_name],
159
+ config[:security_groups]
160
+ )
161
+
162
+ unless config[:wait_for_operational]
163
+ print "#{ui.color("Server launched -- exiting.", :green)}"
164
+ return
165
+ end
166
+
155
167
  if rightscale.server_ready?
156
168
  print "#{ui.color("Server already running", :green)}"
157
- else
169
+ elsif
158
170
  print "\n#{ui.color("Waiting for RightScale to configure server\n", :yellow)}"
159
171
  rightscale.wait_for_operational
160
172
  print "\n"
161
173
  end
162
-
174
+
163
175
  # output connection information
164
176
  print "#{ui.color("Querying server info...\n", :magenta)}"
165
177
  info = rightscale.server_info
@@ -172,6 +184,10 @@ class Chef
172
184
 
173
185
  private
174
186
 
187
+ def get_rightscale_provisioner
188
+ RightApiHelper::Provisioner.new(right_api_client)
189
+ end
190
+
175
191
  def validate!
176
192
  super([:cloud_name, :deployment_name, :server_template, :rightscale_user, :rightscale_password, :rightscale_account_id])
177
193
  end