rest_connection 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/examples/console.rb +3 -4
- data/examples/restart_instance_agent.rb +9 -10
- data/examples/set_deployment_images.rb +0 -0
- data/lib/rest_connection/rightscale/ec2_security_group.rb +17 -0
- data/lib/rest_connection/rightscale/ec2_server_array.rb +33 -0
- data/lib/rest_connection/rightscale/ec2_ssh_key.rb +17 -0
- data/lib/rest_connection/rightscale/executable.rb +2 -2
- data/lib/rest_connection/rightscale/multi_cloud_image.rb +17 -0
- data/lib/rest_connection/rightscale/rightscale_api_base.rb +68 -19
- data/lib/rest_connection/rightscale/rightscale_api_resources.rb +4 -0
- data/lib/rest_connection/rightscale/server.rb +55 -26
- data/lib/rest_connection/rightscale/tag.rb +21 -0
- data/lib/rest_connection/ssh_hax.rb +24 -17
- data/rest_connection.gemspec +10 -8
- metadata +25 -21
- data/examples/mysql_dev_rollback.rb +0 -29
- data/lib/rest_connection/mechanize_connection.rb +0 -43
data/Rakefile
CHANGED
@@ -7,7 +7,6 @@ Jeweler::Tasks.new do |gemspec|
|
|
7
7
|
gemspec.email = "jeremy@rubyonlinux.org"
|
8
8
|
gemspec.homepage = "http://github.com/jeremyd/rest_connection"
|
9
9
|
gemspec.authors = ["Jeremy Deininger"]
|
10
|
-
gemspec.add_dependency('mechanize', '>= 0.9.3')
|
11
10
|
gemspec.add_dependency('activesupport')
|
12
11
|
end
|
13
12
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/examples/console.rb
CHANGED
@@ -7,7 +7,6 @@ require 'net/ssh'
|
|
7
7
|
opts = Trollop::options do
|
8
8
|
opt :deployment, "deployment nickname", :type => :string, :required => true
|
9
9
|
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
10
|
-
opt :hard, "hard reset, uninstalls right_resources premium gem (for code update), and restarts the instance agent", :type => :bool, :required => false
|
11
10
|
end
|
12
11
|
|
13
12
|
# find all servers in the deployment (the fast way)
|
@@ -17,13 +16,13 @@ servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
|
17
16
|
|
18
17
|
servers.each do |s|
|
19
18
|
s.wait_for_operational_with_dns
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
# s.spot_check("/opt/rightscale/sandbox/bin/gem uninstall right_resources_premium") do |result|
|
20
|
+
# puts result
|
21
|
+
# end
|
22
|
+
# monit will restart it
|
23
|
+
# OR-- monit -c /opt/rightscale/etc/monitrc restart instance
|
24
|
+
# s.spot_check("rnac --stop instance") do |result|
|
25
|
+
# puts result
|
26
|
+
# end
|
27
|
+
s.run_recipe("database_test::dev_pristine_restore")
|
29
28
|
end
|
File without changes
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
class Ec2SecurityGroup < RightScale::Api::Base
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
# Example:
|
17
|
+
# a = Ec2ServerArray.new(:href => "https://validhref")
|
18
|
+
# st = ServerTemplate.new(:href => "https://validhref")
|
19
|
+
# st.executables.find(:nickname
|
20
|
+
# a.run_script_on_all(
|
21
|
+
|
22
|
+
class Ec2ServerArray < RightScale::Api::Base
|
23
|
+
def run_script_on_all(script, server_template_hrefs, inputs=nil)
|
24
|
+
serv_href = URI.parse(self.href)
|
25
|
+
options = Hash.new
|
26
|
+
options[:ec2_server_array] = Hash.new
|
27
|
+
options[:ec2_server_array][:right_script_href] = self.href
|
28
|
+
options[:ec2_server_array][:parameters] = inputs unless inputs.nil?
|
29
|
+
options[:ec2_server_array][:server_template_hrefs] = server_template_hrefs
|
30
|
+
connection.post(serv_href.path, options)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
class Ec2SshKey < RightScale::Api::Base
|
17
|
+
end
|
@@ -13,14 +13,14 @@ class Executable < RightScale::Api::Base
|
|
13
13
|
# }
|
14
14
|
|
15
15
|
def recipe?
|
16
|
-
if self["recipe"]
|
16
|
+
if self["recipe"] == nil # && right_script['href']
|
17
17
|
return false
|
18
18
|
end
|
19
19
|
true
|
20
20
|
end
|
21
21
|
|
22
22
|
def right_script?
|
23
|
-
if self["recipe"]
|
23
|
+
if self["recipe"] == nil # && right_script['href']
|
24
24
|
return true
|
25
25
|
end
|
26
26
|
false
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
class MultiCloudImage < RightScale::Api::Base
|
17
|
+
end
|
@@ -13,13 +13,11 @@
|
|
13
13
|
# You should have received a copy of the GNU General Public License
|
14
14
|
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
|
-
require '
|
17
|
-
require 'activesupport'
|
16
|
+
require 'active_support'
|
18
17
|
|
19
18
|
module RightScale
|
20
19
|
module Api
|
21
20
|
class Base
|
22
|
-
include MechanizeConnection::Connection
|
23
21
|
# The params hash of attributes for direct manipulation
|
24
22
|
attr_accessor :params
|
25
23
|
|
@@ -42,6 +40,27 @@ module RightScale
|
|
42
40
|
self.to_s.underscore
|
43
41
|
end
|
44
42
|
|
43
|
+
def resource_plural_name
|
44
|
+
self.class.to_s.underscore.pluralize
|
45
|
+
end
|
46
|
+
|
47
|
+
def resource_singular_name
|
48
|
+
self.class.to_s.underscore
|
49
|
+
end
|
50
|
+
|
51
|
+
def save
|
52
|
+
uri = URI.parse(self.href)
|
53
|
+
connection.put(uri.path, resource_singular_name.to_sym => @params)
|
54
|
+
end
|
55
|
+
|
56
|
+
# matches using result of block match expression
|
57
|
+
# ex: Server.find_by(:nickname) { |n| n =~ /production/ }
|
58
|
+
def self.find_by(attrib, &block)
|
59
|
+
self.find_all.select do |s|
|
60
|
+
yield(s[attrib.to_s])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
45
64
|
def self.find_all
|
46
65
|
a = Array.new
|
47
66
|
connection.get(self.resource_plural_name).each do |object|
|
@@ -51,9 +70,8 @@ module RightScale
|
|
51
70
|
end
|
52
71
|
|
53
72
|
def self.find_by_nickname(nickname)
|
54
|
-
|
55
|
-
|
56
|
-
end
|
73
|
+
connection.logger("DEPRICATION WARNING: use of find_by_nickname is depricated, please use find_by(:nickname) { |n| n == '#{nickname}' } ")
|
74
|
+
self.find_by(:nickname) { |n| n == nickname }
|
57
75
|
end
|
58
76
|
|
59
77
|
def reload
|
@@ -61,18 +79,41 @@ module RightScale
|
|
61
79
|
@params ? @params.merge!(connection.get(uri.path)) : @params = connection.get(uri.path)
|
62
80
|
end
|
63
81
|
|
64
|
-
|
65
|
-
|
66
|
-
|
82
|
+
# the argument can be
|
83
|
+
# 1) takes href (URI),
|
84
|
+
# 2) or id (Integer)
|
85
|
+
# 3) or symbol :all, :first, :last
|
86
|
+
def self.find(href, &block)
|
87
|
+
if href.is_a?(Integer)
|
88
|
+
return self.new(connection.get(self.resource_plural_name + "/#{href}"))
|
89
|
+
elsif href.is_a?(Symbol)
|
90
|
+
results = self.find_all
|
91
|
+
if block_given?
|
92
|
+
results = results.select { |s| yield(s) }
|
93
|
+
end
|
94
|
+
if href == :all
|
95
|
+
return results
|
96
|
+
elsif href == :first
|
97
|
+
return results.first
|
98
|
+
elsif href == :last
|
99
|
+
return results.last
|
100
|
+
end
|
101
|
+
elsif uri = URI.parse(href)
|
102
|
+
return self.new(connection.get(uri.path))
|
103
|
+
end
|
104
|
+
nil
|
67
105
|
end
|
68
106
|
|
69
107
|
def self.find_by_id(id)
|
70
|
-
|
108
|
+
connection.logger("DEPRICATION WARNING: use of find_by_id is depricated, please use find(id) ")
|
109
|
+
self.find(id)
|
71
110
|
end
|
72
111
|
|
73
112
|
def self.create(opts)
|
74
113
|
location = connection.post(self.resource_plural_name, self.resource_singluar_name.to_sym => opts)
|
75
|
-
self.new('href' => location)
|
114
|
+
newrecord = self.new('href' => location)
|
115
|
+
newrecord.reload
|
116
|
+
newrecord
|
76
117
|
end
|
77
118
|
|
78
119
|
# filter is only implemented on some api endpoints
|
@@ -98,20 +139,28 @@ module RightScale
|
|
98
139
|
|
99
140
|
# the following two methods are used to access the @params hash in a friendly way
|
100
141
|
def method_missing(method_name, *args)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
142
|
+
mn = method_name.to_s
|
143
|
+
assignment = mn.gsub!(/=/,"")
|
144
|
+
mn_dash = mn.gsub(/_/,"-")
|
145
|
+
if @params[mn]
|
146
|
+
@params[mn] = args[0] if assignment
|
147
|
+
return @params[mn]
|
148
|
+
elsif @params[mn_dash]
|
149
|
+
@params[mn_dash] = args[0] if assignment
|
150
|
+
return @params[mn_dash]
|
105
151
|
else
|
106
152
|
raise "called unknown method #{method_name} with #{args.inspect}"
|
107
153
|
end
|
108
154
|
end
|
109
155
|
|
110
156
|
def [](name)
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
157
|
+
try_these = [name, name.gsub(/_/,'-'), name.to_sym]
|
158
|
+
try_these.each do |t|
|
159
|
+
if @params[t]
|
160
|
+
return @params[name]
|
161
|
+
else
|
162
|
+
return nil
|
163
|
+
end
|
115
164
|
end
|
116
165
|
end
|
117
166
|
|
@@ -20,3 +20,7 @@ require 'rest_connection/rightscale/status'
|
|
20
20
|
require 'rest_connection/rightscale/server_template'
|
21
21
|
require 'rest_connection/rightscale/right_script'
|
22
22
|
require 'rest_connection/rightscale/instance'
|
23
|
+
require 'rest_connection/rightscale/ec2_security_group'
|
24
|
+
require 'rest_connection/rightscale/ec2_ssh_key'
|
25
|
+
require 'rest_connection/rightscale/multi_cloud_image'
|
26
|
+
require 'rest_connection/rightscale/tag'
|
@@ -17,6 +17,16 @@ require 'rest_connection/ssh_hax'
|
|
17
17
|
|
18
18
|
class Server < RightScale::Api::Base
|
19
19
|
include SshHax
|
20
|
+
def self.create(opts)
|
21
|
+
create_options = Hash.new
|
22
|
+
create_options[self.resource_singluar_name.to_sym] = opts
|
23
|
+
create_options["cloud_id"] = opts[:cloud_id] if opts[:cloud_id]
|
24
|
+
location = connection.post(self.resource_plural_name,create_options)
|
25
|
+
newrecord = self.new('href' => location)
|
26
|
+
newrecord.reload
|
27
|
+
newrecord
|
28
|
+
end
|
29
|
+
|
20
30
|
def wait_for_state(st)
|
21
31
|
reload
|
22
32
|
connection.logger("#{nickname} is #{self.state}")
|
@@ -63,23 +73,23 @@ class Server < RightScale::Api::Base
|
|
63
73
|
connection.logger("WARNING: was in #{self.state} so skiping stop call")
|
64
74
|
end
|
65
75
|
end
|
66
|
-
|
67
|
-
|
76
|
+
|
77
|
+
# This method takes a RightScript or Executable, and optional run time parameters in an options hash.
|
78
|
+
def run_script(script,opts=nil)
|
68
79
|
serv_href = URI.parse(self.href)
|
69
|
-
|
80
|
+
script_options = Hash.new
|
81
|
+
script_options[:server] = Hash.new
|
82
|
+
script_options[:server][:right_script_href] = script.href
|
83
|
+
script_options[:server][:parameters] = opts unless opts.nil?
|
84
|
+
location = connection.post(serv_href.path + '/run_script', script_options)
|
70
85
|
Status.new('href' => location)
|
71
|
-
end
|
86
|
+
end
|
72
87
|
|
73
88
|
def set_input(name, value)
|
74
89
|
serv_href = URI.parse(self.href)
|
75
90
|
connection.put(serv_href.path, :server => {:parameters => {name.to_sym => value} })
|
76
91
|
end
|
77
92
|
|
78
|
-
def self.create(opts)
|
79
|
-
location = connection.post("servers", :server => opts)
|
80
|
-
Server.new('href' => location)
|
81
|
-
end
|
82
|
-
|
83
93
|
def set_template(href)
|
84
94
|
serv_href = URI.parse(self.href)
|
85
95
|
connection.put(serv_href.path, :server => {:server_template_href => href})
|
@@ -90,9 +100,14 @@ class Server < RightScale::Api::Base
|
|
90
100
|
@params.merge! connection.get(serv_href.path + "/settings")
|
91
101
|
end
|
92
102
|
|
93
|
-
def
|
103
|
+
def get_sketchy_data
|
94
104
|
serv_href = URI.parse(self.href)
|
95
|
-
@params.merge! connection.get(serv_href.path + "/
|
105
|
+
@params.merge! connection.get(serv_href.path + "/get_sketchy_data")
|
106
|
+
end
|
107
|
+
|
108
|
+
def monitoring
|
109
|
+
serv_href = URI.parse(self.href)
|
110
|
+
@params.merge! connection.get(serv_href.path + "/monitoring")
|
96
111
|
end
|
97
112
|
|
98
113
|
def reboot
|
@@ -100,22 +115,36 @@ class Server < RightScale::Api::Base
|
|
100
115
|
connection.post(serv_href.path + "/reboot")
|
101
116
|
end
|
102
117
|
|
118
|
+
def events
|
119
|
+
my_events = Event.new
|
120
|
+
id = self.href.split(/\//).last
|
121
|
+
my_events.filter_by(:server_id, id)
|
122
|
+
end
|
123
|
+
|
103
124
|
def relaunch
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
base_url = URI.parse(self.href)
|
108
|
-
base_url.path = "/servers/#{server_id}"
|
109
|
-
|
110
|
-
s = agent.get(base_url.to_s)
|
111
|
-
relaunch = s.links.detect {|d| d.to_s == "Relaunch"}
|
112
|
-
prelaunch_page = agent.get(relaunch.href)
|
113
|
-
launch_form = prelaunch_page.forms[2]
|
114
|
-
launch_form.radiobuttons_with(:name => 'launch_immediately').first.check
|
115
|
-
agent.submit(launch_form, launch_form.buttons.first)
|
116
|
-
else
|
117
|
-
connection.logger("WARNING: detected server is #{self.state}, skipping relaunch")
|
118
|
-
end
|
125
|
+
self.stop
|
126
|
+
self.wait_for_state("stopped")
|
127
|
+
self.start
|
119
128
|
end
|
129
|
+
|
130
|
+
# DOES NOT WORK: fragile web scraping
|
131
|
+
# def relaunch
|
132
|
+
# unless state == "stopped"
|
133
|
+
# wind_monkey
|
134
|
+
# server_id = self.href.split(/\//).last
|
135
|
+
# base_url = URI.parse(self.href)
|
136
|
+
# base_url.path = "/servers/#{server_id}"
|
137
|
+
#
|
138
|
+
# s = agent.get(base_url.to_s)
|
139
|
+
# relaunch = s.links.detect {|d| d.to_s == "Relaunch"}
|
140
|
+
# prelaunch_page = agent.get(relaunch.href)
|
141
|
+
# debugger
|
142
|
+
# launch_form = prelaunch_page.forms[2]
|
143
|
+
# launch_form.radiobuttons_with(:name => 'launch_immediately').first.check
|
144
|
+
# agent.submit(launch_form, launch_form.buttons.first)
|
145
|
+
# else
|
146
|
+
# connection.logger("WARNING: detected server is #{self.state}, skipping relaunch")
|
147
|
+
# end
|
148
|
+
# end
|
120
149
|
end
|
121
150
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file is part of RestConnection
|
2
|
+
#
|
3
|
+
# RestConnection is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# RestConnection is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
class Tag < RightScale::Api::Base
|
17
|
+
|
18
|
+
def self.search(resource_name, tags)
|
19
|
+
result = connection.get("/tags/search", :resource_type => resource_name.to_s, :tags => tags )
|
20
|
+
end
|
21
|
+
end
|
@@ -19,25 +19,35 @@ require 'net/ssh'
|
|
19
19
|
# This is a mixin module run_recipes until api support is ready for checking result of recipe run.
|
20
20
|
# The mixin typically used from Server#run_recipe
|
21
21
|
module SshHax
|
22
|
+
|
23
|
+
def ssh_key_config(item)
|
24
|
+
if item.is_a?(Array)
|
25
|
+
ssh_keys = item
|
26
|
+
elsif item.is_a?(String)
|
27
|
+
ssh_keys = [item]
|
28
|
+
elsif k = connection.settings[:ssh_key]
|
29
|
+
ssh_keys = [k]
|
30
|
+
elsif kk = connection.settings[:ssh_keys]
|
31
|
+
ssh_keys = kk
|
32
|
+
else
|
33
|
+
ssh_keys = nil
|
34
|
+
end
|
35
|
+
ssh_keys
|
36
|
+
end
|
37
|
+
|
22
38
|
# recipe can be either a String, or an Executable
|
23
39
|
# host_dns is optional and will default to objects self.dns_name
|
24
|
-
def run_recipe(recipe, host_dns=self.dns_name)
|
40
|
+
def run_recipe(recipe, ssh_key=nil, host_dns=self.dns_name)
|
25
41
|
if recipe.is_a?(Executable)
|
26
42
|
recipe = recipe.recipe
|
27
43
|
end
|
28
|
-
# legacy used this key by default
|
29
|
-
if connection.settings[:ssh_key]
|
30
|
-
ssh_key = connection.settings[:ssh_key]
|
31
|
-
else
|
32
|
-
ssh_key='~/.ssh/publish-test'
|
33
|
-
end
|
34
44
|
status = nil
|
35
45
|
result = nil
|
36
46
|
output = ""
|
37
47
|
tail_command ="tail -f -n1 /var/log/messages"
|
38
48
|
expect = /RightLink.*RS> ([completed|failed]+: < #{recipe} >)/
|
39
49
|
run_this = "rs_run_recipe -n '#{recipe}'"
|
40
|
-
Net::SSH.start(host_dns, 'root', :keys =>
|
50
|
+
Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
|
41
51
|
cmd_channel = ssh.open_channel do |ch1|
|
42
52
|
ch1.on_request('exit-status') do |ch, data|
|
43
53
|
status = data.read_long
|
@@ -89,30 +99,27 @@ module SshHax
|
|
89
99
|
return {:status => success, :output => output}
|
90
100
|
end
|
91
101
|
|
92
|
-
def spot_check(command, ssh_key=
|
93
|
-
|
94
|
-
|
95
|
-
Net::SSH.start(host_dns, 'root', :keys => [ssh_key]) do |ssh|
|
102
|
+
def spot_check(command, ssh_key=nil, host_dns=self.dns_name, &block)
|
103
|
+
connection.logger "SSHing to #{host_dns}"
|
104
|
+
Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
|
96
105
|
result = ssh.exec!(command)
|
97
106
|
yield result
|
98
107
|
end
|
99
108
|
end
|
100
109
|
|
101
110
|
# returns true or false based on command success
|
102
|
-
def spot_check_command?(command, ssh_key=
|
103
|
-
ssh_key = connection.settings[:ssh_key] if connection.settings[:ssh_key]
|
111
|
+
def spot_check_command?(command, ssh_key=nil, host_dns=self.dns_name)
|
104
112
|
results = spot_check_command(command, ssh_key, host_dns)
|
105
113
|
return results[:status] == 0
|
106
114
|
end
|
107
115
|
|
108
116
|
|
109
117
|
# returns hash of exit_status and output from command
|
110
|
-
def spot_check_command(command, ssh_key=
|
111
|
-
ssh_key = connection.settings[:ssh_key] if connection.settings[:ssh_key]
|
118
|
+
def spot_check_command(command, ssh_key=nil, host_dns=self.dns_name)
|
112
119
|
connection.logger "SSHing to #{host_dns} using key #{ssh_key}"
|
113
120
|
status = nil
|
114
121
|
output = ""
|
115
|
-
Net::SSH.start(host_dns, 'root', :keys =>
|
122
|
+
Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
|
116
123
|
cmd_channel = ssh.open_channel do |ch1|
|
117
124
|
ch1.on_request('exit-status') do |ch, data|
|
118
125
|
status = data.read_long
|
data/rest_connection.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rest_connection}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jeremy Deininger"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-03-18}
|
13
13
|
s.description = %q{provides rest_connection}
|
14
14
|
s.email = %q{jeremy@rubyonlinux.org}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
"Rakefile",
|
21
21
|
"VERSION",
|
22
22
|
"config/rest_api_config.yaml.sample",
|
23
|
+
"examples/console.rb",
|
23
24
|
"examples/dev_setup.rb",
|
24
25
|
"examples/relaunch_deployment.rb",
|
25
26
|
"examples/restart_instance_agent.rb",
|
@@ -30,28 +31,31 @@ Gem::Specification.new do |s|
|
|
30
31
|
"examples/run_php_chef_sequence.rb",
|
31
32
|
"examples/set_deployment_template_href.rb",
|
32
33
|
"lib/rest_connection.rb",
|
33
|
-
"lib/rest_connection/mechanize_connection.rb",
|
34
34
|
"lib/rest_connection/rightscale/deployment.rb",
|
35
|
+
"lib/rest_connection/rightscale/ec2_security_group.rb",
|
36
|
+
"lib/rest_connection/rightscale/ec2_server_array.rb",
|
37
|
+
"lib/rest_connection/rightscale/ec2_ssh_key.rb",
|
35
38
|
"lib/rest_connection/rightscale/executable.rb",
|
36
39
|
"lib/rest_connection/rightscale/instance.rb",
|
40
|
+
"lib/rest_connection/rightscale/multi_cloud_image.rb",
|
37
41
|
"lib/rest_connection/rightscale/right_script.rb",
|
38
42
|
"lib/rest_connection/rightscale/rightscale_api_base.rb",
|
39
43
|
"lib/rest_connection/rightscale/rightscale_api_resources.rb",
|
40
44
|
"lib/rest_connection/rightscale/server.rb",
|
41
45
|
"lib/rest_connection/rightscale/server_template.rb",
|
42
46
|
"lib/rest_connection/rightscale/status.rb",
|
47
|
+
"lib/rest_connection/rightscale/tag.rb",
|
43
48
|
"lib/rest_connection/ssh_hax.rb",
|
44
49
|
"rest_connection.gemspec"
|
45
50
|
]
|
46
51
|
s.homepage = %q{http://github.com/jeremyd/rest_connection}
|
47
52
|
s.rdoc_options = ["--charset=UTF-8"]
|
48
53
|
s.require_paths = ["lib"]
|
49
|
-
s.rubygems_version = %q{1.3.
|
54
|
+
s.rubygems_version = %q{1.3.6}
|
50
55
|
s.summary = %q{lib for restful connections to the rightscale api}
|
51
56
|
s.test_files = [
|
52
57
|
"examples/console.rb",
|
53
58
|
"examples/dev_setup.rb",
|
54
|
-
"examples/mysql_dev_rollback.rb",
|
55
59
|
"examples/relaunch_deployment.rb",
|
56
60
|
"examples/restart_instance_agent.rb",
|
57
61
|
"examples/right_scale_ec2_instances_api_test.rb",
|
@@ -59,6 +63,7 @@ Gem::Specification.new do |s|
|
|
59
63
|
"examples/run_ebs_terminate.rb",
|
60
64
|
"examples/run_mysql_chef_sequence.rb",
|
61
65
|
"examples/run_php_chef_sequence.rb",
|
66
|
+
"examples/set_deployment_images.rb",
|
62
67
|
"examples/set_deployment_template_href.rb"
|
63
68
|
]
|
64
69
|
|
@@ -67,14 +72,11 @@ Gem::Specification.new do |s|
|
|
67
72
|
s.specification_version = 3
|
68
73
|
|
69
74
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
70
|
-
s.add_runtime_dependency(%q<mechanize>, [">= 0.9.3"])
|
71
75
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
72
76
|
else
|
73
|
-
s.add_dependency(%q<mechanize>, [">= 0.9.3"])
|
74
77
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
75
78
|
end
|
76
79
|
else
|
77
|
-
s.add_dependency(%q<mechanize>, [">= 0.9.3"])
|
78
80
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
79
81
|
end
|
80
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest_connection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Jeremy Deininger
|
@@ -9,29 +14,21 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-18 00:00:00 -07:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: mechanize
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.9.3
|
24
|
-
version:
|
25
20
|
- !ruby/object:Gem::Dependency
|
26
21
|
name: activesupport
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
30
24
|
requirements:
|
31
25
|
- - ">="
|
32
26
|
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
33
29
|
version: "0"
|
34
|
-
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
35
32
|
description: provides rest_connection
|
36
33
|
email: jeremy@rubyonlinux.org
|
37
34
|
executables: []
|
@@ -45,6 +42,7 @@ files:
|
|
45
42
|
- Rakefile
|
46
43
|
- VERSION
|
47
44
|
- config/rest_api_config.yaml.sample
|
45
|
+
- examples/console.rb
|
48
46
|
- examples/dev_setup.rb
|
49
47
|
- examples/relaunch_deployment.rb
|
50
48
|
- examples/restart_instance_agent.rb
|
@@ -55,16 +53,20 @@ files:
|
|
55
53
|
- examples/run_php_chef_sequence.rb
|
56
54
|
- examples/set_deployment_template_href.rb
|
57
55
|
- lib/rest_connection.rb
|
58
|
-
- lib/rest_connection/mechanize_connection.rb
|
59
56
|
- lib/rest_connection/rightscale/deployment.rb
|
57
|
+
- lib/rest_connection/rightscale/ec2_security_group.rb
|
58
|
+
- lib/rest_connection/rightscale/ec2_server_array.rb
|
59
|
+
- lib/rest_connection/rightscale/ec2_ssh_key.rb
|
60
60
|
- lib/rest_connection/rightscale/executable.rb
|
61
61
|
- lib/rest_connection/rightscale/instance.rb
|
62
|
+
- lib/rest_connection/rightscale/multi_cloud_image.rb
|
62
63
|
- lib/rest_connection/rightscale/right_script.rb
|
63
64
|
- lib/rest_connection/rightscale/rightscale_api_base.rb
|
64
65
|
- lib/rest_connection/rightscale/rightscale_api_resources.rb
|
65
66
|
- lib/rest_connection/rightscale/server.rb
|
66
67
|
- lib/rest_connection/rightscale/server_template.rb
|
67
68
|
- lib/rest_connection/rightscale/status.rb
|
69
|
+
- lib/rest_connection/rightscale/tag.rb
|
68
70
|
- lib/rest_connection/ssh_hax.rb
|
69
71
|
- rest_connection.gemspec
|
70
72
|
has_rdoc: true
|
@@ -80,25 +82,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
82
|
requirements:
|
81
83
|
- - ">="
|
82
84
|
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
83
87
|
version: "0"
|
84
|
-
version:
|
85
88
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
89
|
requirements:
|
87
90
|
- - ">="
|
88
91
|
- !ruby/object:Gem::Version
|
92
|
+
segments:
|
93
|
+
- 0
|
89
94
|
version: "0"
|
90
|
-
version:
|
91
95
|
requirements: []
|
92
96
|
|
93
97
|
rubyforge_project:
|
94
|
-
rubygems_version: 1.3.
|
98
|
+
rubygems_version: 1.3.6
|
95
99
|
signing_key:
|
96
100
|
specification_version: 3
|
97
101
|
summary: lib for restful connections to the rightscale api
|
98
102
|
test_files:
|
99
103
|
- examples/console.rb
|
100
104
|
- examples/dev_setup.rb
|
101
|
-
- examples/mysql_dev_rollback.rb
|
102
105
|
- examples/relaunch_deployment.rb
|
103
106
|
- examples/restart_instance_agent.rb
|
104
107
|
- examples/right_scale_ec2_instances_api_test.rb
|
@@ -106,4 +109,5 @@ test_files:
|
|
106
109
|
- examples/run_ebs_terminate.rb
|
107
110
|
- examples/run_mysql_chef_sequence.rb
|
108
111
|
- examples/run_php_chef_sequence.rb
|
112
|
+
- examples/set_deployment_images.rb
|
109
113
|
- examples/set_deployment_template_href.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
require 'rubygems'
|
3
|
-
require 'trollop'
|
4
|
-
require 'rest_connection'
|
5
|
-
require 'net/ssh'
|
6
|
-
|
7
|
-
opts = Trollop::options do
|
8
|
-
opt :deployment, "deployment nickname", :type => :string, :required => true
|
9
|
-
opt :only, "regex string matching the nickname of the servers you want to relaunch. This excludes servers that do not match\nExample --only ubuntu", :type => :string, :required => false
|
10
|
-
opt :hard, "hard reset, uninstalls right_resources premium gem (for code update), and restarts the instance agent", :type => :bool, :required => false
|
11
|
-
end
|
12
|
-
|
13
|
-
# find all servers in the deployment (the fast way)
|
14
|
-
deployment = Deployment.find_by_nickname_speed(opts[:deployment]).first
|
15
|
-
servers = deployment.servers_no_reload
|
16
|
-
servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
|
17
|
-
|
18
|
-
servers.each do |s|
|
19
|
-
s.wait_for_operational_with_dns
|
20
|
-
if opts[:hard]
|
21
|
-
s.spot_check("gem uninstall right_resources_premium") do |result|
|
22
|
-
puts result
|
23
|
-
end
|
24
|
-
s.spot_check("monit restart instance") do |result|
|
25
|
-
puts result
|
26
|
-
end
|
27
|
-
end
|
28
|
-
s.run_recipe("database_test::dev_pristine_restore")
|
29
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'mechanize'
|
2
|
-
require 'logger'
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
module MechanizeConnection
|
6
|
-
module Connection
|
7
|
-
|
8
|
-
# creates/returns global mechanize agent
|
9
|
-
def agent
|
10
|
-
@@agent ||= WWW::Mechanize.new do |a|
|
11
|
-
a.log = Logger.new(STDOUT)
|
12
|
-
a.log.level = Logger::INFO
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# creates/returns global mechanize agent
|
17
|
-
def self.agent
|
18
|
-
@@agent ||= WWW::Mechanize.new do |a|
|
19
|
-
a.log = Logger.new(STDOUT)
|
20
|
-
a.log.level = Logger::INFO
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# login to rightscale dashboard /sessions/new using rest connection user and pass
|
25
|
-
def wind_monkey
|
26
|
-
base_url = URI.parse(connection.settings[:api_url])
|
27
|
-
base_url.path = "/"
|
28
|
-
if agent.cookie_jar.empty?(base_url)
|
29
|
-
agent.user_agent_alias = 'Mac Safari'
|
30
|
-
# Login
|
31
|
-
base_url = URI.parse(connection.settings[:api_url])
|
32
|
-
agent.user_agent_alias = 'Mac Safari'
|
33
|
-
# Login
|
34
|
-
base_url.path = "/sessions/new"
|
35
|
-
login_page = agent.get(base_url)
|
36
|
-
login_form = login_page.forms.first
|
37
|
-
login_form.email = connection.settings[:user]
|
38
|
-
login_form.password = connection.settings[:pass]
|
39
|
-
agent.submit(login_form, login_form.buttons.first)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|