collins_client 0.2.7
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/Gemfile +15 -0
- data/Gemfile.lock +50 -0
- data/README.md +46 -0
- data/Rakefile +66 -0
- data/VERSION +1 -0
- data/collins_client.gemspec +73 -0
- data/lib/collins/address.rb +74 -0
- data/lib/collins/api.rb +119 -0
- data/lib/collins/api/admin.rb +19 -0
- data/lib/collins/api/asset.rb +184 -0
- data/lib/collins/api/asset_state.rb +85 -0
- data/lib/collins/api/attributes.rb +76 -0
- data/lib/collins/api/ip_address.rb +87 -0
- data/lib/collins/api/logging.rb +137 -0
- data/lib/collins/api/management.rb +84 -0
- data/lib/collins/api/tag.rb +46 -0
- data/lib/collins/api/util.rb +28 -0
- data/lib/collins/api/util/errors.rb +45 -0
- data/lib/collins/api/util/parameters.rb +44 -0
- data/lib/collins/api/util/requests.rb +136 -0
- data/lib/collins/api/util/responses.rb +46 -0
- data/lib/collins/asset.rb +311 -0
- data/lib/collins/asset_client.rb +57 -0
- data/lib/collins/client.rb +100 -0
- data/lib/collins/errors.rb +56 -0
- data/lib/collins/ipmi.rb +41 -0
- data/lib/collins/logging.rb +33 -0
- data/lib/collins/monkeypatch.rb +24 -0
- data/lib/collins/option.rb +220 -0
- data/lib/collins/power.rb +99 -0
- data/lib/collins/profile.rb +73 -0
- data/lib/collins/simple_callback.rb +141 -0
- data/lib/collins/state.rb +50 -0
- data/lib/collins/util.rb +145 -0
- data/lib/collins_client.rb +7 -0
- metadata +100 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.2)
|
5
|
+
crack (0.3.1)
|
6
|
+
diff-lcs (1.1.3)
|
7
|
+
git (1.2.5)
|
8
|
+
httparty (0.8.3)
|
9
|
+
multi_json (~> 1.0)
|
10
|
+
multi_xml
|
11
|
+
jeweler (1.8.4)
|
12
|
+
bundler (~> 1.0)
|
13
|
+
git (>= 1.2.5)
|
14
|
+
rake
|
15
|
+
rdoc
|
16
|
+
json (1.7.5)
|
17
|
+
multi_json (1.3.6)
|
18
|
+
multi_xml (0.5.1)
|
19
|
+
rake (0.9.2.2)
|
20
|
+
rdoc (3.12)
|
21
|
+
json (~> 1.4)
|
22
|
+
redcarpet (2.1.1)
|
23
|
+
rspec (2.11.0)
|
24
|
+
rspec-core (~> 2.11.0)
|
25
|
+
rspec-expectations (~> 2.11.0)
|
26
|
+
rspec-mocks (~> 2.11.0)
|
27
|
+
rspec-core (2.11.1)
|
28
|
+
rspec-expectations (2.11.3)
|
29
|
+
diff-lcs (~> 1.1.3)
|
30
|
+
rspec-mocks (2.11.3)
|
31
|
+
simplecov (0.6.4)
|
32
|
+
multi_json (~> 1.0)
|
33
|
+
simplecov-html (~> 0.5.3)
|
34
|
+
simplecov-html (0.5.3)
|
35
|
+
webmock (1.8.10)
|
36
|
+
addressable (>= 2.2.7)
|
37
|
+
crack (>= 0.1.7)
|
38
|
+
yard (0.8.2.1)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
ruby
|
42
|
+
|
43
|
+
DEPENDENCIES
|
44
|
+
httparty (~> 0.8.3)
|
45
|
+
jeweler (~> 1.8.3)
|
46
|
+
redcarpet
|
47
|
+
rspec
|
48
|
+
simplecov
|
49
|
+
webmock
|
50
|
+
yard
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Collins::Client
|
2
|
+
|
3
|
+
The collins-service gem provides a library for API access to Collins.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
First install rvm
|
8
|
+
|
9
|
+
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
|
10
|
+
$ source ~/.bash_profile
|
11
|
+
$ rvm requirements
|
12
|
+
$ rvm install 1.9.3
|
13
|
+
$ rvm use 1.9.3
|
14
|
+
|
15
|
+
Install the collins gem and use it
|
16
|
+
|
17
|
+
$ gem install --source=http://repo.tumblr.net:9929/ collins_client
|
18
|
+
|
19
|
+
Remember, if you don't have 1.9.3 set as the default, before you use collins you'll need to do `rvm use 1.9.3`.
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
#!/usr/bin/env ruby
|
24
|
+
require 'collins_client'
|
25
|
+
config = {:username => "foo", :password => "bar", :host => "http://127.0.0.1:8080"}
|
26
|
+
client = Collins::Client.new config
|
27
|
+
client.find :HOSTNAME => /^abc.*/
|
28
|
+
|
29
|
+
## Note for developers
|
30
|
+
|
31
|
+
If you are implementing support for a new API endpoint, and that endpoint
|
32
|
+
requires an asset tag, please observe the standard of having the method
|
33
|
+
parameter be named `asset_or_tag`. For instance do:
|
34
|
+
|
35
|
+
def new_method asset_or_tag
|
36
|
+
# some work
|
37
|
+
end
|
38
|
+
|
39
|
+
and not
|
40
|
+
|
41
|
+
def new_method an_asset
|
42
|
+
# some work
|
43
|
+
end
|
44
|
+
|
45
|
+
The `AssetClient` class depends on this naming convention to know how to
|
46
|
+
appropriately proxy method calls to the collins client instance.
|
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
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
|
+
require 'jeweler'
|
14
|
+
require 'yard'
|
15
|
+
|
16
|
+
jeweler = Jeweler::Tasks.new do |gem|
|
17
|
+
gem.name = 'collins_client'
|
18
|
+
gem.homepage = 'https://github.com/tumblr/collins/tree/master/support/ruby/collins-client'
|
19
|
+
gem.license = 'APL 2.0'
|
20
|
+
gem.summary = %Q{Client library for Collins API}
|
21
|
+
gem.description = "Provides ruby support for interacting with the Collins API"
|
22
|
+
gem.email = 'bmatheny@tumblr.com'
|
23
|
+
gem.authors = ['Blake Matheny']
|
24
|
+
gem.files.exclude "spec/**/*"
|
25
|
+
gem.files.exclude '.gitignore'
|
26
|
+
gem.files.exclude '.rspec'
|
27
|
+
gem.files.exclude '.rvmrc'
|
28
|
+
gem.add_runtime_dependency 'httparty', '~> 0.8.3'
|
29
|
+
end
|
30
|
+
|
31
|
+
task :help do
|
32
|
+
puts("rake -T # See available rake tasks")
|
33
|
+
puts("rake publish # generate gemspec, build it, push it to repo")
|
34
|
+
puts("rake version:bump:patch # Bump patch number")
|
35
|
+
puts("rake all # bump patch and publish")
|
36
|
+
puts("rake # Run tests")
|
37
|
+
end
|
38
|
+
|
39
|
+
task :publish => [:gemspec, :build] do
|
40
|
+
package_abs = jeweler.jeweler.gemspec_helper.gem_path
|
41
|
+
package_name = File.basename(package_abs)
|
42
|
+
|
43
|
+
["repo.tumblr.net","repo.ewr01.tumblr.net"].each do |host|
|
44
|
+
puts("Copying #{package_abs} to #{host} and installing, you may be prompted for your password")
|
45
|
+
system "scp #{package_abs} #{host}:"
|
46
|
+
system "ssh -t #{host} 'sudo tumblr_gem install #{package_name}'"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
task :all => ["version:bump:patch", :publish] do
|
51
|
+
puts("Done!")
|
52
|
+
end
|
53
|
+
|
54
|
+
require 'rspec/core'
|
55
|
+
require 'rspec/core/rake_task'
|
56
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
57
|
+
spec.fail_on_error = false
|
58
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
59
|
+
end
|
60
|
+
|
61
|
+
task :default => :spec
|
62
|
+
|
63
|
+
YARD::Rake::YardocTask.new do |t|
|
64
|
+
t.files = ['lib/**/*.rb']
|
65
|
+
t.options = ['--markup', 'markdown']
|
66
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.7
|
@@ -0,0 +1,73 @@
|
|
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 = "collins_client"
|
8
|
+
s.version = "0.2.7"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Blake Matheny"]
|
12
|
+
s.date = "2012-10-31"
|
13
|
+
s.description = "Provides ruby support for interacting with the Collins API"
|
14
|
+
s.email = "bmatheny@tumblr.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"Gemfile",
|
20
|
+
"Gemfile.lock",
|
21
|
+
"README.md",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"collins_client.gemspec",
|
25
|
+
"lib/collins/address.rb",
|
26
|
+
"lib/collins/api.rb",
|
27
|
+
"lib/collins/api/admin.rb",
|
28
|
+
"lib/collins/api/asset.rb",
|
29
|
+
"lib/collins/api/asset_state.rb",
|
30
|
+
"lib/collins/api/attributes.rb",
|
31
|
+
"lib/collins/api/ip_address.rb",
|
32
|
+
"lib/collins/api/logging.rb",
|
33
|
+
"lib/collins/api/management.rb",
|
34
|
+
"lib/collins/api/tag.rb",
|
35
|
+
"lib/collins/api/util.rb",
|
36
|
+
"lib/collins/api/util/errors.rb",
|
37
|
+
"lib/collins/api/util/parameters.rb",
|
38
|
+
"lib/collins/api/util/requests.rb",
|
39
|
+
"lib/collins/api/util/responses.rb",
|
40
|
+
"lib/collins/asset.rb",
|
41
|
+
"lib/collins/asset_client.rb",
|
42
|
+
"lib/collins/client.rb",
|
43
|
+
"lib/collins/errors.rb",
|
44
|
+
"lib/collins/ipmi.rb",
|
45
|
+
"lib/collins/logging.rb",
|
46
|
+
"lib/collins/monkeypatch.rb",
|
47
|
+
"lib/collins/option.rb",
|
48
|
+
"lib/collins/power.rb",
|
49
|
+
"lib/collins/profile.rb",
|
50
|
+
"lib/collins/simple_callback.rb",
|
51
|
+
"lib/collins/state.rb",
|
52
|
+
"lib/collins/util.rb",
|
53
|
+
"lib/collins_client.rb"
|
54
|
+
]
|
55
|
+
s.homepage = "https://github.com/tumblr/collins/tree/master/support/ruby/collins-client"
|
56
|
+
s.licenses = ["APL 2.0"]
|
57
|
+
s.require_paths = ["lib"]
|
58
|
+
s.rubygems_version = "1.8.24"
|
59
|
+
s.summary = "Client library for Collins API"
|
60
|
+
|
61
|
+
if s.respond_to? :specification_version then
|
62
|
+
s.specification_version = 3
|
63
|
+
|
64
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
65
|
+
s.add_runtime_dependency(%q<httparty>, ["~> 0.8.3"])
|
66
|
+
else
|
67
|
+
s.add_dependency(%q<httparty>, ["~> 0.8.3"])
|
68
|
+
end
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<httparty>, ["~> 0.8.3"])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Collins
|
2
|
+
|
3
|
+
class Address
|
4
|
+
include Collins::Util
|
5
|
+
|
6
|
+
attr_accessor :id, :asset_id, :address, :gateway, :netmask, :pool
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def from_json json
|
10
|
+
return [] if json.nil? || json.empty?
|
11
|
+
if not json.is_a?(Array) then
|
12
|
+
json = [json]
|
13
|
+
end
|
14
|
+
json.map { |j| Collins::Address.new j }
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_private? address
|
18
|
+
if address =~ /^10\./ then
|
19
|
+
true
|
20
|
+
elsif address =~ /^192\.168\./ then
|
21
|
+
true
|
22
|
+
elsif address =~ /^172\.(?:1[6-9]|2[0-9]|3[0-1])\./ then
|
23
|
+
true
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def is_public? address
|
29
|
+
not is_private?(address)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize model = {}
|
34
|
+
hash = symbolize_hash(model).inject({}) do |result, (k,v)|
|
35
|
+
result[k.downcase] = v
|
36
|
+
result
|
37
|
+
end
|
38
|
+
@id = hash[:id].to_s.to_i
|
39
|
+
@asset_id = hash[:asset_id].to_s.to_i
|
40
|
+
@address = hash[:address].to_s
|
41
|
+
@gateway = hash[:gateway].to_s
|
42
|
+
@netmask = hash[:netmask].to_s
|
43
|
+
@pool = hash[:pool].to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_addressable?
|
47
|
+
@address.length > 0
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_private?
|
51
|
+
Collins::Address.is_private? @address
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_public?
|
55
|
+
is_addressable? and not is_private?
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_hash
|
59
|
+
{
|
60
|
+
:address => @address,
|
61
|
+
:gateway => @gateway,
|
62
|
+
:netmask => @netmask,
|
63
|
+
:pool => @pool,
|
64
|
+
:is_private => is_private?,
|
65
|
+
:is_public => is_public?
|
66
|
+
}
|
67
|
+
end
|
68
|
+
def to_s
|
69
|
+
"Collins::Address(address = %{address}, gateway = %{gateway}, netmask = %{netmask}, is_private = %{is_private})" % to_hash
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/lib/collins/api.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'collins/api/admin'
|
2
|
+
require 'collins/api/asset'
|
3
|
+
require 'collins/api/asset_state'
|
4
|
+
require 'collins/api/attributes'
|
5
|
+
require 'collins/api/ip_address'
|
6
|
+
require 'collins/api/logging'
|
7
|
+
require 'collins/api/management'
|
8
|
+
require 'collins/api/tag'
|
9
|
+
require 'collins/api/util'
|
10
|
+
|
11
|
+
module Collins
|
12
|
+
module Api
|
13
|
+
|
14
|
+
# Provides get_asset_or_tag, require stuff, and symbolize
|
15
|
+
include Collins::Util
|
16
|
+
|
17
|
+
# @abstract
|
18
|
+
# @return [Hash<String,String>] hash with header keys/values
|
19
|
+
def headers
|
20
|
+
raise NotImplementedError.new("Classes including the Api module must provide a headers hash")
|
21
|
+
end
|
22
|
+
|
23
|
+
# @abstract
|
24
|
+
# @return [String] the collins host
|
25
|
+
def host
|
26
|
+
raise NotImplementedError.new("Classes including the Api module must provide a host")
|
27
|
+
end
|
28
|
+
|
29
|
+
# Only used for multi-collins systems
|
30
|
+
# @abstract
|
31
|
+
# @return [Hash<Symbol,OpenStruct>] hash with keys as locations, values as collins credentials.
|
32
|
+
def locations
|
33
|
+
raise NotImplementedError.new("Classes including the Api module must provide a locations hash")
|
34
|
+
end
|
35
|
+
|
36
|
+
# @abstract
|
37
|
+
# @return [Logger] a logger instance
|
38
|
+
def logger
|
39
|
+
raise NotImplementedError.new("Classes including the Api module must provide a logger")
|
40
|
+
end
|
41
|
+
|
42
|
+
# @abstract
|
43
|
+
# @return [String] a password for authentication
|
44
|
+
def password
|
45
|
+
raise NotImplementedError.new("Classes including the Api module must provide a password")
|
46
|
+
end
|
47
|
+
|
48
|
+
# How to deal with unexpected API responses
|
49
|
+
#
|
50
|
+
# When true, API methods will throw an exception if an unexpected response is encountered.
|
51
|
+
# When false, API methods will usually normalize responses to an appropriate value indicating
|
52
|
+
# failure.
|
53
|
+
#
|
54
|
+
# @param [Boolean] default
|
55
|
+
# @abstract
|
56
|
+
# @return [Boolean] strict or not
|
57
|
+
def strict? default = false
|
58
|
+
raise NotImplementedError.new("Classes including the Api module must provide a strict? method")
|
59
|
+
end
|
60
|
+
|
61
|
+
# @abstract
|
62
|
+
# @return [Fixnum] a timeout in seconds
|
63
|
+
def timeout_i
|
64
|
+
raise NotImplementedError.new("Classes including the Api module must provide a timeout")
|
65
|
+
end
|
66
|
+
|
67
|
+
# @abstract
|
68
|
+
# @return [String] a username for authentication
|
69
|
+
def username
|
70
|
+
raise NotImplementedError.new("Classes including the Api module must provide a username")
|
71
|
+
end
|
72
|
+
|
73
|
+
# Clear out all headers
|
74
|
+
# @return [nil]
|
75
|
+
def clear_headers
|
76
|
+
headers.clear # Yes, this returns an empty hash not nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Set a key/value in the headers hash
|
80
|
+
#
|
81
|
+
# @param [Symbol,String] key
|
82
|
+
# @param [String] value
|
83
|
+
# @return [nil]
|
84
|
+
def set_header key, value
|
85
|
+
headers.update(key => value)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Provides a safe wrapper for our monkeypatched logger
|
89
|
+
#
|
90
|
+
# If the provided logger responds to a trace method, use that method. Otherwise fallback to
|
91
|
+
# using the debug method.
|
92
|
+
def trace(progname = nil, &block)
|
93
|
+
if logger.respond_to?(:trace) then
|
94
|
+
logger.trace(progname, &block)
|
95
|
+
else
|
96
|
+
logger.debug(progname, &block)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def use_api_version version
|
101
|
+
set_header "Accept", "application/json,#{version_string(version)}"
|
102
|
+
end
|
103
|
+
|
104
|
+
include Collins::Api::Admin
|
105
|
+
include Collins::Api::Asset
|
106
|
+
include Collins::Api::AssetState
|
107
|
+
include Collins::Api::Attributes
|
108
|
+
include Collins::Api::IpAddress
|
109
|
+
include Collins::Api::Logging
|
110
|
+
include Collins::Api::Management
|
111
|
+
include Collins::Api::Tag
|
112
|
+
include Collins::Api::Util
|
113
|
+
|
114
|
+
protected
|
115
|
+
def version_string version
|
116
|
+
"application/com.tumblr.collins;version=#{version}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|