knife-rightscale 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -1
- data/Gemfile +2 -0
- data/README.md +45 -35
- data/Rakefile +14 -2
- data/knife-rightscale.gemspec +5 -1
- data/lib/chef/knife/rightscale_base.rb +26 -13
- data/lib/chef/knife/rightscale_cloud_list.rb +1 -1
- data/lib/chef/knife/rightscale_deployment_list.rb +1 -1
- data/lib/chef/knife/rightscale_image_list.rb +1 -1
- data/lib/chef/knife/rightscale_securitygroup_list.rb +7 -6
- data/lib/chef/knife/rightscale_server_create.rb +39 -23
- data/lib/chef/knife/rightscale_server_list.rb +1 -1
- data/lib/chef/knife/rightscale_servertemplate_list.rb +1 -1
- data/lib/{right_api_provision/exception.rb → chef/knife/rightscale_version.rb} +16 -4
- data/lib/knife-rightscale.rb +1 -2
- data/lib/knife-rightscale/version.rb +1 -1
- data/spec/chef/knife/rightscale_server_create_spec.rb +22 -6
- data/test/create_server_test.rb +27 -23
- data/test/list_actions_test.rb +7 -7
- metadata +79 -16
- checksums.yaml +0 -15
- data/lib/right_api_provision/api15.rb +0 -372
- data/lib/right_api_provision/provisioner.rb +0 -139
- data/lib/right_api_provision/version.rb +0 -21
- data/spec/right_api_provision/api15_spec.rb +0 -203
@@ -1,139 +0,0 @@
|
|
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
|
-
module RightApiProvision
|
20
|
-
class Provisioner
|
21
|
-
|
22
|
-
BAD_STATES_UP = [ "stranded", "terminated"]
|
23
|
-
|
24
|
-
def initialize(rightscale_api_object)
|
25
|
-
raise "ERROR: you must supply an valid RightScale API object" unless rightscale_api_object
|
26
|
-
@rsapi = rightscale_api_object
|
27
|
-
end
|
28
|
-
|
29
|
-
def provision(servertemplate,
|
30
|
-
server_name = "default",
|
31
|
-
cloud_name = "ec2",
|
32
|
-
deployment_name = "default",
|
33
|
-
inputs = nil,
|
34
|
-
ssh_key_uuid = nil,
|
35
|
-
security_groups = nil)
|
36
|
-
|
37
|
-
# fail if the requested cloud is not registered with RightScale account
|
38
|
-
@cloud = @rsapi.find_cloud_by_name(cloud_name)
|
39
|
-
raise "ERROR: cannot find a cloud named: '#{cloud_name}'. " +
|
40
|
-
"Please check the spelling of the 'cloud_name' parameter " +
|
41
|
-
"and verify the cloud is registered with " +
|
42
|
-
"your RightScale account?" unless @cloud
|
43
|
-
|
44
|
-
# Verify ssh key uuid, if required by cloud
|
45
|
-
if @rsapi.requires_ssh_keys?(@cloud)
|
46
|
-
@ssh_key = @rsapi.find_ssh_key_by_uuid_or_first(@cloud, ssh_key_uuid)
|
47
|
-
raise "ERROR: cannot find an ssh_key named: #{ssh_key_uuid}" unless @ssh_key
|
48
|
-
end
|
49
|
-
|
50
|
-
# Verify security group, if required by cloud
|
51
|
-
if @rsapi.requires_security_groups?(@cloud)
|
52
|
-
@sec_groups = []
|
53
|
-
security_groups ||= ["default"]
|
54
|
-
security_groups.each do |name|
|
55
|
-
group = @rsapi.find_security_group_by_name(@cloud, name)
|
56
|
-
raise "ERROR: cannot find an security group named: #{name}" unless group
|
57
|
-
@sec_groups << group
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# check for existing deployment and server in RightScale account
|
62
|
-
@deployment = @rsapi.find_deployment_by_name(deployment_name)
|
63
|
-
puts "Deployment '#{deployment_name}' #{@deployment ? "found." : "not found."}"
|
64
|
-
@server = @rsapi.find_server_by_name(server_name) if @deployment
|
65
|
-
puts "Server '#{server_name}' #{@server ? "found." : "not found."}"
|
66
|
-
|
67
|
-
if @server
|
68
|
-
# verify existing server is on the cloud we are requesting, if not fail.
|
69
|
-
actual_cloud_name = @rsapi.server_cloud_name(@server)
|
70
|
-
raise "ERROR: the server is in the '#{actual_cloud_name}' cloud, " +
|
71
|
-
"and not in the requested '#{cloud_name}' cloud.\n" +
|
72
|
-
"Please delete the server or pick and new server name." if cloud_name != actual_cloud_name
|
73
|
-
end
|
74
|
-
|
75
|
-
unless @deployment && @server
|
76
|
-
# we need to create a server, can we find the servertemplate?
|
77
|
-
@servertemplate = @rsapi.find_servertemplate(servertemplate)
|
78
|
-
raise "ERROR: cannot find ServerTemplate '#{servertemplate}'. Did you import it?\n" +
|
79
|
-
"Visit http://bit.ly/VnOiA7 for more info.\n\n" unless @servertemplate
|
80
|
-
# can we find the MCI?
|
81
|
-
#TODO: @mci = @rsapi.find_multicloudimage_by_name(@servertemplate, config.multi_cloud_image_name)
|
82
|
-
end
|
83
|
-
|
84
|
-
# create deployment and server as needed
|
85
|
-
unless @deployment
|
86
|
-
@deployment = @rsapi.create_deployment(deployment_name)
|
87
|
-
puts "Created deployment."
|
88
|
-
end
|
89
|
-
|
90
|
-
unless @server
|
91
|
-
@server = @rsapi.create_server(@deployment, @servertemplate, @mci, @cloud, server_name, @ssh_key, @sec_groups)
|
92
|
-
puts "Created server."
|
93
|
-
end
|
94
|
-
|
95
|
-
unless @rsapi.is_provisioned?(@server)
|
96
|
-
|
97
|
-
# setup any inputs
|
98
|
-
@rsapi.set_server_inputs(@server, inputs) if inputs
|
99
|
-
|
100
|
-
# launch server
|
101
|
-
puts "Launching server..."
|
102
|
-
@server = @rsapi.launch_server(@server, inputs)
|
103
|
-
@rsapi.set_bad_states(BAD_STATES_UP)
|
104
|
-
@rsapi.server_wait_for_state(@server, "booting", 30)
|
105
|
-
end
|
106
|
-
|
107
|
-
# if cloud_name == VAGRANT_CLOUD_NAME
|
108
|
-
# # Vagrant box: grab "Data request URL" from UserData
|
109
|
-
# user_data = @server.current_instance.show(:view => "full").user_data
|
110
|
-
# puts user_data.inspect
|
111
|
-
# @data_request_url = @rsapi.data_request_url(user_data)
|
112
|
-
# puts "Data Request URL: #{@data_request_url}"
|
113
|
-
# else
|
114
|
-
# @rsapi.server_wait_for_state(server_name, "operational", 30)
|
115
|
-
# end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
|
-
def server_ready?
|
120
|
-
@rsapi.server_ready?(@server)
|
121
|
-
end
|
122
|
-
|
123
|
-
def wait_for_operational
|
124
|
-
@rsapi.set_bad_states(BAD_STATES_UP)
|
125
|
-
@rsapi.server_wait_for_state(@server, "operational", 30)
|
126
|
-
end
|
127
|
-
|
128
|
-
def server_info
|
129
|
-
info = @rsapi.server_info(@server)
|
130
|
-
while info.private_ip_addresses.empty?
|
131
|
-
puts "Waiting for cloud to provide IP address..."
|
132
|
-
sleep 30
|
133
|
-
info = @rsapi.server_info(@server)
|
134
|
-
end
|
135
|
-
info
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
end
|
@@ -1,21 +0,0 @@
|
|
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
|
-
module RightApiProvision
|
20
|
-
VERSION = "0.1.0"
|
21
|
-
end
|
@@ -1,203 +0,0 @@
|
|
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 "right_api_provision/api15"
|
20
|
-
|
21
|
-
describe "API15 object" do
|
22
|
-
|
23
|
-
before(:each) do
|
24
|
-
@api = RightApiProvision::API15.new()
|
25
|
-
apiStub = double("RightApi::Client")
|
26
|
-
RightApi::Client.should_receive(:new).and_return(apiStub)
|
27
|
-
@conn = @api.connection("someemail", "somepasswd", "someaccountid", "https://my.rightscale.com")
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "requires_ssh_keys?" do
|
31
|
-
it "should return true when cloud supports ssh keys" do
|
32
|
-
sshKeyStub = stub("sshkeys", :index => ["key1", "key2"])
|
33
|
-
|
34
|
-
cStub = stub("cloud", :ssh_keys => sshKeyStub)
|
35
|
-
csStub = stub("clouds", :show => cStub)
|
36
|
-
|
37
|
-
@api.requires_ssh_keys?(csStub).should == true
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should return false when cloud doesn't support ssh keys" do
|
41
|
-
cStub = stub("cloud", :ssh_keys => "will throw exception if no ssh keys")
|
42
|
-
cStub.should_receive(:ssh_keys).and_raise(RightApi::Exceptions::ApiException.new "error")
|
43
|
-
csStub = stub("clouds", :show => cStub)
|
44
|
-
|
45
|
-
@api.requires_ssh_keys?(csStub).should == false
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "find_ssh_key_by_uuid_or_first" do
|
50
|
-
it "should find first ssh_key" do
|
51
|
-
sshKeyStub = stub("sshkeys", :index => ["key1", "key2"])
|
52
|
-
|
53
|
-
cStub = stub("cloud", :ssh_keys => sshKeyStub)
|
54
|
-
csStub = stub("clouds", :show => cStub)
|
55
|
-
|
56
|
-
@api.find_ssh_key_by_uuid_or_first(csStub).should == "key1"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should find deployment by name" do
|
61
|
-
deploymentsStub = stub("deployments", :index => [ :name => "my_fake_deployment" ])
|
62
|
-
@api.instance_variable_get("@connection").should_receive(:deployments).and_return(deploymentsStub)
|
63
|
-
@api.find_deployment_by_name("my_fake_deployment")
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should raise error if deployment not found by name" do
|
67
|
-
deploymentsStub = stub("deployments", :index => nil)
|
68
|
-
@api.instance_variable_get("@connection").should_receive(:deployments).and_return(deploymentsStub)
|
69
|
-
lambda{@api.find_deployment_by_name("my_fake_deployment")}.should raise_error
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should raise error if multiple deployments found by name" do
|
73
|
-
deploymentsStub = stub("deployments", :index => [ {:name => "my_fake_deployment"}, {:name => "my_fake_deployment2"} ])
|
74
|
-
@api.instance_variable_get("@connection").should_receive(:deployments).and_return(deploymentsStub)
|
75
|
-
lambda{@api.find_deployment_by_name("my_fake_deployment")}.should raise_error
|
76
|
-
end
|
77
|
-
|
78
|
-
it "should find server by name" do
|
79
|
-
serversStub = stub("servers", :index => [ :name => "my_fake_server" ])
|
80
|
-
@api.instance_variable_get("@connection").should_receive(:servers).and_return(serversStub)
|
81
|
-
@api.find_server_by_name("my_fake_server")
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should raise error if multiple servers found by name" do
|
85
|
-
serversStub = stub("servers", :index => [ {:name => "my_fake_server"}, {:name => "my_fake_server2"} ])
|
86
|
-
@api.instance_variable_get("@connection").should_receive(:servers).and_return(serversStub)
|
87
|
-
lambda{@api.find_server_by_name("my_fake_server")}.should raise_error
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should find MCI by name" do
|
91
|
-
pending ("TODO: add support for multi_cloud_image_name")
|
92
|
-
mcisStub = stub("mcis", :index => [ :name => "my_fake_mci" ])
|
93
|
-
@api.instance_variable_get("@connection").should_receive(:mcis).and_return(mcisStub)
|
94
|
-
@api.find_mci_by_name("my_fake_mci")
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should raise error if multiple MCI found by name" do
|
98
|
-
pending ("TODO: add support for multi_cloud_image_name")
|
99
|
-
mcisStub = stub("mcis", :index => [ {:name => "my_fake_mci"}, {:name => "my_fake_mci2"} ])
|
100
|
-
@api.instance_variable_get("@connection").should_receive(:mcis).and_return(mcisStub)
|
101
|
-
lambda{@api.find_mci_by_name("my_fake_mci")}.should raise_error
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should find servertemplate by name" do
|
105
|
-
servertemplatesStub = stub("servertemplates", :index => [ stub("servertemplate", :name => "my_fake_servertemplate", :revision => true) ])
|
106
|
-
@api.instance_variable_get("@connection").should_receive(:server_templates).and_return(servertemplatesStub)
|
107
|
-
@api.find_servertemplate("my_fake_servertemplate")
|
108
|
-
end
|
109
|
-
|
110
|
-
it "should raise error if multiple servertemplates found by name" do
|
111
|
-
servertemplatesStub = stub("servertemplates", :index => [ stub("servertemplate", :name => "my_fake_servertemplate"), stub("servertemplate", :name => "my_fake_servertemplate") ])
|
112
|
-
@api.instance_variable_get("@connection").should_receive(:server_templates).and_return(servertemplatesStub)
|
113
|
-
lambda{@api.find_servertemplate("my_fake_servertemplate")}.should raise_error
|
114
|
-
end
|
115
|
-
|
116
|
-
it "should find servertemplate by id" do
|
117
|
-
servertemplatesStub = stub("servertemplates", :index => [ :name => "my_fake_servertemplate" ])
|
118
|
-
@api.instance_variable_get("@connection").should_receive(:server_templates).and_return(servertemplatesStub)
|
119
|
-
@api.find_servertemplate(1234)
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should create deployment" do
|
123
|
-
deploymentsStub = stub("deployments", :create => [ {:name => "my_fake_deployment"} ])
|
124
|
-
@api.instance_variable_get("@connection").should_receive(:deployments).and_return(deploymentsStub)
|
125
|
-
deploymentsStub.should_receive(:create)
|
126
|
-
@api.create_deployment("my_deployment")
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should create server" do
|
130
|
-
dStub = stub("deployment", :href => "/some/fake/path")
|
131
|
-
dsStub = stub("deployments", :show => dStub)
|
132
|
-
@api.should_receive(:create_deployment).and_return(dsStub)
|
133
|
-
deployment = @api.create_deployment("my_deployment")
|
134
|
-
|
135
|
-
stStub = stub("servertemplate", :href => "/some/fake/path", :show => "")
|
136
|
-
stsStub = stub("servertemplates", :show => stStub)
|
137
|
-
@api.should_receive(:find_servertemplate).and_return(stsStub)
|
138
|
-
server_template = @api.find_servertemplate(1234)
|
139
|
-
|
140
|
-
cStub = stub("cloud", :href => "/some/fake/path")
|
141
|
-
csStub = stub("clouds", :show => cStub)
|
142
|
-
@api.should_receive(:find_cloud_by_name).and_return(csStub)
|
143
|
-
cloud = @api.find_cloud_by_name(1234)
|
144
|
-
|
145
|
-
serversStub = stub("servers", :create => [ :name => "my_fake_server" ])
|
146
|
-
@api.instance_variable_get("@connection").should_receive(:servers).and_return(serversStub)
|
147
|
-
@api.create_server(deployment, server_template, nil, cloud, "my_fake_server", nil)
|
148
|
-
end
|
149
|
-
|
150
|
-
it "should launch server with inputs" do
|
151
|
-
serverStub = stub("server", :name => "foo")
|
152
|
-
serversStub = stub("servers", :launch => true, :show => serverStub, :index => [ :name => "my_fake_server" ])
|
153
|
-
@api.should_receive(:create_server).and_return(serversStub)
|
154
|
-
server = @api.create_server("foo", "bar", "my_fake_server")
|
155
|
-
@api.instance_variable_get("@connection").should_receive(:servers).and_return(serversStub)
|
156
|
-
@api.launch_server(server, [ {:name => "input1", :value => 1} ])
|
157
|
-
end
|
158
|
-
|
159
|
-
it "should launch server without inputs" do
|
160
|
-
serverStub = stub("server", :name => "foo")
|
161
|
-
serversStub = stub("servers", :launch => true, :show => serverStub, :index => [ :name => "my_fake_server" ])
|
162
|
-
@api.should_receive(:create_server).and_return(serversStub)
|
163
|
-
server = @api.create_server("foo", "bar", "my_fake_server")
|
164
|
-
@api.instance_variable_get("@connection").should_receive(:servers).and_return(serversStub)
|
165
|
-
@api.launch_server(server)
|
166
|
-
end
|
167
|
-
|
168
|
-
it "returns data_request_url for instance" do
|
169
|
-
@user_data = "RS_rn_url=amqp://b915586461:278a854748@orange2-broker.test.rightscale.com/right_net&RS_rn_id=4985249009&RS_server=orange2-moo.test.rightscale.com&RS_rn_auth=d98106775832c174ffd55bd7b7cb175077574adf&RS_token=b233a57d1d24f27bd8650d0f9b6bfd54&RS_sketchy=sketchy1-145.rightscale.com&RS_rn_host=:0"
|
170
|
-
@request_data_url = "https://my.rightscale.com/servers/data_injection_payload/d98106775832c174ffd55bd7b7cb175077574adf"
|
171
|
-
|
172
|
-
@api.data_request_url(@user_data).should == @request_data_url
|
173
|
-
end
|
174
|
-
|
175
|
-
pending "waits for state to change from booting state" do
|
176
|
-
currentStub = stub("instance", :state => "booting")
|
177
|
-
instanceStub = stub("instance", :show => currentStub)
|
178
|
-
serverStub = stub("server", :api_methods => [:current_instance], :current_instance => instanceStub)
|
179
|
-
serversStub = stub("servers", :launch => true, :show => serverStub, :index => [ :name => "my_fake_server" ])
|
180
|
-
|
181
|
-
@api.server_wait_for_state(@server, "booting", 1)
|
182
|
-
end
|
183
|
-
|
184
|
-
it "fails if the server's cloud is not the requested cloud" do
|
185
|
-
pending "TODO"
|
186
|
-
end
|
187
|
-
|
188
|
-
it "sets inputs on the next instance" do
|
189
|
-
pending "TODO"
|
190
|
-
end
|
191
|
-
|
192
|
-
it "terminates a server" do
|
193
|
-
pending "TODO"
|
194
|
-
serverStub = stub("server", :name => "foo")
|
195
|
-
# serversStub = stub("servers", :launch => true, :show => serverStub, :index => [ :name => "my_fake_server" ])
|
196
|
-
# @api.should_receive(:create_server).and_return(serversStub)
|
197
|
-
# server = @api.create_server("foo", "bar", "my_fake_server")
|
198
|
-
# @api.instance_variable_get("@connection").should_receive(:servers).and_return(serversStub)
|
199
|
-
@api.terminate_server(serverStub)
|
200
|
-
end
|
201
|
-
|
202
|
-
|
203
|
-
end
|