collins_client 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
1
+ require 'collins/util'
2
+
3
+ module Collins
4
+
5
+ class Profile
6
+
7
+ include Collins::Util
8
+
9
+ attr_accessor :options
10
+
11
+ def initialize options = {}
12
+ @options = symbolize_hash options, :downcase => true
13
+ end
14
+
15
+ def profile
16
+ @options[:profile]
17
+ end
18
+ def profile?
19
+ not profile.nil?
20
+ end
21
+
22
+ def label
23
+ @options[:label]
24
+ end
25
+ def label?
26
+ not label.nil?
27
+ end
28
+
29
+ def prefix
30
+ @options[:prefix]
31
+ end
32
+ def prefix?
33
+ not prefix.nil?
34
+ end
35
+
36
+ def suffix_allowed?
37
+ @options[:suffix_allowed]
38
+ end
39
+
40
+ def primary_role
41
+ @options[:primary_role]
42
+ end
43
+ def primary_role?
44
+ not primary_role.nil?
45
+ end
46
+
47
+ def pool
48
+ @options[:pool]
49
+ end
50
+ def pool?
51
+ not pool.nil?
52
+ end
53
+
54
+ def secondary_role
55
+ @options[:secondary_role]
56
+ end
57
+ def secondary_role?
58
+ not secondary_role.nil?
59
+ end
60
+
61
+ def requires_primary_role?
62
+ @options[:requires_primary_role]
63
+ end
64
+ def requires_pool?
65
+ @options[:requires_pool]
66
+ end
67
+ def requires_secondary_role?
68
+ @options[:requires_secondary_role]
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,141 @@
1
+ require 'collins/util'
2
+ require 'collins/option'
3
+
4
+ module Collins
5
+
6
+ # Represents a simple callback, e.g. something with a name, options and an exec block
7
+ # This is designed to be a building block for other callback implementations as opposed to a
8
+ # complete implementation. Note that we duck-type Proc. We can't extend it without running into
9
+ # some initialize issues. We do this so people can feel free to tread the class like a proc.
10
+ class SimpleCallback
11
+ include ::Collins::Util
12
+
13
+ EMPTY_NAME = :None
14
+
15
+ # @return [Symbol] Name of the callback
16
+ attr_reader :name
17
+
18
+ # @return [Hash] Options specified with the callback, after normalizing
19
+ attr_reader :options
20
+
21
+ # @return [Collins::SimpleCallback] {#empty?} will return true
22
+ def self.empty
23
+ Collins::SimpleCallback.new(:none => true) {}
24
+ end
25
+
26
+ # Instantiate a new SimpleCallback
27
+ #
28
+ # @param [Array,Hash] args Arguments for instantiation
29
+ # @yieldparam [Array<Object>] block Callback to execute, can also be specified via :block option
30
+ #
31
+ # @example
32
+ # SimpleCallback.new(:my_callback, Proc.new {|arg1| puts(arg1)})
33
+ # SimpleCallback.new(:my_callback, :block => Proc.new{|arg1| puts(arg1)})
34
+ # SimpleCallback.new :my_callback, :opt1 => "val" do |arg1|
35
+ # puts(arg1)
36
+ # end
37
+ #
38
+ # @raise [ArgumentError] when name not set, and not created via #{SimpleCallback.empty}
39
+ def initialize *args, &block
40
+ opts = {}
41
+ while arg = args.shift do
42
+ if arg.is_a?(Hash) then
43
+ opts.update(arg)
44
+ elsif arg.respond_to?(:call) then
45
+ opts.update(:block => arg)
46
+ else
47
+ key = [:name, :options].select{|k| !opts.key?(k)}.first
48
+ opts.update(key => arg) unless key.nil?
49
+ end
50
+ end
51
+ if block && block.respond_to?(:call) then
52
+ opts.update(:block => block)
53
+ end
54
+ opts = symbolize_hash(opts)
55
+ if opts.fetch(:none, false) then
56
+ @name = EMPTY_NAME
57
+ @block = ::Collins::None.new
58
+ @options = {}
59
+ else
60
+ @name = ::Collins::Option(opts.delete(:name)).get_or_else {
61
+ raise ArgumentError.new("SimpleCallback requires a name")
62
+ }.to_sym
63
+ @block = ::Collins::Option(opts.delete(:block))
64
+ @options = opts
65
+ end
66
+ end
67
+
68
+ # @see Hash
69
+ # @param [String,Symbol] key
70
+ # @return [Object] value associated with key
71
+ def [](key)
72
+ options[key.to_sym]
73
+ end
74
+
75
+ # @see Proc
76
+ # @return [Fixnum] number of arguments that would not be ignored
77
+ def arity
78
+ block.map {|b| b.arity}.get_or_else(0)
79
+ end
80
+ # @see Proc
81
+ # @return [Binding] binding associated with the proc
82
+ def binding
83
+ to_proc.binding
84
+ end
85
+ # @see Proc
86
+ # @return [Boolean] lambda or not
87
+ def lambda?
88
+ block.map {|b| b.lambda?}.get_or_else(false)
89
+ end
90
+ # @see Proc
91
+ # @return [Array<Array<Symbol>>] array of parameters accepted by proc
92
+ def parameters
93
+ block.map {|b| b.parameters}.get_or_else([])
94
+ end
95
+ # @see Proc
96
+ # @return [Proc] proc or noop proc
97
+ def to_proc
98
+ block.map{|b| b.to_proc}.get_or_else(Proc.new{})
99
+ end
100
+
101
+ # @return [Collins::Option] Self as option
102
+ def to_option
103
+ if self.defined? then
104
+ ::Collins::Some.new(self)
105
+ else
106
+ ::Collins::None.new
107
+ end
108
+ end
109
+
110
+ # @return [Boolean] True if block was given to constructor
111
+ def defined?
112
+ name != EMPTY_NAME || block.defined?
113
+ end
114
+ # @return [Boolean] False if block was given to constructor
115
+ def empty?
116
+ name == EMPTY_NAME && block.empty?
117
+ end
118
+
119
+ # Call the callback block with the specified arguments
120
+ #
121
+ # @see Proc
122
+ # @param [Array<Object>] args - Arguments for callback
123
+ # @return [Object] Value from callback
124
+ # @raise [NameError] if block wasn't specified but call was executed
125
+ def call *args
126
+ block.map do |b|
127
+ b.call(*args)
128
+ end.get
129
+ end
130
+
131
+ # @return [String] representation of callback
132
+ def to_s
133
+ "Collins::SimpleCallback(name = #{name}, options = #{options.inspect})"
134
+ end
135
+
136
+ protected
137
+ # The code block associated with the simple callback
138
+ attr_reader :block
139
+ end
140
+
141
+ end
@@ -0,0 +1,50 @@
1
+ require 'ostruct'
2
+
3
+ module Collins
4
+ class AssetState
5
+ include Collins::Util
6
+
7
+ attr_accessor :description, :id, :label, :name, :status
8
+
9
+ def self.from_json json
10
+ Collins::AssetState.new json
11
+ end
12
+
13
+ def initialize opts = {}
14
+ hash = symbolize_hash(opts).inject({}) do |result, (k,v)|
15
+ key = k.to_s.downcase.to_sym
16
+ result[key] = v
17
+ result
18
+ end
19
+ @description = hash[:description].to_s
20
+ @id = hash[:id].to_s.to_i
21
+ @label = hash[:label].to_s
22
+ @name = hash[:name].to_s
23
+ @status = get_status hash[:status]
24
+ end
25
+
26
+ def empty?
27
+ @id == 0
28
+ end
29
+
30
+ def to_s
31
+ if empty? then
32
+ "State(None)"
33
+ else
34
+ "State(id = #{id}, name = '#{name}', label = '#{label}', description = '#{description}')"
35
+ end
36
+ end
37
+
38
+ private
39
+ def get_status opt
40
+ opts = opt || {}
41
+ hash = symbolize_hash(opts).inject({}) do |result, (k,v)|
42
+ key = k.to_s.downcase.to_sym
43
+ result[key] = v
44
+ result
45
+ end
46
+ OpenStruct.new(hash)
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,145 @@
1
+ require 'collins/logging'
2
+
3
+ module Collins
4
+
5
+ # General purpose util methods
6
+ #
7
+ # Methods in {Collins::Util} can be accessed by....
8
+ #
9
+ # * `Collins::Util.method_name`
10
+ # * `ClassIncludingCollinsUtil.method_name`
11
+ # * `instance_of_class_including_collins_util.method_name`
12
+ #
13
+ # Other than {Util#get\_asset\_or\_tag} most of these methods are not collins specific
14
+ module Util
15
+
16
+ include Collins::Util::Logging
17
+
18
+ def self.included base
19
+ base.extend(Collins::Util)
20
+ end
21
+
22
+ # Create a deep copy of a hash
23
+ #
24
+ # This is useful for copying a hash that will be mutated
25
+ # @note All keys and values must be serializable, Proc for instance will fail
26
+ # @param [Hash] hash the hash to copy
27
+ # @return [Hash]
28
+ def deep_copy_hash hash
29
+ require_that(hash.is_a?(Hash), "deep_copy_hash requires a hash be specified, got #{hash.class}")
30
+ Marshal.load Marshal.dump(hash)
31
+ end
32
+
33
+ # Require that a value not be empty
34
+ #
35
+ # If the value is a string, ensure that once stripped it's not empty. If the value responds to
36
+ # `:empty?`, ensure that it's not. Otherwise ensure the value isn't nil.
37
+ #
38
+ # @param [Object] value the value to check
39
+ # @param [String] message the exception message to use if the value is empty
40
+ # @param [Boolean,Object] return_value If true, returns value. If not false, returns the object
41
+ # @raise [ExpectationFailedError] if the value is empty
42
+ # @return [NilClass,Object] NilClass, or respecting return_value
43
+ def require_non_empty value, message, return_value = false
44
+ guard_value = if return_value == true then
45
+ value
46
+ elsif return_value != false then
47
+ return_value
48
+ else
49
+ false
50
+ end
51
+ if value.is_a?(String) then
52
+ require_that(!value.strip.empty?, message, guard_value)
53
+ elsif value.respond_to?(:empty?) then
54
+ require_that(!value.empty?, message, guard_value)
55
+ else
56
+ require_that(!value.nil?, message, guard_value)
57
+ end
58
+ end
59
+
60
+ # Require that a guard condition passes
61
+ #
62
+ # Simply checks that the guard is truthy, and throws an error otherwise
63
+ # @see #require_non_empty
64
+ def require_that guard, message, return_guard = false
65
+ if not guard then
66
+ raise ExpectationFailedError.new(message)
67
+ end
68
+ if return_guard == true then
69
+ guard
70
+ elsif return_guard != false then
71
+ return_guard
72
+ end
73
+ end
74
+
75
+ # Resolve an asset from a string tag or collins asset
76
+ # @note This is perhaps the only collins specific method in Util
77
+ # @param [Collins::Asset,String,Symbol] asset_or_tag
78
+ # @return [Collins::Asset] a collins asset
79
+ # @raise [ExpectationFailedError] if asset\_or\_tag isn't valid
80
+ def get_asset_or_tag asset_or_tag
81
+ asset =
82
+ case asset_or_tag
83
+ when Collins::Asset then asset_or_tag
84
+ when String then Collins::Asset.new(asset_or_tag)
85
+ when Symbol then Collins::Asset.new(asset_or_tag.to_s)
86
+ else
87
+ error_message = "Expected Collins::Asset, String or Symbol. Got #{asset_or_tag.class}"
88
+ raise ExpectationFailedError.new(error_message)
89
+ end
90
+ if asset.nil? || asset.tag.nil? then
91
+ raise ExpectationFailedError.new("Empty asset tag, but a tag is required")
92
+ end
93
+ asset
94
+ end
95
+
96
+ # Given a hash, rewrite keys to symbols
97
+ #
98
+ # @param [Hash] hash the hash to symbolize
99
+ # @param [Hash] options specify how to process the hash
100
+ # @option options [Boolean] :rewrite_regex if the value is a regex and this is true, convert it to a string
101
+ # @option options [Boolean] :downcase if true, downcase the keys as well
102
+ # @raise [ExpectationFailedError] if hash is not a hash
103
+ def symbolize_hash hash, options = {}
104
+ return {} if (hash.nil? or hash.empty?)
105
+ (raise ExpectationFailedError.new("symbolize_hash called without a hash")) unless hash.is_a?(Hash)
106
+ hash.inject({}) do |result, (k,v)|
107
+ key = options[:downcase] ? k.to_s.downcase.to_sym : k.to_s.to_sym
108
+ if v.is_a?(Hash) then
109
+ result[key] = symbolize_hash(v)
110
+ elsif v.is_a?(Regexp) && options[:rewrite_regex] then
111
+ result[key] = v.inspect[1..-2]
112
+ else
113
+ result[key] = v
114
+ end
115
+ result
116
+ end
117
+ end
118
+
119
+ # Given a hash, convert all keys to strings
120
+ # @see #symbolize_hash
121
+ def stringify_hash hash, options = {}
122
+ (raise ExpectationFailedError.new("stringify_hash called without a hash")) unless hash.is_a?(Hash)
123
+ hash.inject({}) do |result, (k,v)|
124
+ key = options[:downcase] ? k.to_s.downcase : k.to_s
125
+ if v.is_a?(Hash) then
126
+ result[key] = stringify_hash(v)
127
+ elsif v.is_a?(Regexp) && options[:rewrite_regex] then
128
+ result[key] = v.inspect[1..-2]
129
+ else
130
+ result[key] = v
131
+ end
132
+ result
133
+ end
134
+ end
135
+
136
+ # This provides access to these methods via a Collins::Util.method_name call
137
+ [:deep_copy_hash, :require_non_empty, :get_asset_or_tag, :require_that,
138
+ :symbolize_hash, :stringify_hash
139
+ ].each do |method|
140
+ module_function method
141
+ public method # without this, module_function makes the method private
142
+ end
143
+ end # Util module
144
+
145
+ end # Collins module
@@ -0,0 +1,7 @@
1
+ $:.unshift File.join File.dirname(__FILE__)
2
+ require 'collins/util'
3
+ require 'collins/option'
4
+ require 'collins/simple_callback'
5
+ require 'collins/asset'
6
+ require 'collins/client'
7
+ require 'collins/errors'
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: collins_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Blake Matheny
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.3
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.8.3
30
+ description: Provides ruby support for interacting with the Collins API
31
+ email: bmatheny@tumblr.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files:
35
+ - README.md
36
+ files:
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - README.md
40
+ - Rakefile
41
+ - VERSION
42
+ - collins_client.gemspec
43
+ - lib/collins/address.rb
44
+ - lib/collins/api.rb
45
+ - lib/collins/api/admin.rb
46
+ - lib/collins/api/asset.rb
47
+ - lib/collins/api/asset_state.rb
48
+ - lib/collins/api/attributes.rb
49
+ - lib/collins/api/ip_address.rb
50
+ - lib/collins/api/logging.rb
51
+ - lib/collins/api/management.rb
52
+ - lib/collins/api/tag.rb
53
+ - lib/collins/api/util.rb
54
+ - lib/collins/api/util/errors.rb
55
+ - lib/collins/api/util/parameters.rb
56
+ - lib/collins/api/util/requests.rb
57
+ - lib/collins/api/util/responses.rb
58
+ - lib/collins/asset.rb
59
+ - lib/collins/asset_client.rb
60
+ - lib/collins/client.rb
61
+ - lib/collins/errors.rb
62
+ - lib/collins/ipmi.rb
63
+ - lib/collins/logging.rb
64
+ - lib/collins/monkeypatch.rb
65
+ - lib/collins/option.rb
66
+ - lib/collins/power.rb
67
+ - lib/collins/profile.rb
68
+ - lib/collins/simple_callback.rb
69
+ - lib/collins/state.rb
70
+ - lib/collins/util.rb
71
+ - lib/collins_client.rb
72
+ homepage: https://github.com/tumblr/collins/tree/master/support/ruby/collins-client
73
+ licenses:
74
+ - APL 2.0
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ segments:
86
+ - 0
87
+ hash: -1509418886285766907
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 1.8.24
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Client library for Collins API
100
+ test_files: []