rest_connection 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.swp
2
+ *.swo
data/Rakefile CHANGED
@@ -9,6 +9,7 @@ Jeweler::Tasks.new do |gemspec|
9
9
  gemspec.authors = ["Jeremy Deininger"]
10
10
  gemspec.add_dependency('activesupport')
11
11
  gemspec.add_dependency('net-ssh')
12
+ gemspec.add_dependency('json')
12
13
  end
13
14
  Jeweler::GemcutterTasks.new
14
15
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
@@ -1,7 +1,10 @@
1
1
  ---
2
+ :ssh_keys:
3
+ - ~/.ssh/my_server_key
4
+ - ~/.ssh/my_server_key-eu
5
+ - ~/.ssh/my_server_key-west
2
6
  :pass: myUltraSecurePasswordz
3
7
  :user: myUserEmail@MyMailDomain.com
4
8
  :api_url: https://my.rightscale.com/api/acct/00000000
5
- :ssh_key: ~/.ssh/my-server-key
6
9
  :common_headers:
7
10
  X_API_VERSION: "1.0"
data/examples/console.rb CHANGED
@@ -2,8 +2,6 @@ require 'rubygems'
2
2
  require 'rest_connection'
3
3
  require 'ruby-debug'
4
4
 
5
- s=Server.find(746271)
6
- s.relaunch
7
-
5
+ debugger
8
6
  puts "done!"
9
7
 
@@ -7,6 +7,7 @@ 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
10
11
  end
11
12
 
12
13
  # find all servers in the deployment (the fast way)
@@ -16,13 +17,13 @@ servers = servers.select { |s| s.nickname =~ /#{opts[:only]}/ } if opts[:only]
16
17
 
17
18
  servers.each do |s|
18
19
  s.wait_for_operational_with_dns
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")
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")
28
29
  end
@@ -169,13 +169,10 @@ module RestConnection
169
169
  def logger(message)
170
170
  init_message = "Initializing Logging using "
171
171
  if @@logger.nil?
172
- if @settings[:log_file]
173
- @@logger = Logger.new(@settings[:log_file])
174
- init_message += @settings[:log_file]
175
- elsif ENV['REST_CONNECTION_LOG']
172
+ if ENV['REST_CONNECTION_LOG']
176
173
  @@logger = Logger.new(ENV['REST_CONNECTION_LOG'])
177
174
  init_message += ENV['REST_CONNECTION_LOG']
178
- else @settings[:log_file]
175
+ else
179
176
  @@logger = Logger.new(STDOUT)
180
177
  init_message += "STDOUT"
181
178
  end
@@ -0,0 +1,44 @@
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 AuditEntry
17
+ # attr_accessor :status, :output
18
+ # def initialize(opts)
19
+ # @status = opts[:status]
20
+ # @output = opts[:output]
21
+ # end
22
+ # def wait_for_completed(audit_link = "no audit link available")
23
+ # raise "FATAL: script failed. see audit #{audit_link}" unless @status
24
+ # end
25
+ #end
26
+
27
+ class AuditEntry
28
+ include RightScale::Api::Base
29
+ extend RightScale::Api::BaseExtend
30
+
31
+ def wait_for_state(state)
32
+ while(1)
33
+ reload
34
+ connection.logger("state is #{self.state}, waiting for #{state}")
35
+ raise "FATAL error, script failed\nSee Audit: #{self.href}" if self.state == 'failed'
36
+ sleep 5
37
+ return true if state == self.state
38
+ end
39
+ end
40
+
41
+ def wait_for_completed(legacy=nil)
42
+ wait_for_state("completed")
43
+ end
44
+ end
@@ -13,7 +13,10 @@
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
- class Deployment < RightScale::Api::Base
16
+ class Deployment
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
19
+
17
20
  def set_input(name, value)
18
21
  deploy_href = URI.parse(self.href)
19
22
  connection.put(deploy_href.path, :deployment => {:parameters => {name => value} })
@@ -13,5 +13,7 @@
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
- class Ec2SecurityGroup < RightScale::Api::Base
16
+ class Ec2SecurityGroup
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  end
@@ -19,7 +19,9 @@
19
19
  # st.executables.find(:nickname
20
20
  # a.run_script_on_all(
21
21
 
22
- class Ec2ServerArray < RightScale::Api::Base
22
+ class Ec2ServerArray
23
+ include RightScale::Api::Base
24
+ extend RightScale::Api::BaseExtend
23
25
  def run_script_on_all(script, server_template_hrefs, inputs=nil)
24
26
  serv_href = URI.parse(self.href)
25
27
  options = Hash.new
@@ -13,5 +13,7 @@
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
- class Ec2SshKey < RightScale::Api::Base
16
+ class Ec2SshKey
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  end
@@ -1,4 +1,6 @@
1
- class Executable < RightScale::Api::Base
1
+ class Executable
2
+ include RightScale::Api::Base
3
+ extend RightScale::Api::BaseExtend
2
4
 
3
5
  # executable can be EITHER a right_script or recipe
4
6
  # executable example params format:
@@ -16,7 +16,9 @@
16
16
  # This is an instance facing api and can only be used with
17
17
  # an authentication URL normally found in the instance's userdata called
18
18
  # RS_API_URL
19
- class Instance < RightScale::Api::Base
19
+ class Instance
20
+ include RightScale::Api::Base
21
+ extend RightScale::Api::BaseExtend
20
22
  #def create_ebs_volume_from_snap(snap_aws_id)
21
23
  # connection.post('create_ebs_volume.js', :aws_id => snap_aws_id )
22
24
  #end
@@ -13,5 +13,7 @@
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
- class MultiCloudImage < RightScale::Api::Base
16
+ class MultiCloudImage
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  end
@@ -14,7 +14,9 @@
14
14
  # along with RestConnection. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
16
 
17
- class RightScript < RightScale::Api::Base
17
+ class RightScript
18
+ include RightScale::Api::Base
19
+ extend RightScale::Api::BaseExtend
18
20
  def self.from_yaml(yaml)
19
21
  scripts = []
20
22
  x = YAML.load(yaml)
@@ -17,51 +17,27 @@ require 'active_support'
17
17
 
18
18
  module RightScale
19
19
  module Api
20
- class Base
21
- # The params hash of attributes for direct manipulation
22
- attr_accessor :params
23
-
24
- def self.connection()
25
- @@connection ||= RestConnection::Connection.new
26
- end
20
+ module BaseExtend
27
21
  def connection()
28
22
  @@connection ||= RestConnection::Connection.new
29
23
  end
30
24
 
31
- def initialize(params = {})
32
- @params = params
33
- end
34
-
35
- def self.resource_plural_name
25
+ def resource_plural_name
36
26
  self.to_s.underscore.pluralize
37
27
  end
38
28
 
39
- def self.resource_singluar_name
29
+ def resource_singluar_name
40
30
  self.to_s.underscore
41
31
  end
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
32
  # matches using result of block match expression
57
33
  # ex: Server.find_by(:nickname) { |n| n =~ /production/ }
58
- def self.find_by(attrib, &block)
34
+ def find_by(attrib, &block)
59
35
  self.find_all.select do |s|
60
36
  yield(s[attrib.to_s])
61
37
  end
62
38
  end
63
39
 
64
- def self.find_all
40
+ def find_all
65
41
  a = Array.new
66
42
  connection.get(self.resource_plural_name).each do |object|
67
43
  a << self.new(object)
@@ -69,21 +45,16 @@ module RightScale
69
45
  return a
70
46
  end
71
47
 
72
- def self.find_by_nickname(nickname)
48
+ def find_by_nickname(nickname)
73
49
  connection.logger("DEPRICATION WARNING: use of find_by_nickname is depricated, please use find_by(:nickname) { |n| n == '#{nickname}' } ")
74
50
  self.find_by(:nickname) { |n| n == nickname }
75
51
  end
76
52
 
77
- def reload
78
- uri = URI.parse(self.href)
79
- @params ? @params.merge!(connection.get(uri.path)) : @params = connection.get(uri.path)
80
- end
81
-
82
53
  # the argument can be
83
54
  # 1) takes href (URI),
84
55
  # 2) or id (Integer)
85
56
  # 3) or symbol :all, :first, :last
86
- def self.find(href, &block)
57
+ def find(href, &block)
87
58
  if href.is_a?(Integer)
88
59
  return self.new(connection.get(self.resource_plural_name + "/#{href}"))
89
60
  elsif href.is_a?(Symbol)
@@ -104,12 +75,12 @@ module RightScale
104
75
  nil
105
76
  end
106
77
 
107
- def self.find_by_id(id)
78
+ def find_by_id(id)
108
79
  connection.logger("DEPRICATION WARNING: use of find_by_id is depricated, please use find(id) ")
109
80
  self.find(id)
110
81
  end
111
82
 
112
- def self.create(opts)
83
+ def create(opts)
113
84
  location = connection.post(self.resource_plural_name, self.resource_singluar_name.to_sym => opts)
114
85
  newrecord = self.new('href' => location)
115
86
  newrecord.reload
@@ -117,12 +88,12 @@ module RightScale
117
88
  end
118
89
 
119
90
  # filter is only implemented on some api endpoints
120
- def self.find_by_nickname_speed(nickname)
91
+ def find_by_nickname_speed(nickname)
121
92
  self.find_with_filter('nickname' => nickname)
122
93
  end
123
94
 
124
95
  # filter is only implemented on some api endpoints
125
- def self.find_with_filter(filter = {})
96
+ def find_with_filter(filter = {})
126
97
  filter_params = ""
127
98
  filter.each {|key,val| filter_params += "filter[]=#{key}=#{val}&"}
128
99
  a = Array.new
@@ -131,6 +102,36 @@ module RightScale
131
102
  end
132
103
  return a
133
104
  end
105
+ end
106
+
107
+ module Base
108
+ # The params hash of attributes for direct manipulation
109
+ attr_accessor :params
110
+ def initialize(params = {})
111
+ @params = params
112
+ end
113
+
114
+ def connection()
115
+ @@connection ||= RestConnection::Connection.new
116
+ end
117
+
118
+ def resource_plural_name
119
+ self.class.to_s.underscore.pluralize
120
+ end
121
+
122
+ def resource_singular_name
123
+ self.class.to_s.underscore
124
+ end
125
+
126
+ def save
127
+ uri = URI.parse(self.href)
128
+ connection.put(uri.path, resource_singular_name.to_sym => @params)
129
+ end
130
+
131
+ def reload
132
+ uri = URI.parse(self.href)
133
+ @params ? @params.merge!(connection.get(uri.path)) : @params = connection.get(uri.path)
134
+ end
134
135
 
135
136
  def destroy
136
137
  my_href = URI.parse(self.href)
@@ -148,8 +149,11 @@ module RightScale
148
149
  elsif @params[mn_dash]
149
150
  @params[mn_dash] = args[0] if assignment
150
151
  return @params[mn_dash]
152
+ elsif @params[mn.to_sym]
153
+ return @params[mn.to_sym]
151
154
  else
152
- raise "called unknown method #{method_name} with #{args.inspect}"
155
+ return nil
156
+ #raise "called unknown method #{method_name} with #{args.inspect}"
153
157
  end
154
158
  end
155
159
 
@@ -24,3 +24,5 @@ require 'rest_connection/rightscale/ec2_security_group'
24
24
  require 'rest_connection/rightscale/ec2_ssh_key'
25
25
  require 'rest_connection/rightscale/multi_cloud_image'
26
26
  require 'rest_connection/rightscale/tag'
27
+ require 'rest_connection/rightscale/rs_internal'
28
+ require 'rest_connection/rightscale/audit_entry'
@@ -0,0 +1,42 @@
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
+ #
17
+ # You must have special API access to use these internal API calls.
18
+ #
19
+ class RsInternal
20
+ include RightScale::Api::Base
21
+ extend RightScale::Api::BaseExtend
22
+
23
+ def connection
24
+ @@little_brother_connection ||= RestConnection::Connection.new
25
+ @@little_brother_connection.settings[:common_headers] = { 'X-API-VERSION' => '0.1' }
26
+ @@little_brother_connection
27
+ end
28
+
29
+ def self.connection
30
+ @@little_brother_connection ||= RestConnection::Connection.new
31
+ @@little_brother_connection.settings[:common_headers] = { 'X-API-VERSION' => '0.1' }
32
+ @@little_brother_connection
33
+ end
34
+
35
+ def self.get_server_template_multi_cloud_images(server_template_href)
36
+ connection.get("rs_internal/get_server_template_multi_cloud_images","server_template_href=#{server_template_href}")
37
+ end
38
+
39
+ def self.set_server_multi_cloud_image(server_href, mci_href)
40
+ connection.put("rs_internal/set_server_multi_cloud_image", {:server_href => server_href, :multi_cloud_image_href => mci_href})
41
+ end
42
+ end
@@ -15,8 +15,11 @@
15
15
 
16
16
  require 'rest_connection/ssh_hax'
17
17
 
18
- class Server < RightScale::Api::Base
18
+ class Server
19
+ include RightScale::Api::Base
20
+ extend RightScale::Api::BaseExtend
19
21
  include SshHax
22
+
20
23
  def self.create(opts)
21
24
  create_options = Hash.new
22
25
  create_options[self.resource_singluar_name.to_sym] = opts
@@ -74,8 +77,34 @@ class Server < RightScale::Api::Base
74
77
  end
75
78
  end
76
79
 
77
- # This method takes a RightScript or Executable, and optional run time parameters in an options hash.
80
+ # This should be used with v5 images only.
81
+ # executable to run can be an Executable or RightScript object
82
+ def run_executable(executable, opts=nil)
83
+ script_options = Hash.new
84
+ script_options[:server] = Hash.new
85
+ if executable.is_a?(Executable)
86
+ if executable.recipe?
87
+ script_options[:server][:recipe] = executable.recipe
88
+ else
89
+ script_options[:server][:right_script_href] = executable.right_script.href
90
+ end
91
+ elsif executable.is_a?(RightScript)
92
+ script_options[:server][:right_script_href] = executable.href
93
+ else
94
+ raise "Invalid class passed to run_executable, needs Executable or RightScript, was:#{executable.class}"
95
+ end
96
+
97
+ serv_href = URI.parse(self.href)
98
+ script_options[:server][:parameters] = opts unless opts.nil?
99
+ location = connection.post(serv_href.path + '/run_executable', script_options)
100
+ AuditEntry.new('href' => location)
101
+ end
102
+
103
+ # This should be used with v4 images only.
78
104
  def run_script(script,opts=nil)
105
+ if script.is_a?(Executable)
106
+ script = script.right_script
107
+ end
79
108
  serv_href = URI.parse(self.href)
80
109
  script_options = Hash.new
81
110
  script_options[:server] = Hash.new
@@ -127,6 +156,7 @@ class Server < RightScale::Api::Base
127
156
  self.start
128
157
  end
129
158
 
159
+
130
160
  # DOES NOT WORK: fragile web scraping
131
161
  # def relaunch
132
162
  # unless state == "stopped"
@@ -13,7 +13,9 @@
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
- class ServerTemplate < RightScale::Api::Base
16
+ class ServerTemplate
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
  def initialize(params)
18
20
  @params = params
19
21
  fetch_executables
@@ -28,4 +30,9 @@ class ServerTemplate < RightScale::Api::Base
28
30
  end
29
31
  @params["executables"] = ex
30
32
  end
33
+
34
+ def fetch_multi_cloud_images
35
+ @params["multi_cloud_images"] = RsInternal.get_server_template_multi_cloud_images(self.href)
36
+ end
37
+
31
38
  end
@@ -12,8 +12,14 @@
12
12
  #
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
+ #
16
+ # For now this is a stub for using with the ssh enabled Server#run_script
15
17
 
16
- class Status < RightScale::Api::Base
18
+ #This is the v4 image only work status api.
19
+ # was used by Server#run_script (depricating..)
20
+ class Status
21
+ include RightScale::Api::Base
22
+ extend RightScale::Api::BaseExtend
17
23
  def wait_for_completed(audit_link = "no audit link available")
18
24
  while(1)
19
25
  reload
@@ -13,7 +13,9 @@
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
- class Tag < RightScale::Api::Base
16
+ class Tag
17
+ include RightScale::Api::Base
18
+ extend RightScale::Api::BaseExtend
17
19
 
18
20
  def self.search(resource_name, tags)
19
21
  result = connection.get("/tags/search", :resource_type => resource_name.to_s, :tags => tags )
@@ -35,18 +35,11 @@ module SshHax
35
35
  ssh_keys
36
36
  end
37
37
 
38
- # recipe can be either a String, or an Executable
39
- # host_dns is optional and will default to objects self.dns_name
40
- def run_recipe(recipe, ssh_key=nil, host_dns=self.dns_name)
41
- if recipe.is_a?(Executable)
42
- recipe = recipe.recipe
43
- end
38
+ def run_and_tail(run_this, tail_command, expect, ssh_key=nil, host_dns=self.dns_name)
44
39
  status = nil
45
40
  result = nil
46
41
  output = ""
47
- tail_command ="tail -f -n1 /var/log/messages"
48
- expect = /RightLink.*RS> ([completed|failed]+: < #{recipe} >)/
49
- run_this = "rs_run_recipe -n '#{recipe}'"
42
+ connection.logger("Running: #{run_this}")
50
43
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
51
44
  cmd_channel = ssh.open_channel do |ch1|
52
45
  ch1.on_request('exit-status') do |ch, data|
@@ -93,12 +86,46 @@ module SshHax
93
86
  cmd_channel.wait
94
87
  log_channel.wait
95
88
  end
96
- success = result.include?('completed')
97
89
  connection.logger output
90
+ success = result.include?('completed')
98
91
  connection.logger "Converge failed. See server audit: #{self.audit_link}" unless success
99
92
  return {:status => success, :output => output}
100
93
  end
101
94
 
95
+ # script is an Executable object with minimally nick or id set
96
+ def run_executable_with_ssh(script, options={}, ssh_key=nil)
97
+ raise "FATAL: run_executable called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless self.dns_name
98
+ if script.is_a?(Executable)
99
+ script = script.right_script
100
+ end
101
+
102
+ raise "FATAL: unrecognized format for script. Must be an Executable or RightScript with href or name attributes" unless (script.is_a?(RightScript)) && (script.href || script.name)
103
+ if script.href
104
+ run_this = "rs_run_right_script -i #{script.href.split(/\//).last}"
105
+ elsif script.name
106
+ run_this = "rs_run_right_script -n #{script.name}"
107
+ end
108
+ tail_command ="tail -f -n1 /var/log/messages"
109
+ expect = /RightLink.*RS> ([completed|failed]+:)/
110
+ options.each do |key, value|
111
+ run_this += " -p #{key}=#{value}"
112
+ end
113
+ AuditEntry.new(run_and_tail(run_this, tail_command, expect))
114
+ end
115
+
116
+ # recipe can be either a String, or an Executable
117
+ # host_dns is optional and will default to objects self.dns_name
118
+ def run_recipe_with_ssh(recipe, ssh_key=nil, host_dns=self.dns_name)
119
+ raise "FATAL: run_script called on a server with no dns_name. You need to run .settings on the server to populate this attribute." unless self.dns_name
120
+ if recipe.is_a?(Executable)
121
+ recipe = recipe.recipe
122
+ end
123
+ tail_command ="tail -f -n1 /var/log/messages"
124
+ expect = /RightLink.*RS> ([completed|failed]+: < #{recipe} >)/
125
+ run_this = "rs_run_recipe -n '#{recipe}'"
126
+ run_and_tail(run_this, tail_command, expect, ssh_key)
127
+ end
128
+
102
129
  def spot_check(command, ssh_key=nil, host_dns=self.dns_name, &block)
103
130
  connection.logger "SSHing to #{host_dns}"
104
131
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
@@ -116,7 +143,7 @@ module SshHax
116
143
 
117
144
  # returns hash of exit_status and output from command
118
145
  def spot_check_command(command, ssh_key=nil, host_dns=self.dns_name)
119
- connection.logger "SSHing to #{host_dns} using key #{ssh_key}"
146
+ connection.logger "SSHing to #{host_dns} using key(s) #{ssh_key_config(ssh_key)}"
120
147
  status = nil
121
148
  output = ""
122
149
  Net::SSH.start(host_dns, 'root', :keys => ssh_key_config(ssh_key)) do |ssh|
@@ -131,6 +158,7 @@ module SshHax
131
158
  status = 1
132
159
  end
133
160
  ch2.on_data do |ch, data|
161
+
134
162
  output += data
135
163
  end
136
164
  ch2.on_extended_data do |ch, type, data|
@@ -5,18 +5,19 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rest_connection}
8
- s.version = "0.0.3"
8
+ s.version = "0.0.4"
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-03-18}
12
+ s.date = %q{2010-04-15}
13
13
  s.description = %q{provides rest_connection}
14
14
  s.email = %q{jeremy@rubyonlinux.org}
15
15
  s.extra_rdoc_files = [
16
16
  "README"
17
17
  ]
18
18
  s.files = [
19
- "README",
19
+ ".gitignore",
20
+ "README",
20
21
  "Rakefile",
21
22
  "VERSION",
22
23
  "config/rest_api_config.yaml.sample",
@@ -31,6 +32,7 @@ Gem::Specification.new do |s|
31
32
  "examples/run_php_chef_sequence.rb",
32
33
  "examples/set_deployment_template_href.rb",
33
34
  "lib/rest_connection.rb",
35
+ "lib/rest_connection/rightscale/audit_entry.rb",
34
36
  "lib/rest_connection/rightscale/deployment.rb",
35
37
  "lib/rest_connection/rightscale/ec2_security_group.rb",
36
38
  "lib/rest_connection/rightscale/ec2_server_array.rb",
@@ -41,12 +43,15 @@ Gem::Specification.new do |s|
41
43
  "lib/rest_connection/rightscale/right_script.rb",
42
44
  "lib/rest_connection/rightscale/rightscale_api_base.rb",
43
45
  "lib/rest_connection/rightscale/rightscale_api_resources.rb",
46
+ "lib/rest_connection/rightscale/rs_internal.rb",
44
47
  "lib/rest_connection/rightscale/server.rb",
45
48
  "lib/rest_connection/rightscale/server_template.rb",
46
49
  "lib/rest_connection/rightscale/status.rb",
47
50
  "lib/rest_connection/rightscale/tag.rb",
48
51
  "lib/rest_connection/ssh_hax.rb",
49
- "rest_connection.gemspec"
52
+ "rest_connection.gemspec",
53
+ "spec/rs_internal_spec.rb",
54
+ "spec/server_spec.rb"
50
55
  ]
51
56
  s.homepage = %q{http://github.com/jeremyd/rest_connection}
52
57
  s.rdoc_options = ["--charset=UTF-8"]
@@ -54,17 +59,18 @@ Gem::Specification.new do |s|
54
59
  s.rubygems_version = %q{1.3.6}
55
60
  s.summary = %q{lib for restful connections to the rightscale api}
56
61
  s.test_files = [
57
- "examples/console.rb",
58
- "examples/dev_setup.rb",
59
- "examples/relaunch_deployment.rb",
62
+ "spec/server_spec.rb",
63
+ "spec/rs_internal_spec.rb",
60
64
  "examples/restart_instance_agent.rb",
65
+ "examples/console.rb",
66
+ "examples/run_php_chef_sequence.rb",
67
+ "examples/set_deployment_template_href.rb",
68
+ "examples/dev_setup.rb",
61
69
  "examples/right_scale_ec2_instances_api_test.rb",
62
- "examples/run_ebs_sequence.rb",
70
+ "examples/relaunch_deployment.rb",
63
71
  "examples/run_ebs_terminate.rb",
64
72
  "examples/run_mysql_chef_sequence.rb",
65
- "examples/run_php_chef_sequence.rb",
66
- "examples/set_deployment_images.rb",
67
- "examples/set_deployment_template_href.rb"
73
+ "examples/run_ebs_sequence.rb"
68
74
  ]
69
75
 
70
76
  if s.respond_to? :specification_version then
@@ -74,13 +80,16 @@ Gem::Specification.new do |s|
74
80
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
75
81
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
76
82
  s.add_runtime_dependency(%q<net-ssh>, [">= 0"])
83
+ s.add_runtime_dependency(%q<json>, [">= 0"])
77
84
  else
78
85
  s.add_dependency(%q<activesupport>, [">= 0"])
79
86
  s.add_dependency(%q<net-ssh>, [">= 0"])
87
+ s.add_dependency(%q<json>, [">= 0"])
80
88
  end
81
89
  else
82
90
  s.add_dependency(%q<activesupport>, [">= 0"])
83
91
  s.add_dependency(%q<net-ssh>, [">= 0"])
92
+ s.add_dependency(%q<json>, [">= 0"])
84
93
  end
85
94
  end
86
95
 
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'rest_connection'
3
+ require 'spec'
4
+ require 'ruby-debug'
5
+
6
+ describe RsInternal, "exercises the rs_internal api" do
7
+ before(:all) do
8
+ @st = ServerTemplate.find(27418)
9
+ end
10
+
11
+ # this will never be checked in, these tests are too hardwired
12
+ # (doesn't mean it's not useful)
13
+ it "should get all the mcis for this hardcoded template and set this hardcoded server" do
14
+ mcis = RsInternal.get_server_template_multi_cloud_images(@st.href)
15
+ mcis.empty?.should_not == true
16
+ mcis.first['href'].include?("https://").should == true
17
+
18
+ server = "/servers/752944"
19
+ success = RsInternal.set_server_multi_cloud_image(server, mcis.first['href'])
20
+
21
+ debugger
22
+ puts "blah"
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,34 @@
1
+ require 'rubygems'
2
+ require 'rest_connection'
3
+ require 'spec'
4
+ require 'ruby-debug'
5
+
6
+ describe Server, "server api object exercise" do
7
+ before(:all) do
8
+ @server_v4_right_script = Server.find(752616) # a v4 server
9
+ @server_v5_recipe = Server.find(697640) # a v5 server
10
+ @server_v5_right_script = Server.find() # a v5 server
11
+ end
12
+
13
+ it "should run a right_script on a v4 server" do
14
+ this_template = ServerTemplate.find(@server_v4_right_script.server_template_href)
15
+ run_first = this_template.executables.first
16
+ location = @server_v4_right_script.run_executable(run_first)
17
+ audit = AuditEntry.new(:href => location)
18
+ audit.wait_for_completed
19
+ end
20
+
21
+ it "should run a recipe on a v5 server" do
22
+ this_template = ServerTemplate.find(@server_v5_recipe.server_template_href)
23
+ run_first = this_template.executables.first
24
+ audit = @server_v5_recipe.run_executable(run_first)
25
+ audit.wait_for_completed
26
+ end
27
+
28
+ it "should run a right_script on a v5 server" do
29
+ this_template = ServerTemplate.find(@server_v5_right_script.server_template_href)
30
+ run_first = this_template.executables.first
31
+ audit = @server_v5_right_script.run_executable(run_first)
32
+ audit.wait_for_completed
33
+ end
34
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jeremy Deininger
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-18 00:00:00 -07:00
17
+ date: 2010-04-15 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,18 @@ dependencies:
41
41
  version: "0"
42
42
  type: :runtime
43
43
  version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: json
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :runtime
55
+ version_requirements: *id003
44
56
  description: provides rest_connection
45
57
  email: jeremy@rubyonlinux.org
46
58
  executables: []
@@ -50,6 +62,7 @@ extensions: []
50
62
  extra_rdoc_files:
51
63
  - README
52
64
  files:
65
+ - .gitignore
53
66
  - README
54
67
  - Rakefile
55
68
  - VERSION
@@ -65,6 +78,7 @@ files:
65
78
  - examples/run_php_chef_sequence.rb
66
79
  - examples/set_deployment_template_href.rb
67
80
  - lib/rest_connection.rb
81
+ - lib/rest_connection/rightscale/audit_entry.rb
68
82
  - lib/rest_connection/rightscale/deployment.rb
69
83
  - lib/rest_connection/rightscale/ec2_security_group.rb
70
84
  - lib/rest_connection/rightscale/ec2_server_array.rb
@@ -75,12 +89,15 @@ files:
75
89
  - lib/rest_connection/rightscale/right_script.rb
76
90
  - lib/rest_connection/rightscale/rightscale_api_base.rb
77
91
  - lib/rest_connection/rightscale/rightscale_api_resources.rb
92
+ - lib/rest_connection/rightscale/rs_internal.rb
78
93
  - lib/rest_connection/rightscale/server.rb
79
94
  - lib/rest_connection/rightscale/server_template.rb
80
95
  - lib/rest_connection/rightscale/status.rb
81
96
  - lib/rest_connection/rightscale/tag.rb
82
97
  - lib/rest_connection/ssh_hax.rb
83
98
  - rest_connection.gemspec
99
+ - spec/rs_internal_spec.rb
100
+ - spec/server_spec.rb
84
101
  has_rdoc: true
85
102
  homepage: http://github.com/jeremyd/rest_connection
86
103
  licenses: []
@@ -112,14 +129,15 @@ signing_key:
112
129
  specification_version: 3
113
130
  summary: lib for restful connections to the rightscale api
114
131
  test_files:
132
+ - spec/server_spec.rb
133
+ - spec/rs_internal_spec.rb
134
+ - examples/restart_instance_agent.rb
115
135
  - examples/console.rb
136
+ - examples/run_php_chef_sequence.rb
137
+ - examples/set_deployment_template_href.rb
116
138
  - examples/dev_setup.rb
117
- - examples/relaunch_deployment.rb
118
- - examples/restart_instance_agent.rb
119
139
  - examples/right_scale_ec2_instances_api_test.rb
120
- - examples/run_ebs_sequence.rb
140
+ - examples/relaunch_deployment.rb
121
141
  - examples/run_ebs_terminate.rb
122
142
  - examples/run_mysql_chef_sequence.rb
123
- - examples/run_php_chef_sequence.rb
124
- - examples/set_deployment_images.rb
125
- - examples/set_deployment_template_href.rb
143
+ - examples/run_ebs_sequence.rb
File without changes