collins_client 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source :rubygems
2
+
3
+ gem 'httparty', '~> 0.8.3'
4
+
5
+ group :development do
6
+ gem 'jeweler', '~> 1.8.3'
7
+ gem 'yard'
8
+ gem 'redcarpet'
9
+ end
10
+
11
+ group :test do
12
+ gem 'rspec'
13
+ gem 'webmock'
14
+ gem 'simplecov'
15
+ end
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
@@ -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