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 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