Home > Guides > RightScale API 1.0 > Ruby RestConnection Helper

Ruby RestConnection Helper

About RestConnection

RestConnection is a Ruby Net::HTTP helper for restful requests and includes an additional library of helpers for various APIs such as RightScale.

Installation

There are several methods to install RestConnection. Users of a unix-like system on their desktop such as OS X or Linux will find the software is easy to install and can be used from a terminal emulator. Instructions for RightScale Windows Servers are also found below.

Installing from the RubyGem

UNIX-like systems
gem install rest_connection --no-rdoc --no-ri
RightScale Windows Server

From Command Prompt or Powershell, you can use the following to install RestConneciton into the RightLink sandbox:

cd "C:\Program Files (x86)\RightScale\Sandbox\Ruby\bin"
gem.bat install rest_connection --no-rdoc --no-ri

Installing from source

git clone http://github.com/rightscale/rest_connection.git
gem install jeweler rspec
rake check_dependencies
rake install

Installing with a RightScript

For RightScale Linux servers, import Install & configure RestConnection from the MultiCloud Marketplace for use as a boot, operational or any script. Several inputs are provided for to enter your RightScale user credentials (no extra configuration below required).

Installing with RightScale/EC2 API Toolbox

For Linux users, the RightScale/EC2 API Toolbox provides RestConnection as well as the EC2 AMI & API Tools out-of-box.

Installing with RightScale Windows Dev Server

For Windows users, the RightScale Windows Dev Server RL 5.7 ServerTemplate will stand up a Windows 2008 R2 server with Ruby 1.9.2, DevKit and the rest_connection RubyGem installed. Please note that the ServerTemplate only installs the gem and the configuration items detailed below will still need to be applied accordingly.

Configuration

Create user profile directory

Create the rest_connection configuration profile directory in your user home directory, or globally in /etc/rest_connection.
Ensure the permissions are secure. For EC2 instances this will usually reside in /root/.rest_connection.

e.g. Create profile for current user

[[ -e ~/.rest_connection ]] || mkdir -pv ~/.rest_connection && chmod -v 700 ~/.rest_connection

Configure yaml profile

Now, you must setup ~/.rest_connection/rest_api_config.yaml or /etc/rest_connection/rest_api_config.yaml.

Find the rest_connection RubyGem home

rc_homes=( "$(gem environment gemdir)/gems"/rest_connection* )
echo "$rc_homes"

Or, use gemedit:

gem install gemedit
gem edit rest_connection

This will show the location of your installed rest_connection RubyGem. Press :q <enter> to exit (editor is vi).

[root@CentOS-6-4 ~]# gem edit rest_connection
Opening the rest_connection gem, version 1.0.5, with vi from /usr/lib/ruby/gems/1.8/gems/rest_connection-1.0.5

Copy and edit the rest_api_config.yaml.sample into
~/.rest_connection/rest_api_config.yaml or /etc/rest_connection/rest_api_config.yaml

Fill in your connection info.
e.g. for OS X 10.6:

config=~/.rest_connection/rest_api_config.yaml
cp -v "$rc_homes"/config/rest_api_config.yaml.sample "$config"
chmod -v 700 "$config"
open "$config" || nano "$config"

Example rest_api_config.yaml    (Note: SSH key info is not required and you should always start with the sample copy)

---
:ssh_keys:
- ~/.ssh/my_server_key
- ~/.ssh/my_server_key-eu
- ~/.ssh/my_server_key-west
:pass: foobar123
:user: foo@bar.suf
:api_url: https://my.rightscale.com/api/acct/1234
:common_headers:
  X_API_VERSION: "1.0"

Configuration on RightScale Windows Servers

Create a folder, C:\etc\rest_connection then save a copy of the above template to C:\etc\rest_connection\rest_api_config.yaml.
Edit the file with your relevent credentials.

You can use RestConnection interactively via the irb in the RightLink sandbox:

cd "C:\Program Files (x86)\RightScale\Sandbox\Ruby\bin"
irb
>require 'rubygems'
>require 'rest_connection'
# rest_connection commands here

Usage Examples

Example: Fetch the server settings of 'self'

#! /usr/bin/ruby

# rs-describe-server-self

require 'rubygems'
require 'rest_connection'

instance_id = File.read('/var/spool/cloud/meta-data/instance-id')
server = Server.find_with_filter('aws_id' => "#{instance_id}")[0].settings

#server = Server.find(:all) {|server| server.settings['aws-id'] == "#{instance_id}"}		# client-side filtering=expensive and lengthy on accounts with many servers

if server
	puts "Found a server:"
	puts server.to_yaml
else
	puts 'Server not found, exiting.'
	exit 1
end

Example: Fetch a server's current instance's inputs

#!/usr/bin/ruby

require 'rubygems'
require 'rest_connection'

server_name = "My Server Nickname"

server = Server.find(:first) { |s| s.nickname =~ /#{server_name}/ }
if server.nil?
	puts 'Server not found, exiting.'
	exit 1
end
puts "Found server, '#{server.nickname}'."

server.reload_current
inputs = server.settings['parameters']

puts inputs.to_yaml

Example: Stop a Deployment

#!/usr/bin/ruby

require 'rest_connection'

deployment = Deployment.find(opts[:id])
my_servers = deployment.servers
my_servers.each { |s| s.stop }
my_servers.each { |s| s.wait_for_state("stopped") }

Example: Activate an Ec2ServerArray / Display instances IPs

#!/usr/bin/ruby

require 'rest_connection'
 
my_array = Ec2ServerArray.find(opts[:href])  
my_array.active = true
my_array.save

puts my_array.instances.map { |i| i['ip-address'] }

Example: Ping all instances in an array

my_array = Ec2ServerArray.find(1234)
#my_array = Ec2ServerArray.find(:first) { |a| a.nickname =~ /My Array/ }
my_array.instances.map.each { |i|
    ip_address = i['ip_address']
    puts "Pinging #{ip_address}."
    system("ping -c 3 #{ip_address}")
}

Example: Print server array instance # numbers

#!/usr/bin/ruby

# rs-print-array-instance-numbers

require 'rubygems'
require 'rest_connection'

array_nickname = 'RightScale Linux Server RL 5.6'    # nickname of the server array
#array_id = 1234    # or the server array id

# fetch the server array
server_array = Ec2ServerArray.find(:first) { |a| a.nickname =~ /#{array_nickname}/ }
#server_array = Ec2ServerArray.find(array_id)

# print all array instances # numbers
server_array.instances.each { |instance|
    puts instance['nickname'].split(' ').last
}
Example: Lookup and run a RightScript
#!/usr/bin/ruby

require 'rest_connection'

first_fe = Server.find(:first) { |s| s.nickname =~ /Front End/ }
st = ServerTemplate.find(first_fe.server_template_href)
connect_script = st.executables.detect { |ex| ex.name =~ /LB [app|mongrels]+ to HA proxy connect/i }
state = first_fe.run_executable(connect_script)
state.wait_for_completed

Example: Describe a deployment

#!/usr/bin/ruby

require 'rest_connection'

deployment_id = 43612
deployment = Deployment.find(deployment_id)
puts deployment.to_yaml

Example: Relaunch a server

#!/usr/bin/ruby

server_name = 'FooBar Server'
server_id = false

# get server
if server_name
  puts "Finding server: '%#{server_name}%'"
  server = Server.find(:first) { |s| s.nickname =~ /#{server_name}/ }
  puts "Found server, '#{server.nickname}'."
elsif server_id
  server = Server.find(server_id.to_i)
else
  exit
end

# relaunch server
puts "Relaunching server, '#{server.nickname}'."
server.relaunch()

Example: Search for EC2 servers with a specific tag

#!/usr/bin/ruby

# rs-search-tags

require 'rubygems'
require 'getoptlong'

def usage
  puts("usage:  rs-search-tags [options] --resource <taggable_resource> <tag>")
end

def usage_exit
  usage; exit
end

def help
  usage
  puts ''
  puts 'Searches for resources with a specific RightScale tag.'
  puts ''
  puts "examples:  rs-search-tags --resource Ec2Instance \"foo:bar=foobar\""
  puts "               - Searches for all EC2 instances with the tag, \"foo:bar=foobar\""
  puts "           rs-search-tags --resource Server \"rs_agent_dev:log_level=DEBUG\""
  puts "               - Searches for all Servers (next instance) with the tag, \"rs_agent_dev:log_level=DEBUG\""
  puts ''
  exit
end

json = false
xml = false
verbose = false
resource = false

opts = GetoptLong.new(
  [ '--resource', '-r', GetoptLong::REQUIRED_ARGUMENT ],
  [ '--xml', '-x', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--json', '-j', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--help', '-h', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT ]
)

opts.each do |opt, arg|
  case opt
    when '--resource'
      resource = arg
    when '--json'
      json = true
    when '--xml'
      xml = true
    when '--verbose'
      verbose = true
    when '--help'
      help; exit
    end
end

tag = ARGV[0] if ARGV[0]
usage_exit if !(tag || resource || ARGV[0])

require 'json'
require 'rest_connection'

tags_search = Array.new
tags_search.push(tag)

servers = Tag.search(resource, ["#{tag}"])

if json
  puts servers.to_json
elsif xml
  require 'active_support'
  #require 'active_support/core_ext'
  puts JSON.parse(servers.to_json).to_xml(:root => 'servers', :skip_instruct => true)
else
  puts servers.to_yaml
end

Example: Ping all active servers

#!/usr/bin/ruby

# rs-ping-active-servers

require 'rubygems'
require 'getoptlong'
require 'rest_connection'

def usage
  puts("rs-ping-active-servers")
    exit
end

opts = GetoptLong.new(
  [ '--private', '-p', GetoptLong::OPTIONAL_ARGUMENT ]
)

private_ip = false

opts.each do |opt, arg|
  case opt
    when '--private'
      private_ip = true
      end
end

puts 'Finding operational servers...'
servers = Server.find(:all) {|server| server.state =~ /operational/ }

ip_address = String.new
private_ip_address = false

servers.each {|server|
  server.settings
  if private_ip
    ip_address = server.private_ip_address
  else
    ip_address = server.ip_address
  end
  puts ''
  puts "-- Server: '#{server.nickname}'; AWS ID: #{server.aws_id}; IP: "+ip_address
  system("ping -c 3 #{ip_address}")
  puts ''
}

Example: Run all boot scripts on a server

#!/usr/bin/ruby

# rs-run-all-boot-executables

def usage
  puts("rs-run-all-boot-executables")
  puts("  usage:  rs-run-all-boot-executables [--id <server_id>] [--api [<api_version>]]")
end

def usage_exit
  usage; exit
end

def help
  usage
  puts ''
  puts 'Runs all boot scripts (RightScripts/Recipes) on a RightScale server, synchronously.'
  puts ''
  puts "examples:  rs-run-all-boot-execuables --id 1234 --api 1.5 --verbose"
  puts ''
  puts 'Note: Use --api 1.5 for non-EC2 servers.'
  exit
end

require 'getoptlong'

server_id = false
api_version = false
show_help = false
verbose = false

opts = GetoptLong.new(
  [ '--id', '-i', GetoptLong::REQUIRED_ARGUMENT ],
  [ '--api', '-a', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--xml', '-x', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--json', '-j', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--help', '-h', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT ]
)

opts.each do |opt, arg|
  case opt
    when '--id'
      server_id = arg
    when '--api'
      api_version = arg
    when '--help'
      show_help = true
	  when '--verbose'
      verbose = true
  end
end

help if show_help
usage_exit unless server_id

require 'rubygems'
require 'json'
require 'rest_connection'

# get server
puts "Fetching server with ID, #{server_id}."
if api_version.to_s == '1.5'
  server = McServer.find(server_id.to_i)
  server_settings = server.settings
  puts server_settings.to_yaml if verbose
  template_href = server_settings['current_instance']['links'].select { |link| link['rel'] == 'server_template' }.first['href']
  puts "ServerTemplate HREF: #{template_href}" if verbose
else
  server = Server.find(server_id.to_i)
  server_settings = server.settings
  template_href = server_settings['server_template_href']
  puts server_settings.to_yaml if verbose
end

# get template
template_id = template_href.match("[^/]+$")[0]
puts "Fetching ServerTemplate with ID, #{template_id}."
template = ServerTemplate.find(template_id.to_i)

# run executables
#puts "Executables found:\n#{template.executables.to_yaml}" if debug (todo)
puts 'Running executables.'
template.executables.each { |executable|
  unless executable['apply'] != 'boot'
    if executable['recipe']
      puts "#{executable['position']}. #{executable['recipe']}"
    elsif executable['right_script']
      puts "#{executable['position']}. #{executable['right_script']['name']}"
    end
    server.run_executable(executable)
    #state.wait_for_completed (todo)
  end
}

Example: Describe EBS volumes attached to a server

#!/usr/bin/ruby

# rs-describe-attached-vols

require 'rubygems'
require 'getoptlong'

def usage
  puts("usage:  rs-describe-attached-vols <server_nickname> [[--verbose]]")
end

def usage_exit
  usage; exit
end

def help
  usage
  puts ''
  puts 'Describes the attached volumes of a RightScale Server.'
  puts ''
  puts "examples: rs-describe-attached-vols 'Sandbox'"
  puts ''
  exit
end

opts = GetoptLong.new(
  [ '--xml', '-x', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--json', '-j', GetoptLong::OPTIONAL_ARGUMENT ]
)

json = false
xml = false
verbose = false

opts.each do |opt, arg|
  case opt
    when '--json'
      json = true
    when '--xml'
      xml = true
    when '--verbose'
      verbose = true
  	end
end

usage_exit if ! ARGV[0]

server_name = ARGV[0]
region = 'us-west-1'

require 'json'
require 'rest_connection'
require 'active_support'  #for to_xml()
#require 'xmlsimple'

# get server
if server_name
  puts "Finding server: '%#{server_name}%'"
  server = Server.find(:first) { |s| s.nickname =~ /#{server_name}/ }
  puts "Found server, '#{server.nickname}'."
elsif server_id
  server = Server.find(server_id.to_i)
else
  usage_exit
end

puts "Getting server settings for '#{server.nickname}'."
server_settings = server.settings
instance_id = server_settings['aws-id']
puts "Found instance-id, #{instance_id}."
volumes = Array.new
puts "Getting volumes for #{instance_id}."
volumes_out = `ec2-describe-volumes --region '#{region}' --filter attachment.instance-id=#{instance_id} --filter attachment.status=attached `
volumes_out.split("\n").each do |line|
  volume = Array.new
  line.split("\t").each do |value|
    volume.push(value)
  end
  volumes.push(volume)
end

#puts volumes.inspect
puts volumes.to_yaml

Example: Describe a server

#!/usr/bin/ruby

# rs-describe-server

require 'rubygems'
require 'getoptlong'

def usage
  puts("usage:  rs-describe-server --settings [current] [--name <server_nickname> | --id <server_id>]")
  puts("           [[--verbose]]")
end

def usage_exit
  usage; exit
end

def help
  usage
  puts ''
  puts 'Describes a RightScale server.'
  puts ''
  puts "examples:  rs-describe-server --id 836587 --settings current"
  puts ''
  exit
end

opts = GetoptLong.new(
  [ '--name', '-n', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--settings', '-s', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--id', '-i', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--xml', '-x', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--json', '-j', GetoptLong::OPTIONAL_ARGUMENT ]
)

server_name = false
server_id = false
settings = false
json = false
xml = false
verbose = false
server = false

opts.each do |opt, arg|
  case opt
    when '--name'
      server_name = arg
    when '--settings'
      settings = arg
      usage_exit if !(settings = 'current' || settings = 'next')
    when '--id'
      server_id = arg  
    when '--json'
      json = true
    when '--xml'
      xml = true
    when '--verbose'
      verbose = true
      end
end

usage_exit if !(server_name || server_id)

require 'json'
require 'rest_connection'

# get server
if server_name
  puts "Finding server: '%#{server_name}%'"
  server = Server.find(:first) { |s| s.nickname =~ /#{server_name}/ }
elsif server_id
  server = Server.find(server_id.to_i)
else
  usage_exit
end

if server
  puts "Found server, '#{server.nickname}'."
else
  puts "No server found!"
end

if settings
  if settings == 'next'
    server_settings = server.settings
  elsif settings == 'current'
    server.reload_current
    server_settings = server.settings
  end
  api_result = server_settings
else
  api_result = server
end

if json
  puts api_result.to_json
elsif xml
  require 'xmlsimple'
  puts JSON.parse(api_result.to_json).to_xml(:root => 'servers', :skip_instruct => true)
else
  puts api_result.to_yaml
end

Documentation

See the RestConnection RDoc.

You must to post a comment.
Last Modified
21:57, 16 May 2013

Page Rating

Was this article helpful?

Tags

This page has no custom tags.

Announcements

None

Glossary | 用語용어 Site Map | Site Help Community Corporate Site Get Support Dashboard Login
Doc Feedback Product Feedback Resources MultiCloud Marketplace Forums

Dashboard Status


© 2006-2014 RightScale, Inc. All rights reserved.
RightScale is a registered trademark of RightScale, Inc. All other products and services may be trademarks or servicemarks of their respective owners.