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 +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
@@ -16,8 +16,20 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
require 'chef/knife/rightscale_base'
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Knife
|
23
|
+
class RightscaleVersion < Knife
|
24
|
+
|
25
|
+
include Knife::RightscaleBase
|
26
|
+
|
27
|
+
banner "knife rightscale version"
|
28
|
+
|
29
|
+
def run
|
30
|
+
print "#{::Knife::Rightscale::VERSION}\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
22
34
|
end
|
23
|
-
end
|
35
|
+
end
|
data/lib/knife-rightscale.rb
CHANGED
@@ -18,15 +18,31 @@
|
|
18
18
|
|
19
19
|
require File.expand_path('../../../spec_helper', __FILE__)
|
20
20
|
|
21
|
-
|
22
|
-
before do
|
21
|
+
Chef::Knife::RightscaleServerCreate.load_deps
|
23
22
|
|
23
|
+
describe Chef::Knife::RightscaleServerCreate do
|
24
|
+
before(:each) do
|
25
|
+
Chef::Config[:node_name] = "webmonkey.example.com"
|
26
|
+
@knife = Chef::Knife::RightscaleServerCreate.new
|
27
|
+
@stdout = StringIO.new
|
28
|
+
@knife.stub(:stdout).and_return(@stdout)
|
29
|
+
provisionerStub = double("provisioner")
|
30
|
+
provisionerStub.stub(:provision)
|
31
|
+
@knife.stub(:get_rightscale_provisioner).and_return(provisionerStub)
|
24
32
|
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
34
|
+
it "provisions server" do
|
35
|
+
@knife.config = {
|
36
|
+
:server_template => "my servertemplate",
|
37
|
+
:deployment_name => 'my deployment',
|
38
|
+
:server_name => 'my server',
|
39
|
+
:cloud_name => "my favorite cloud",
|
40
|
+
:rightscale_user => "someuser",
|
41
|
+
:rightscale_password => "somepassword",
|
42
|
+
:rightscale_account_id => "1234"
|
43
|
+
}
|
44
|
+
@knife.run
|
30
45
|
end
|
31
46
|
|
47
|
+
|
32
48
|
end
|
data/test/create_server_test.rb
CHANGED
@@ -27,32 +27,36 @@ describe "provision a ChefClient on each cloud" do
|
|
27
27
|
|
28
28
|
[
|
29
29
|
"EC2 us-west-2",
|
30
|
-
"CS 2.2.14 Eng - XenServer",
|
31
30
|
"Google",
|
32
|
-
"
|
33
|
-
"
|
31
|
+
"Openstack Havana",
|
32
|
+
"VScale Engineering v5.5"
|
34
33
|
].each do |cloud_name|
|
35
|
-
|
34
|
+
|
36
35
|
it "can provision on '#{cloud_name}'" do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
begin
|
48
|
-
run "knife rightscale server delete 'KNIFE:ChefClient #{cloud_name}'"
|
49
|
-
ensure
|
50
|
-
run "knife client delete MyChefClient"
|
51
|
-
run "knife node delete MyChefClient"
|
52
|
-
end
|
53
|
-
end
|
36
|
+
|
37
|
+
run "knife rightscale server create --cloud '#{cloud_name}' " +
|
38
|
+
"--server-template 328222001 --deployment 'KNIFE: test knife-provisioner' " +
|
39
|
+
"--name 'KNIFE:ChefClient #{cloud_name}' " +
|
40
|
+
"--no-block " +
|
41
|
+
"--input 'chef/client/server_url':'text:https://api.opscode.com/organizations/kindsol' " +
|
42
|
+
"--input 'chef/client/validation_name':'cred:CKP: validation_client_name' " +
|
43
|
+
"--input 'chef/client/validator_pem':'cred:CKP:validator.pem' " +
|
44
|
+
"--input 'chef/client/node_name':'text:MyChefClient' " +
|
45
|
+
"--input 'chef/client/roles':'text:hello_world' "
|
54
46
|
end
|
55
|
-
|
56
47
|
end
|
57
|
-
|
48
|
+
|
49
|
+
it "can delete server on '{cloud_name}'" do
|
50
|
+
# wait for all servers (fail or pass)
|
51
|
+
|
52
|
+
# - begin
|
53
|
+
# - run "knife rightscale server delete 'KNIFE:ChefClient #{cloud_name}'"
|
54
|
+
# - ensure
|
55
|
+
# - run "knife client delete MyChefClient"
|
56
|
+
# - run "knife node delete MyChefClient"
|
57
|
+
# - end
|
58
|
+
end
|
59
|
+
|
58
60
|
end
|
61
|
+
|
62
|
+
|
data/test/list_actions_test.rb
CHANGED
@@ -27,25 +27,25 @@ describe "run list actions" do
|
|
27
27
|
it "lists security groups" do
|
28
28
|
run_list_command("securitygroup")
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
it "lists clouds" do
|
32
32
|
run_list_command("cloud")
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it "lists deployments" do
|
36
36
|
run_list_command("deployment")
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
it "lists servers" do
|
40
40
|
run_list_command("server")
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "lists servertemplate" do
|
44
44
|
run_list_command("servertemplate")
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "lists images" do
|
48
|
-
run_list_command("image", "-s
|
48
|
+
run_list_command("image", "-s 328222001 --cloud 'EC2 us-west-2'")
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
end
|
metadata
CHANGED
@@ -1,29 +1,96 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-rightscale
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Cary Penniman
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: right_api_helper
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
21
|
+
version: 1.1.2
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
29
|
+
version: 1.1.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yard
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: chef
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
27
94
|
description: One plugin to provision them all! This plugin allows the Chef developer
|
28
95
|
to provision Chef clients on all major clouds using the RightScale platform.
|
29
96
|
email:
|
@@ -50,43 +117,39 @@ files:
|
|
50
117
|
- lib/chef/knife/rightscale_server_delete.rb
|
51
118
|
- lib/chef/knife/rightscale_server_list.rb
|
52
119
|
- lib/chef/knife/rightscale_servertemplate_list.rb
|
120
|
+
- lib/chef/knife/rightscale_version.rb
|
53
121
|
- lib/knife-rightscale.rb
|
54
122
|
- lib/knife-rightscale/version.rb
|
55
|
-
- lib/right_api_provision/api15.rb
|
56
|
-
- lib/right_api_provision/exception.rb
|
57
|
-
- lib/right_api_provision/provisioner.rb
|
58
|
-
- lib/right_api_provision/version.rb
|
59
123
|
- spec/chef/knife/rightscale_server_create_spec.rb
|
60
|
-
- spec/right_api_provision/api15_spec.rb
|
61
124
|
- spec/spec_helper.rb
|
62
125
|
- test/create_server_test.rb
|
63
126
|
- test/list_actions_test.rb
|
64
127
|
homepage: http://github.com/caryp/knife-rightscale
|
65
128
|
licenses: []
|
66
|
-
metadata: {}
|
67
129
|
post_install_message:
|
68
130
|
rdoc_options: []
|
69
131
|
require_paths:
|
70
132
|
- lib
|
71
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
72
135
|
requirements:
|
73
136
|
- - ! '>='
|
74
137
|
- !ruby/object:Gem::Version
|
75
138
|
version: '0'
|
76
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
77
141
|
requirements:
|
78
142
|
- - ! '>='
|
79
143
|
- !ruby/object:Gem::Version
|
80
144
|
version: '0'
|
81
145
|
requirements: []
|
82
146
|
rubyforge_project:
|
83
|
-
rubygems_version:
|
147
|
+
rubygems_version: 1.8.23
|
84
148
|
signing_key:
|
85
|
-
specification_version:
|
149
|
+
specification_version: 3
|
86
150
|
summary: RightScale plugin for Knife
|
87
151
|
test_files:
|
88
152
|
- spec/chef/knife/rightscale_server_create_spec.rb
|
89
|
-
- spec/right_api_provision/api15_spec.rb
|
90
153
|
- spec/spec_helper.rb
|
91
154
|
- test/create_server_test.rb
|
92
155
|
- test/list_actions_test.rb
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
ZDYyOGVjYjEyNmY5ODBkOGM1NzM1OThkMTc0ZTNjN2YyZGM5YmVhZg==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
Mzg3YTRiODM5Y2EzNWFhZmVlMGYzMDdjMzcxMmY5MDkxODk2ZGE2Yg==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
OTFiOTcwOWFiNGFmNTY5OTJjNjBhNjY3NjE2NDk5NWMzNDE0YjFhMmQ3ZTUz
|
10
|
-
ODZhZGQ0MjJkZmEwZTlkZWNlYWFlNzgyZWQxNGFiYTgyYmU5YzQzNjMwZTkw
|
11
|
-
NTdlYTEwZjFjZGFlZmEzZjY4OTc0NWU0OTZlYzUzMzE1YWM2Zjk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzkzMGYxZjFlMWFhMDA3ZjM1Nzg1ZmZlMWRhYThhZjFmZjM4MDU0ZGIzZDgz
|
14
|
-
OWM4MzI4NTNmMjEzNDYxMjA0ODE5NWM2ZGM4ZjQ2YzEwYmI3NzAyMjNiMTE1
|
15
|
-
ZjFjZWNmMmQ1NGE4ZWFkNzQxOWZmNzg3Y2U2MDQ0N2JlMjY2NmE=
|
@@ -1,372 +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 API15
|
21
|
-
|
22
|
-
attr_reader :client
|
23
|
-
|
24
|
-
def initialize
|
25
|
-
require "right_api_client"
|
26
|
-
end
|
27
|
-
|
28
|
-
def connection(email, password, account_id, api_url = nil)
|
29
|
-
begin
|
30
|
-
args = { :email => email, :password => password, :account_id => account_id }
|
31
|
-
@url = api_url
|
32
|
-
args[:api_url] = @url if @url
|
33
|
-
@connection ||= RightApi::Client.new(args)
|
34
|
-
#@logger = Logger.new(STDOUT)
|
35
|
-
#@logger.level = Logger::DEBUG
|
36
|
-
#@connection.log(@logger)
|
37
|
-
@client = @connection
|
38
|
-
rescue Exception => e
|
39
|
-
args.delete(:password) # don't log password
|
40
|
-
puts "ERROR: could not connect to RightScale API. Params: #{args.inspect}"
|
41
|
-
puts e.message
|
42
|
-
puts e.backtrace
|
43
|
-
raise e
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# If the cloud reports ssh keys, then we assume it requires them to launch
|
48
|
-
# servers.
|
49
|
-
def requires_ssh_keys?(cloud)
|
50
|
-
begin
|
51
|
-
cloud.show.ssh_keys
|
52
|
-
true
|
53
|
-
rescue RightApi::Exceptions::ApiException => e
|
54
|
-
false # assume cloud does not require them
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Find SSH key
|
59
|
-
#
|
60
|
-
# EC2 and Eucalyptus require an SSH key to launch a server. RightScale
|
61
|
-
# manages SSH keys for each user so just grabbing the first one is fine,
|
62
|
-
# however older configurations might relay on specific keys. You will
|
63
|
-
# need to grab the resource UUID from the RightScale dashboard for the key
|
64
|
-
# that you want to use.
|
65
|
-
def find_ssh_key_by_uuid_or_first(cloud, ssh_uuid = nil)
|
66
|
-
ssh_key = nil
|
67
|
-
if ssh_uuid
|
68
|
-
# grab specific ssh key
|
69
|
-
sshkey = find_resource(:ssh_keys, :by_resource_uid, uuid)
|
70
|
-
else
|
71
|
-
# grab first key found
|
72
|
-
keys = cloud.show.ssh_keys
|
73
|
-
ssh_key = keys.index.first if keys
|
74
|
-
end
|
75
|
-
ssh_key
|
76
|
-
end
|
77
|
-
|
78
|
-
# If the cloud reports security groups then we assume it requires them to launch
|
79
|
-
# servers.
|
80
|
-
def requires_security_groups?(cloud)
|
81
|
-
begin
|
82
|
-
cloud.show.security_groups
|
83
|
-
true
|
84
|
-
rescue RightApi::Exceptions::ApiException => e
|
85
|
-
false # assume cloud does not require them
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def user_data
|
90
|
-
@user_data ||= @server.show.current_instance(:view=>"extended").show.user_data
|
91
|
-
end
|
92
|
-
|
93
|
-
def data_request_url(userdata)
|
94
|
-
data_hash = {}
|
95
|
-
entry = userdata.split('&').select { |entry| entry =~ /RS_rn_auth/i }
|
96
|
-
raise "ERROR: user data token not found. " +
|
97
|
-
"Does your MCI have a provides:rs_agent_type=right_link tag?" unless entry
|
98
|
-
token = entry.first.split('=')[1]
|
99
|
-
"#{@url}/servers/data_injection_payload/#{token}"
|
100
|
-
end
|
101
|
-
|
102
|
-
def delete_server(name)
|
103
|
-
server = find_server_by_name(name)
|
104
|
-
server.terminate
|
105
|
-
begin
|
106
|
-
server_wait_for_state(server, "terminated")
|
107
|
-
rescue Exception => e
|
108
|
-
|
109
|
-
end
|
110
|
-
server.destroy
|
111
|
-
end
|
112
|
-
|
113
|
-
def list_servers(filter_by, filter_value)
|
114
|
-
list_resources(:servers, filter_by, filter_value)
|
115
|
-
end
|
116
|
-
|
117
|
-
def list_deployments(filter_by, filter_value)
|
118
|
-
list_resources(:deployments, filter_by, filter_value)
|
119
|
-
end
|
120
|
-
|
121
|
-
def list_clouds(filter_by, filter_value)
|
122
|
-
list_resources(:clouds, filter_by, filter_value)
|
123
|
-
end
|
124
|
-
|
125
|
-
def list_servertemplates(filter_by, filter_value)
|
126
|
-
list_resources(:server_templates, filter_by, filter_value)
|
127
|
-
end
|
128
|
-
|
129
|
-
def list_security_groups(cloud, filter_by, filter_value)
|
130
|
-
list_subresources(cloud, :security_groups, filter_by, filter_value)
|
131
|
-
end
|
132
|
-
|
133
|
-
def list_multi_cloud_images(server_template, filter_by, filter_value)
|
134
|
-
list_subresources(server_template, :multi_cloud_images, filter_by, filter_value)
|
135
|
-
end
|
136
|
-
|
137
|
-
def find_security_group_by_name(cloud, security_group_name)
|
138
|
-
find_cloud_resource(cloud, :security_groups, :by_name, security_group_name)
|
139
|
-
end
|
140
|
-
|
141
|
-
def find_server_by_name(name)
|
142
|
-
find_resource(:servers, :by_name, name)
|
143
|
-
end
|
144
|
-
|
145
|
-
def find_deployment_by_name(name)
|
146
|
-
find_resource(:deployments, :by_name, name)
|
147
|
-
end
|
148
|
-
|
149
|
-
# returns:: String if cloud is found, nil if not found
|
150
|
-
def find_cloud_by_name(name)
|
151
|
-
find_resource(:clouds, :by_name, name)
|
152
|
-
end
|
153
|
-
|
154
|
-
def find_mci_by_name(server_template, mci_name)
|
155
|
-
find_resource(:mcis, :by_name, name)
|
156
|
-
end
|
157
|
-
|
158
|
-
def find_servertemplate(name_or_id)
|
159
|
-
server_template = nil; id = nil; name = nil
|
160
|
-
|
161
|
-
# detect if user passed in a name or an id
|
162
|
-
# there is probably a cleaner way to do this, but I am lazy ATM.
|
163
|
-
begin
|
164
|
-
id = Integer(name_or_id)
|
165
|
-
rescue Exception => e
|
166
|
-
name = name_or_id # Cannot be case to integer, assume a name was passed
|
167
|
-
end
|
168
|
-
|
169
|
-
if name
|
170
|
-
# find ServerTemplate by name
|
171
|
-
st_list = list_resources(:server_templates, :by_name, name)
|
172
|
-
revisions = st_list.map { |st| st.revision }
|
173
|
-
|
174
|
-
# check for duplicate revisions
|
175
|
-
duplicates = (revisions.size != revisions.uniq.size)
|
176
|
-
raise "ERROR: Duplicate ServerTemplate with the name of '#{name}' detected " +
|
177
|
-
"in account -- there can be only one. Please fix via the RightScale dashboard and retry." if duplicates
|
178
|
-
|
179
|
-
# always use latest revision
|
180
|
-
latest_rev = revisions.sort.last
|
181
|
-
server_template = st_list.select { |st| st.revision == latest_rev}.first
|
182
|
-
else
|
183
|
-
# find ServerTemplate by id
|
184
|
-
server_template = @connection.server_templates.index(:id => id)
|
185
|
-
end
|
186
|
-
|
187
|
-
server_template
|
188
|
-
end
|
189
|
-
|
190
|
-
def create_deployment(name)
|
191
|
-
@connection.deployments.create(:deployment => { :name => name, :decription => "Created by the Vagrant"})
|
192
|
-
end
|
193
|
-
|
194
|
-
def destroy_deployment(deployment)
|
195
|
-
deployment.destroy
|
196
|
-
end
|
197
|
-
|
198
|
-
def create_server(deployment, server_template, mci, cloud, name, ssh_key = nil, groups = nil)
|
199
|
-
|
200
|
-
#TODO: mci param not used yet
|
201
|
-
|
202
|
-
# check params
|
203
|
-
unless st_href = server_template.show.href
|
204
|
-
raise "ERROR: ServerTemplate parameter not initialized properly"
|
205
|
-
end
|
206
|
-
|
207
|
-
unless d_href = deployment.show.href
|
208
|
-
raise "ERROR: Deployment parameter not initialized properly"
|
209
|
-
end
|
210
|
-
|
211
|
-
unless c_href = cloud.show.href
|
212
|
-
raise "ERROR: Deployment parameter not initialized properly"
|
213
|
-
end
|
214
|
-
|
215
|
-
if ssh_key
|
216
|
-
unless ssh_key_href = ssh_key.show.href
|
217
|
-
raise "ERROR: ssh_key parameter not initialized properly"
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
security_group_hrefs = nil
|
222
|
-
if groups
|
223
|
-
security_group_hrefs = []
|
224
|
-
groups.each do |group|
|
225
|
-
unless group_href = group.show.href
|
226
|
-
raise "ERROR: ssh_key parameter not initialized properly"
|
227
|
-
end
|
228
|
-
security_group_hrefs << group_href
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
instance_hash = {
|
233
|
-
:cloud_href => c_href,
|
234
|
-
:server_template_href => st_href
|
235
|
-
}
|
236
|
-
instance_hash[:ssh_key_href] = ssh_key_href if ssh_key
|
237
|
-
instance_hash[:security_group_hrefs] = security_group_hrefs if security_group_hrefs
|
238
|
-
|
239
|
-
|
240
|
-
# create server in deployment using specfied ST
|
241
|
-
server =
|
242
|
-
@connection.servers.create({
|
243
|
-
:server => {
|
244
|
-
:name => name,
|
245
|
-
:decription => "Created by the Vagrant",
|
246
|
-
:deployment_href => d_href,
|
247
|
-
:instance => instance_hash
|
248
|
-
}
|
249
|
-
})
|
250
|
-
end
|
251
|
-
|
252
|
-
def is_provisioned?(server)
|
253
|
-
server.show.api_methods.include?(:current_instance)
|
254
|
-
end
|
255
|
-
|
256
|
-
# @param(Hash) inputs Hash input name/value pairs i.e. { :name => "text:dummy"}
|
257
|
-
def launch_server(server, inputs = { :name => "text:dummy"})
|
258
|
-
server_name = server.show.name
|
259
|
-
server.launch(inputs) # TODO: parse inputs from Vagrantfile
|
260
|
-
# XXX: need to create a new server object after launch -- why? API bug?
|
261
|
-
find_server_by_name(server_name)
|
262
|
-
end
|
263
|
-
|
264
|
-
def terminate_server(server)
|
265
|
-
server.terminate
|
266
|
-
end
|
267
|
-
|
268
|
-
# Only use this *before* you launch the server
|
269
|
-
def set_server_inputs(server, inputs)
|
270
|
-
server.show.next_instance.show.inputs.multi_update({"inputs" => inputs})
|
271
|
-
end
|
272
|
-
|
273
|
-
def server_wait_for_state(server, target_state, delay = 10)
|
274
|
-
current_state = server_state(server)
|
275
|
-
while current_state != target_state
|
276
|
-
raise "Unexpected sever state: #{current_state}" if is_bad?(current_state)
|
277
|
-
puts "Server #{current_state}. Waiting for instance to be in #{target_state} state..."
|
278
|
-
sleep delay
|
279
|
-
current_state = server_state(server)
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
def set_bad_states(list_array)
|
284
|
-
@bad_states = list_array
|
285
|
-
end
|
286
|
-
|
287
|
-
def is_bad?(state)
|
288
|
-
@bad_states ||= []
|
289
|
-
@bad_states.select{|s| state =~ /#{s}/}.size > 0
|
290
|
-
end
|
291
|
-
|
292
|
-
def server_ready?(server)
|
293
|
-
server_state(server) == "operational"
|
294
|
-
end
|
295
|
-
|
296
|
-
def server_cloud_name(server)
|
297
|
-
instance = instance_from_server(server)
|
298
|
-
cloud = cloud_from_instance(instance)
|
299
|
-
cloud.show.name
|
300
|
-
end
|
301
|
-
|
302
|
-
def server_info(server)
|
303
|
-
server.show.current_instance.show(:view => 'extended')
|
304
|
-
end
|
305
|
-
|
306
|
-
private
|
307
|
-
|
308
|
-
def server_state(server)
|
309
|
-
instance_from_server(server).show.state
|
310
|
-
end
|
311
|
-
|
312
|
-
def instance_from_server(server)
|
313
|
-
server_data = server.show
|
314
|
-
if is_provisioned?(server)
|
315
|
-
begin
|
316
|
-
server_data.current_instance
|
317
|
-
rescue
|
318
|
-
server_data.next_instance
|
319
|
-
end
|
320
|
-
else
|
321
|
-
server_data.next_instance
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
def cloud_from_instance(instance)
|
326
|
-
instance.show.cloud
|
327
|
-
end
|
328
|
-
|
329
|
-
def find_resource(api_resource, filter_key, filter_value)
|
330
|
-
resource = nil
|
331
|
-
list = list_resources(api_resource, filter_key, filter_value)
|
332
|
-
raise "More than one #{api_resource} with the #{filter_key} of '#{filter_value}'. " +
|
333
|
-
"Please resolve via the RightScale dashboard and retry." if list.size > 1
|
334
|
-
resource = list.first unless list.empty?
|
335
|
-
resource
|
336
|
-
end
|
337
|
-
|
338
|
-
def list_resources(api_resource, filter_key, filter_value)
|
339
|
-
raise ArgumentError.new("api_resource must be a symbol") unless api_resource.kind_of?(Symbol)
|
340
|
-
key = filter_key.to_s.delete("by_") # convert :by_name to "name"
|
341
|
-
filter = {}
|
342
|
-
filter = {:filter => ["#{key}==#{filter_value}"]} if filter_value
|
343
|
-
list = @connection.send(api_resource).index(filter)
|
344
|
-
list
|
345
|
-
end
|
346
|
-
|
347
|
-
def index_resource(api_resource, index_key, index_value)
|
348
|
-
raise ArgumentError.new("api_resource must be a symbol") unless api_resource.kind_of?(Symbol)
|
349
|
-
arry = @connection.send(api_resource).index(index_key => index_value)
|
350
|
-
arry
|
351
|
-
end
|
352
|
-
|
353
|
-
def find_cloud_resource(cloud, api_resource, filter_key, filter_value)
|
354
|
-
resource = nil
|
355
|
-
list = list_subresources(cloud, api_resource, filter_key, filter_value)
|
356
|
-
raise "More than one #{api_resource} with the #{filter_key} of '#{filter_value}'. " +
|
357
|
-
"Please resolve via the RightScale dashboard and retry." if list.size > 1
|
358
|
-
resource = list.first unless list.empty?
|
359
|
-
resource
|
360
|
-
end
|
361
|
-
|
362
|
-
def list_subresources(api_resource, subresource, filter_key, filter_value)
|
363
|
-
raise ArgumentError.new("subresource must be a symbol") unless subresource.kind_of?(Symbol)
|
364
|
-
key = filter_key.to_s.delete("by_") # convert :by_name to "name"
|
365
|
-
filter = {}
|
366
|
-
filter = {:filter => ["#{key}==#{filter_value}"]} if filter_value
|
367
|
-
list = api_resource.show.send(subresource).index(filter)
|
368
|
-
list
|
369
|
-
end
|
370
|
-
|
371
|
-
end
|
372
|
-
end
|