stingray 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/.document +5 -0
- data/Gemfile +20 -0
- data/README.rdoc +67 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/lib/stingray.rb +24 -0
- data/lib/stingray/config.rb +14 -0
- data/lib/stingray/error.rb +15 -0
- data/lib/stingray/extra.rb +41 -0
- data/lib/stingray/monitors.rb +41 -0
- data/lib/stingray/pools.rb +90 -0
- data/lib/stingray/rules.rb +42 -0
- data/lib/stingray/service_interface.rb +67 -0
- data/lib/stingray/vservers.rb +51 -0
- data/stingray.gemspec +78 -0
- data/test/helper.rb +25 -0
- data/test/pool_test.rb +37 -0
- data/test/service_interface_test.rb +83 -0
- data/test/stingray_test.rb +23 -0
- metadata +196 -0
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
gem "rest-client"
|
9
|
+
gem "json"
|
10
|
+
gem "map"
|
11
|
+
|
12
|
+
group :development do
|
13
|
+
gem "shoulda"
|
14
|
+
gem "rdoc", "~> 3.12"
|
15
|
+
gem "jeweler", "~> 1.8.4"
|
16
|
+
gem "simplecov"
|
17
|
+
gem "webmock"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
= stingray
|
2
|
+
|
3
|
+
Stingray gem for interfacing with the Riverbed Stingray loadbalancers.
|
4
|
+
|
5
|
+
|
6
|
+
== Notes
|
7
|
+
|
8
|
+
== To use the Stingray Gem
|
9
|
+
|
10
|
+
1. Install the gem
|
11
|
+
git clone git@github.com:sammarx/stingray.git
|
12
|
+
cd stingray
|
13
|
+
rake build
|
14
|
+
gem install pkg/stingray-0.0.1.gem
|
15
|
+
|
16
|
+
2. Add the following line to your Gemfile:
|
17
|
+
|
18
|
+
gem 'stingray'
|
19
|
+
|
20
|
+
3. Create a config/stingray.yml as follows
|
21
|
+
url: <base url of stingray API>
|
22
|
+
user: <username for authentication>
|
23
|
+
password: <password for authentication>
|
24
|
+
|
25
|
+
The URL must be the full path to the Stingray REST endpoint -
|
26
|
+
eg.
|
27
|
+
https://<stingray hostname>:<REST port>/api/tm/1.0/config/active/
|
28
|
+
|
29
|
+
PUT and DELETE operations will only work over HTTPS.
|
30
|
+
|
31
|
+
== Examples
|
32
|
+
|
33
|
+
Set up a connection to the Stingray Load Balancer
|
34
|
+
|
35
|
+
Stingray.config(YAML.load(File.read('config/stingray.yml'))
|
36
|
+
|
37
|
+
Initialize a new pool
|
38
|
+
p=Stingray::Pool.new
|
39
|
+
|
40
|
+
Create a pool
|
41
|
+
p.create('test-pool')
|
42
|
+
|
43
|
+
Add a node (server) to the pool. Takes an array of hosts. The hosts must be reachable from the Load Balancer.
|
44
|
+
p.add_nodes_to_pool('[test1.example.com, test2.example.com]')
|
45
|
+
|
46
|
+
Save the pool. This sends a PUT request to the REST API. No changes to the pool will be commited until the pool is saved.
|
47
|
+
p.save
|
48
|
+
|
49
|
+
List all existing pools
|
50
|
+
p.pools => ["test-pool"]
|
51
|
+
|
52
|
+
Get a pool
|
53
|
+
p.pool('test-pool')
|
54
|
+
|
55
|
+
Delete a node (server) from the pool. Takes an array of hosts.
|
56
|
+
p.delete_nodes_from_pool('[test2.example.com]')
|
57
|
+
|
58
|
+
Delete a pool. This is an immediate action.
|
59
|
+
p.delete
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
* I'm still working on writing tests.
|
64
|
+
|
65
|
+
== License
|
66
|
+
Under the {MIT License}[http://www.opensource.org/licenses/MIT].
|
67
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "stingray"
|
18
|
+
gem.homepage = "http://github.com/sammarx/stingray"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Stingray gem for interfacing with the Riverbed Stingray loadbalancers.}
|
21
|
+
gem.description = %Q{Stingray gem for interfacing with the Riverbed Stingray loadbalancers.}
|
22
|
+
gem.email = "smarx@thirdspacephoto.com"
|
23
|
+
gem.authors = ["Sam Marx"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/*_test.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
task :default => :test
|
37
|
+
|
38
|
+
require 'rdoc/task'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "stingray #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/stingray.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
require 'map'
|
4
|
+
require_relative "stingray/error"
|
5
|
+
require_relative "stingray/service_interface"
|
6
|
+
require_relative "stingray/config"
|
7
|
+
require_relative "stingray/pools"
|
8
|
+
require_relative "stingray/extra"
|
9
|
+
require_relative "stingray/vservers"
|
10
|
+
require_relative "stingray/monitors"
|
11
|
+
require_relative "stingray/rules"
|
12
|
+
|
13
|
+
|
14
|
+
module Stingray
|
15
|
+
class << self
|
16
|
+
def config(options = {})
|
17
|
+
@@config||=Stingray::Config.new(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Stingray
|
2
|
+
class Config
|
3
|
+
|
4
|
+
# Give us a standard interface for all of the sub modules.
|
5
|
+
def initialize(args={})
|
6
|
+
args.each do |key,val|
|
7
|
+
self.class.__send__(:attr_accessor,"#{key}")
|
8
|
+
instance_variable_set("@#{key}",val)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Stingray
|
2
|
+
class Error < Exception
|
3
|
+
attr_reader :rest_exception
|
4
|
+
def initialize(rest_exception)
|
5
|
+
super(rest_exception.message)
|
6
|
+
@rest_exception = rest_exception
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class NotFoundError < Error
|
11
|
+
def initialize(rest_exception)
|
12
|
+
super(rest_exception)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Stingray
|
2
|
+
class Extra
|
3
|
+
include Stingray::ServiceInterface
|
4
|
+
attr_accessor :name, :file, :files, :content
|
5
|
+
|
6
|
+
# Get a list of all files
|
7
|
+
def files
|
8
|
+
@files=get_endpoint('extra').keys
|
9
|
+
end
|
10
|
+
|
11
|
+
# get one specific file
|
12
|
+
def file(name)
|
13
|
+
begin
|
14
|
+
@name=name
|
15
|
+
@content=get_rest("extra/#{@name}")
|
16
|
+
rescue Stingray::NotFoundError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# create a new file
|
22
|
+
def create(name,content='')
|
23
|
+
@name=name
|
24
|
+
@content=content
|
25
|
+
end
|
26
|
+
|
27
|
+
# Save the current file.
|
28
|
+
def save
|
29
|
+
return if @content.nil?
|
30
|
+
put_rest "extra/#{@name}", @content, :content_type => "application/octet-stream"
|
31
|
+
end
|
32
|
+
|
33
|
+
# destroy the current file.
|
34
|
+
def destroy
|
35
|
+
return if @name.nil?
|
36
|
+
delete_rest "extra/#{@name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Stingray
|
2
|
+
class Monitor
|
3
|
+
include Stingray::ServiceInterface
|
4
|
+
attr_accessor :name, :monitor, :monitors, :monitor_hash
|
5
|
+
|
6
|
+
# Get a list of all monitors
|
7
|
+
def monitors
|
8
|
+
@monitors=get_endpoint('monitors').keys
|
9
|
+
end
|
10
|
+
|
11
|
+
# get one specific monitor
|
12
|
+
def monitor(name)
|
13
|
+
begin
|
14
|
+
@name=name
|
15
|
+
@monitor_hash=get_endpoint("monitors/#{@name}")
|
16
|
+
rescue Stingray::NotFoundError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# create a new monitor
|
22
|
+
def create(name)
|
23
|
+
@name=name
|
24
|
+
@monitor_hash=Map.new.set(:properties, :basic, :http, :path)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Save the current monitor.
|
28
|
+
def save
|
29
|
+
return if @monitor_hash.nil?
|
30
|
+
put_rest "monitors/#{@name}", @monitor_hash, :content_type => "application/json"
|
31
|
+
end
|
32
|
+
|
33
|
+
# destroy the current monitor.
|
34
|
+
def destroy
|
35
|
+
return if @name.nil?
|
36
|
+
delete_rest "monitors/#{@name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Stingray
|
2
|
+
|
3
|
+
|
4
|
+
class Pool
|
5
|
+
|
6
|
+
include Stingray::ServiceInterface
|
7
|
+
|
8
|
+
attr_accessor :name, :pool_hash, :pools, :pool, :nodes, :monitors, :note
|
9
|
+
|
10
|
+
|
11
|
+
# List all available pools
|
12
|
+
def pools
|
13
|
+
@pools=get_endpoint("pools").keys
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get a named pool
|
17
|
+
def pool(name)
|
18
|
+
begin
|
19
|
+
@name=name
|
20
|
+
@pool_hash=get_endpoint("pools/#{@name}")
|
21
|
+
rescue Stingray::NotFoundError
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create a new pool
|
27
|
+
def create(name)
|
28
|
+
@name=name
|
29
|
+
@pool_hash=Map.new.set(:properties, :basic, :nodes,[])
|
30
|
+
end
|
31
|
+
|
32
|
+
# list the nodes of a pool
|
33
|
+
def nodes
|
34
|
+
@nodes=@pool_hash.properties.basic.nodes || []
|
35
|
+
end
|
36
|
+
|
37
|
+
# set nodes
|
38
|
+
def nodes=(node_arr)
|
39
|
+
@pool_hash.properties.basic.nodes=node_arr
|
40
|
+
end
|
41
|
+
|
42
|
+
# list monitors for a pool
|
43
|
+
def monitors
|
44
|
+
@monitors=@pool_hash.properties.basic.monitors || []
|
45
|
+
end
|
46
|
+
|
47
|
+
# monitors
|
48
|
+
def monitors=(monitor_arr)
|
49
|
+
@monitors=@pool_hash.properties.basic.monitors=monitor_arr
|
50
|
+
end
|
51
|
+
|
52
|
+
# notes
|
53
|
+
def note
|
54
|
+
@note=@pool_hash.properties.basic.note
|
55
|
+
end
|
56
|
+
|
57
|
+
def note=(note)
|
58
|
+
@pool_hash.properties.basic.note=note
|
59
|
+
end
|
60
|
+
|
61
|
+
# add an array of nodes to the pool
|
62
|
+
def add_nodes_to_pool(node_arr)
|
63
|
+
current_nodes=nodes
|
64
|
+
node_arr.map {|node| current_nodes << node unless current_nodes.include?(node)}
|
65
|
+
nodes=current_nodes.uniq
|
66
|
+
end
|
67
|
+
|
68
|
+
# delete an array of nodes from the pool
|
69
|
+
def delete_nodes_from_pool(node_arr)
|
70
|
+
current_nodes=nodes
|
71
|
+
node_arr.map {|node| current_nodes.delete(node)if current_nodes.include?(node)}
|
72
|
+
nodes=current_nodes.uniq
|
73
|
+
end
|
74
|
+
|
75
|
+
# Delete a pool.
|
76
|
+
def destroy
|
77
|
+
return false if @name.nil?
|
78
|
+
delete_rest "pools/#{@name}"
|
79
|
+
true
|
80
|
+
end
|
81
|
+
|
82
|
+
# Save the current pool.
|
83
|
+
def save
|
84
|
+
return false if @pool_hash.nil?
|
85
|
+
put_rest "pools/#{@name}", @pool_hash.to_json, :content_type => "application/json"
|
86
|
+
true
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Stingray
|
2
|
+
class Rule
|
3
|
+
|
4
|
+
include Stingray::ServiceInterface
|
5
|
+
attr_accessor :name, :rule, :rules, :content
|
6
|
+
|
7
|
+
# Get a list of all rules
|
8
|
+
def rules
|
9
|
+
@rules=get_endpoint('rule').keys
|
10
|
+
end
|
11
|
+
|
12
|
+
# get one specific rule
|
13
|
+
def rule(name)
|
14
|
+
begin
|
15
|
+
@name=name
|
16
|
+
@content=get_rest "rules/#{@name}"
|
17
|
+
rescue Stingray::NotFoundError
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# create a new rule
|
23
|
+
def create(name,content='')
|
24
|
+
@name=name
|
25
|
+
@content=content
|
26
|
+
end
|
27
|
+
|
28
|
+
# Save the current rule.
|
29
|
+
def save
|
30
|
+
return if @content.nil?
|
31
|
+
put_rest "rules/#{@name}", @content, :content_type => "application/octet-stream"
|
32
|
+
end
|
33
|
+
|
34
|
+
# destroy the current rule.
|
35
|
+
def destroy
|
36
|
+
return if @name.nil?
|
37
|
+
delete_rest "rules/#{@name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Stingray
|
2
|
+
module ServiceInterface
|
3
|
+
|
4
|
+
def initialize(args={})
|
5
|
+
# Iterate over the existing config, if one exists, and set instance variables for the current object
|
6
|
+
config=Stingray.config
|
7
|
+
config.instance_variables.each do |var|
|
8
|
+
instance_variable_set("#{var}",config.instance_variable_get("#{var}"))
|
9
|
+
end
|
10
|
+
# Allow override of individual variables
|
11
|
+
args.each do |key,val|
|
12
|
+
self.class.__send__(:attr_accessor,"#{key}")
|
13
|
+
instance_variable_set("@#{key}",val)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
%w(get delete).each do |verb|
|
19
|
+
define_method("#{verb}_rest") do |path|
|
20
|
+
begin
|
21
|
+
rest[URI.escape(path)].send(verb)
|
22
|
+
rescue RestClient::Exception => e
|
23
|
+
raise_error(e)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
%w(post put).each do |verb|
|
29
|
+
define_method("#{verb}_rest") do |path, content, opts|
|
30
|
+
begin
|
31
|
+
rest[URI.escape(path)].send(verb, content, opts)
|
32
|
+
rescue RestClient::Exception => e
|
33
|
+
raise_error(e)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Default REST object
|
39
|
+
def rest
|
40
|
+
@rest||=RestClient::Resource.new(URI.escape(@url),:user => @user, :password => @password)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Parse out the endpoint
|
44
|
+
def get_endpoint(endpoint='')
|
45
|
+
r=self.get_rest(endpoint)
|
46
|
+
actions={}
|
47
|
+
response=Map.new(JSON.parse(r))
|
48
|
+
if response.respond_to?(:children)
|
49
|
+
response.children.map{|k| actions[k.values.first]=k.values.last} unless error
|
50
|
+
actions
|
51
|
+
else
|
52
|
+
response
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def raise_error(e)
|
59
|
+
if e.is_a? RestClient::ResourceNotFound
|
60
|
+
raise NotFoundError.new(e)
|
61
|
+
else
|
62
|
+
raise Error.new(e)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Stingray
|
2
|
+
class Vserver
|
3
|
+
include Stingray::ServiceInterface
|
4
|
+
attr_accessor :name, :vserver, :vservers, :vserver_hash, :pool
|
5
|
+
|
6
|
+
# Get a list of all vservers
|
7
|
+
def vservers
|
8
|
+
@vservers=get_endpoint('vservers').keys
|
9
|
+
end
|
10
|
+
|
11
|
+
# get one specific vserver
|
12
|
+
def vserver(name)
|
13
|
+
begin
|
14
|
+
@name=name
|
15
|
+
@vserver_hash=get_endpoint("vservers/#{@name}")
|
16
|
+
rescue Stingray::NotFoundError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# default pool for vserver
|
22
|
+
def pool
|
23
|
+
@pool=@vserver_hash.properties.basic.pool
|
24
|
+
end
|
25
|
+
|
26
|
+
# set pool for vserver
|
27
|
+
def pool=(pool)
|
28
|
+
@vserver_hash.properties.basic.pool=pool
|
29
|
+
end
|
30
|
+
|
31
|
+
# create a new vserver
|
32
|
+
def create(name)
|
33
|
+
@name=name
|
34
|
+
@vserver_hash=Map.new.set(:properties, :basic, :pool)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Save the current vserver.
|
38
|
+
def save
|
39
|
+
return if @vserver_hash.nil?
|
40
|
+
put_rest "vservers/#{@name}", @vserver_hash.to_json, :content_type => "application/json"
|
41
|
+
end
|
42
|
+
|
43
|
+
# destroy the current vserver.
|
44
|
+
def destroy
|
45
|
+
return if @name.nil?
|
46
|
+
delete_rest "vservers/#{@name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/stingray.gemspec
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "stingray"
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Sam Marx"]
|
12
|
+
s.date = "2014-02-13"
|
13
|
+
s.description = "Stingray gem for interfacing with the Riverbed Stingray loadbalancers."
|
14
|
+
s.email = "smarx@thirdspacephoto.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".document",
|
20
|
+
"Gemfile",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"lib/stingray.rb",
|
25
|
+
"lib/stingray/config.rb",
|
26
|
+
"lib/stingray/error.rb",
|
27
|
+
"lib/stingray/extra.rb",
|
28
|
+
"lib/stingray/monitors.rb",
|
29
|
+
"lib/stingray/pools.rb",
|
30
|
+
"lib/stingray/rules.rb",
|
31
|
+
"lib/stingray/service_interface.rb",
|
32
|
+
"lib/stingray/vservers.rb",
|
33
|
+
"stingray.gemspec",
|
34
|
+
"test/helper.rb",
|
35
|
+
"test/pool_test.rb",
|
36
|
+
"test/service_interface_test.rb",
|
37
|
+
"test/stingray_test.rb"
|
38
|
+
]
|
39
|
+
s.homepage = "http://github.com/sammarx/stingray"
|
40
|
+
s.licenses = ["MIT"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = "1.8.25"
|
43
|
+
s.summary = "Stingray gem for interfacing with the Riverbed Stingray loadbalancers."
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<rest-client>, [">= 0"])
|
50
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
51
|
+
s.add_runtime_dependency(%q<map>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
53
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
54
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
55
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
56
|
+
s.add_development_dependency(%q<webmock>, [">= 0"])
|
57
|
+
else
|
58
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
59
|
+
s.add_dependency(%q<json>, [">= 0"])
|
60
|
+
s.add_dependency(%q<map>, [">= 0"])
|
61
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
62
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
63
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
64
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
65
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<rest-client>, [">= 0"])
|
69
|
+
s.add_dependency(%q<json>, [">= 0"])
|
70
|
+
s.add_dependency(%q<map>, [">= 0"])
|
71
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
72
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
74
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
75
|
+
s.add_dependency(%q<webmock>, [">= 0"])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
require 'webmock/test_unit'
|
13
|
+
|
14
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
16
|
+
$print_runs = ENV['DEBUG']
|
17
|
+
require 'stingray'
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
Stingray.class_variable_set(:@@config, nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/test/pool_test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Stingray
|
4
|
+
class PoolTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context 'has config and pool' do
|
7
|
+
setup do
|
8
|
+
@config = Stingray.config({:url => "http://localhost/", :user => "user", :password => "password"})
|
9
|
+
@client = Pool.new
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'a pool returns 404' do
|
13
|
+
setup do
|
14
|
+
stub_request(:get, "http://user:password@localhost/pools/blah").to_return(status: 404, body: 'bawdy')
|
15
|
+
@pool = @client.pool('blah')
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'return nil' do
|
19
|
+
assert_nil @pool
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'a pool returns 200' do
|
24
|
+
setup do
|
25
|
+
stub_request(:get, "http://user:password@localhost/pools/blah").to_return(status: 200, body: "{\"prop\":\"meh\"}")
|
26
|
+
@pool = @client.pool('blah')
|
27
|
+
end
|
28
|
+
|
29
|
+
should 'return pool hash' do
|
30
|
+
assert 'meh', @pool[:prop]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Stingray
|
4
|
+
|
5
|
+
class Client
|
6
|
+
include ServiceInterface
|
7
|
+
end
|
8
|
+
|
9
|
+
class ServiceInterfaceTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
context 'has config and client' do
|
12
|
+
setup do
|
13
|
+
@config = Stingray.config({:url => "http://localhost/", :user => "user", :password => "password"})
|
14
|
+
@client = Client.new
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'get_rest with success' do
|
18
|
+
setup do
|
19
|
+
stub_request(:get, "http://user:password@localhost/path").to_return(status: 200, body: 'bawdy')
|
20
|
+
@response = @client.get_rest('path')
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'return response as string' do
|
24
|
+
assert_equal 'bawdy', @response
|
25
|
+
assert_equal 200, @response.code
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
context 'get_rest with 404 response' do
|
31
|
+
setup do
|
32
|
+
stub_request(:get, "http://user:password@localhost/pathtown").to_return(status: 404, body: 'errortown')
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'throw Stingray::NotFoundError and retain rest exception' do
|
36
|
+
error = assert_raise(Stingray::NotFoundError){ @client.get_rest('pathtown') }
|
37
|
+
assert error.rest_exception.is_a?(RestClient::ResourceNotFound)
|
38
|
+
assert_equal "404 Resource Not Found", error.message
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'get_endpoint with success and parsable json' do
|
43
|
+
setup do
|
44
|
+
stub_request(:get, "http://user:password@localhost/path").to_return(status: 200, body: "{\"prop\":\"meh\"}")
|
45
|
+
@response = @client.get_endpoint('path')
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'return a hash' do
|
49
|
+
assert_equal 'meh', @response[:prop]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'get_endpoint with 404' do
|
54
|
+
setup do
|
55
|
+
stub_request(:get, "http://user:password@localhost/pathtown").to_return(status: 404, body: 'errortown')
|
56
|
+
end
|
57
|
+
|
58
|
+
should 'throw Stingray::NotFoundError and retain rest exception' do
|
59
|
+
error = assert_raise(Stingray::NotFoundError){ @client.get_rest('pathtown') }
|
60
|
+
assert error.rest_exception.is_a?(RestClient::ResourceNotFound)
|
61
|
+
assert_equal "404 Resource Not Found", error.message
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'get_endpoint with 401 unauthorized' do
|
66
|
+
setup do
|
67
|
+
stub_request(:get, "http://user:password@localhost/pathtown").to_return(status: 401, body: 'errortown')
|
68
|
+
end
|
69
|
+
|
70
|
+
should 'throw Stingray::Error and retain rest exception' do
|
71
|
+
error = assert_raise(Stingray::Error){ @client.get_rest('pathtown') }
|
72
|
+
assert error.rest_exception.is_a?(RestClient::Unauthorized)
|
73
|
+
assert_equal "401 Unauthorized", error.message
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
|
4
|
+
module Stingray
|
5
|
+
class TestStingray < Test::Unit::TestCase
|
6
|
+
|
7
|
+
should 'return a config object' do
|
8
|
+
assert Stingray.config.is_a?(Stingray::Config)
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'pass arguments through #config' do
|
12
|
+
assert Stingray.config({:url => "urltest", :user => "user", :password => "password"}).is_a?(Stingray::Config)
|
13
|
+
assert_equal 'urltest', Stingray.config.url
|
14
|
+
assert_equal 'user', Stingray.config.user
|
15
|
+
assert_equal 'password', Stingray.config.password
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'return same config when no options are added' do
|
19
|
+
assert_equal Stingray.config, Stingray.config
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stingray
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sam Marx
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-02-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: json
|
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: map
|
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: shoulda
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
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: rdoc
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '3.12'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '3.12'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: jeweler
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.8.4
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.8.4
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: simplecov
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: webmock
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
description: Stingray gem for interfacing with the Riverbed Stingray loadbalancers.
|
143
|
+
email: smarx@thirdspacephoto.com
|
144
|
+
executables: []
|
145
|
+
extensions: []
|
146
|
+
extra_rdoc_files:
|
147
|
+
- README.rdoc
|
148
|
+
files:
|
149
|
+
- .document
|
150
|
+
- Gemfile
|
151
|
+
- README.rdoc
|
152
|
+
- Rakefile
|
153
|
+
- VERSION
|
154
|
+
- lib/stingray.rb
|
155
|
+
- lib/stingray/config.rb
|
156
|
+
- lib/stingray/error.rb
|
157
|
+
- lib/stingray/extra.rb
|
158
|
+
- lib/stingray/monitors.rb
|
159
|
+
- lib/stingray/pools.rb
|
160
|
+
- lib/stingray/rules.rb
|
161
|
+
- lib/stingray/service_interface.rb
|
162
|
+
- lib/stingray/vservers.rb
|
163
|
+
- stingray.gemspec
|
164
|
+
- test/helper.rb
|
165
|
+
- test/pool_test.rb
|
166
|
+
- test/service_interface_test.rb
|
167
|
+
- test/stingray_test.rb
|
168
|
+
homepage: http://github.com/sammarx/stingray
|
169
|
+
licenses:
|
170
|
+
- MIT
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options: []
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
none: false
|
177
|
+
requirements:
|
178
|
+
- - ! '>='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
segments:
|
182
|
+
- 0
|
183
|
+
hash: 1658474743644664583
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
requirements: []
|
191
|
+
rubyforge_project:
|
192
|
+
rubygems_version: 1.8.25
|
193
|
+
signing_key:
|
194
|
+
specification_version: 3
|
195
|
+
summary: Stingray gem for interfacing with the Riverbed Stingray loadbalancers.
|
196
|
+
test_files: []
|