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,56 @@
1
+ module Collins
2
+
3
+ class CollinsError < StandardError; end
4
+ class ExpectationFailedError < CollinsError; end
5
+ class UnexpectedResponseError < CollinsError; end
6
+ class RequestError < CollinsError
7
+ attr_accessor :code, :uri
8
+ def initialize message, code
9
+ super(message)
10
+ @code = code.to_i
11
+ end
12
+ def description verbose = false
13
+ <<-D
14
+ #{message}
15
+ Response Code: #{code}
16
+ URI: #{uri}
17
+ D
18
+ end
19
+ end
20
+
21
+ class RichRequestError < RequestError
22
+ attr_accessor :class_of, :remote_description, :remote_message, :stacktrace
23
+ def initialize message, code, description, details = {}
24
+ super(message, code)
25
+ @code = code
26
+ @remote_description = description
27
+ @class_of = details["classOf"]
28
+ @remote_message = details["message"]
29
+ @stacktrace = details["stackTrace"]
30
+ end
31
+ def get_remote_stacktrace verbose
32
+ if verbose then
33
+ stacktrace
34
+ else
35
+ "Suppressed"
36
+ end
37
+ end
38
+ def description verbose = false
39
+ <<-D
40
+ #{message}
41
+ Response Code: #{code}
42
+ URI: #{uri}
43
+ Remote Description: #{remote_description}
44
+ Remote Exception Class: #{class_of}
45
+ Remote Message:
46
+ #{remote_message}
47
+
48
+ Remote Backtrace:
49
+ #{get_remote_stacktrace(verbose)}
50
+ D
51
+ end
52
+ end
53
+
54
+ class AuthenticationError < CollinsError; end
55
+
56
+ end
@@ -0,0 +1,41 @@
1
+ module Collins
2
+
3
+ class Ipmi
4
+
5
+ include Collins::Util
6
+
7
+ attr_accessor :address, :asset_id, :gateway, :id, :netmask, :password, :username
8
+
9
+ def self.from_json json
10
+ Collins::Ipmi.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.sub(/^ipmi_/, "").to_sym
16
+ result[key] = v
17
+ result
18
+ end
19
+ @address = hash[:address].to_s
20
+ @asset_id = hash[:asset_id].to_s.to_i
21
+ @gateway = hash[:gateway].to_s
22
+ @id = hash[:id].to_s.to_i
23
+ @netmask = hash[:netmask].to_s
24
+ @password = hash[:password].to_s
25
+ @username = hash[:username].to_s
26
+ end
27
+
28
+ def empty?
29
+ @id == 0
30
+ end
31
+
32
+ def to_s
33
+ if empty? then
34
+ "Ipmi(None)"
35
+ else
36
+ "Ipmi(id = #{id}, asset_id = #{asset_id}, address = #{address}, gateway = #{gateway}, netmask = #{netmask}, username = #{username}, password = #{password})"
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ require 'collins/monkeypatch'
2
+ require 'collins/option'
3
+
4
+ module Collins; module Util
5
+
6
+ module Logging
7
+
8
+ DEFAULT_LOG_FORMAT = "%Y-%m-%d %H:%M:%S.%L"
9
+
10
+ def get_logger options = {}
11
+ return options[:logger] if options[:logger]
12
+ trace = Collins::Option(options[:trace]).get_or_else(false)
13
+ debug = Collins::Option(options[:debug]).get_or_else(false)
14
+ progname = Collins::Option(options[:progname] || options[:program]).get_or_else('unknown')
15
+ logfile = Collins::Option(options[:logfile]).get_or_else(STDOUT)
16
+ logger = Logger.new(logfile)
17
+ if trace then
18
+ logger.level = Logger::TRACE
19
+ elsif debug then
20
+ logger.level = Logger::DEBUG
21
+ else
22
+ logger.level = Logger::INFO
23
+ end
24
+ logger.progname = File.basename(progname)
25
+ logger.formatter = Proc.new do |severity, datetime, progname, message|
26
+ date_s = datetime.strftime(Collins::Util::Logging::DEFAULT_LOG_FORMAT)
27
+ "#{severity} [#{date_s}] #{progname}: #{message}\n"
28
+ end
29
+ logger
30
+ end
31
+ end
32
+
33
+ end; end
@@ -0,0 +1,24 @@
1
+ require 'logger'
2
+
3
+ class Logger
4
+
5
+ module Severity
6
+ TRACE = -1
7
+ end
8
+
9
+ def trace?; @level <= TRACE; end
10
+
11
+ def trace(progname = nil, &block)
12
+ add(TRACE, nil, progname, &block)
13
+ end
14
+
15
+ private
16
+ def format_severity severity
17
+ if severity == TRACE then
18
+ 'TRACE'
19
+ else
20
+ SEV_LABEL[severity] || 'ANY'
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,220 @@
1
+ module Collins
2
+
3
+ # Convenience method for creating an `Option`
4
+ def self.Option value
5
+ if value.nil? then
6
+ ::Collins::None()
7
+ else
8
+ ::Collins::Some(value)
9
+ end
10
+ end
11
+ # Convenience method for creating a `None`
12
+ def self.None
13
+ ::Collins::None.new
14
+ end
15
+ # Convenience method for creating a `Some`
16
+ def self.Some value
17
+ ::Collins::Some.new(value)
18
+ end
19
+
20
+ # Represents optional values. Instances of `Option` are either an instance of `Some` or `None`
21
+ # @note This is pretty much a straight rip off of the scala version
22
+ # @example
23
+ # name = get_parameter("name")
24
+ # upper = Option(name).map{|s| s.strip}.filter{|s|s.size > 0}.map{|s|s.upcase}
25
+ # puts(upper.get_or_else(""))
26
+ class Option
27
+
28
+ # @return [Boolean] True if the value is undefined
29
+ def empty?
30
+ raise NotImplementedError.new("empty? not implemented")
31
+ end
32
+
33
+ # @return [Boolean] True if the value is defined
34
+ def defined?
35
+ !empty?
36
+ end
37
+
38
+ # @return [Object] Value, if defined
39
+ # @raise [NameError] if value is undefined
40
+ def get
41
+ raise NotImplementedError.new("get not implemented")
42
+ end
43
+
44
+ # The value associated with this option, or the default
45
+ #
46
+ # @example
47
+ # # Raises an exception
48
+ # Option(nil).get_or_else { raise Exception.new("Stuff") }
49
+ # # Returns -1
50
+ # Option("23").map {|i| i.to_i}.filter{|i| i > 25}.get_or_else -1
51
+ #
52
+ # @param [Object] default A default value to use if the option value is undefined
53
+ # @yield [] Provide a default with a block instead of a parameter
54
+ # @return [Object] If None, default, otherwise the value
55
+ def get_or_else *default
56
+ if empty? then
57
+ if block_given? then
58
+ yield
59
+ else
60
+ default.first
61
+ end
62
+ else
63
+ get
64
+ end
65
+ end
66
+
67
+ # Return this `Option` if non-empty, otherwise return the result of evaluating the default
68
+ # @example
69
+ # Option(nil).or_else { "foo" } == Some("foo")
70
+ # @return [Option<Object>]
71
+ def or_else *default
72
+ if empty? then
73
+ res = if block_given? then
74
+ yield
75
+ else
76
+ default.first
77
+ end
78
+ if res.is_a?(Option) then
79
+ res
80
+ else
81
+ ::Collins::Option(res)
82
+ end
83
+ else
84
+ self
85
+ end
86
+ end
87
+
88
+ # Return true if non-empty and predicate is true for the value
89
+ # @return [Boolean] test passed
90
+ def exists? &predicate
91
+ !empty? && predicate.call(get)
92
+ end
93
+
94
+ # Apply the block specified to the value if non-empty
95
+ # @return [NilClass]
96
+ def foreach &f
97
+ if self.defined? then
98
+ f.call(get)
99
+ end
100
+ nil
101
+ end
102
+
103
+ # If the option value is defined, apply the specified block to that value
104
+ #
105
+ # @example
106
+ # Option("15").map{|i| i.to_i}.get == 15
107
+ #
108
+ # @yieldparam [Object] block The current value
109
+ # @yieldreturn [Object] The new value
110
+ # @return [Option<Object>] Optional value
111
+ def map &block
112
+ if empty? then
113
+ None.new
114
+ else
115
+ Some.new(block.call(get))
116
+ end
117
+ end
118
+
119
+ # Same as map, but flatten the results
120
+ #
121
+ # This is useful when operating on an object that will return an `Option`.
122
+ #
123
+ # @example
124
+ # Option(15).flat_map {|i| Option(i).filter{|i2| i2 > 0}} == Some(15)
125
+ #
126
+ # @see #map
127
+ # @return [Option<Object>] Optional value
128
+ def flat_map &block
129
+ if empty? then
130
+ None.new
131
+ else
132
+ res = block.call(get)
133
+ if res.is_a?(Some) then
134
+ res
135
+ else
136
+ Some.new(res)
137
+ end
138
+ end
139
+ end
140
+
141
+ # Convert to `None` if predicate fails
142
+ #
143
+ # Returns this option if it is non-empty *and* applying the predicate to this options returns
144
+ # true. Otherwise return `None`.
145
+ #
146
+ # @yieldparam [Object] predicate The current value
147
+ # @yieldreturn [Boolean] result of testing value
148
+ # @return [Option<Object>] `None` if predicate fails, or already `None`
149
+ def filter &predicate
150
+ if empty? || predicate.call(get) then
151
+ self
152
+ else
153
+ None.new
154
+ end
155
+ end
156
+
157
+ # Inverse of `filter` operation.
158
+ #
159
+ # Returns this option if it is non-empty *and* applying the predicate to this option returns
160
+ # false. Otherwise return `None`.
161
+ #
162
+ # @see #filter
163
+ # @return [Option<Object>]
164
+ def filter_not &predicate
165
+ if empty? || !predicate.call(get) then
166
+ self
167
+ else
168
+ None.new
169
+ end
170
+ end
171
+ end
172
+
173
+ # Represents a missing value
174
+ class None < Option
175
+ # Always true for `None`
176
+ # @see Option#empty?
177
+ def empty?
178
+ true
179
+ end
180
+ # Always raises a NameError
181
+ # @raise [NameError]
182
+ def get
183
+ raise NameError.new("None.get")
184
+ end
185
+ def eql? other
186
+ self.class.equal?(other.class)
187
+ end
188
+ alias == eql?
189
+ end
190
+
191
+ # Represents a present value
192
+ #
193
+ # A number of equality and comparison methods are implemented so that `Some` values are compared
194
+ # using the value of `x`.
195
+ class Some < Option
196
+ def initialize value
197
+ @x = value
198
+ end
199
+ def empty?
200
+ false
201
+ end
202
+ def get
203
+ x
204
+ end
205
+ def eql? other
206
+ self.class.equal?(other.class) && x.eql?(other.x)
207
+ end
208
+ alias == eql?
209
+ def hash
210
+ x.hash
211
+ end
212
+ def <=>(other)
213
+ self.class == other.class ?
214
+ (x <=> other.x) : nil
215
+ end
216
+ protected
217
+ attr_reader :x
218
+ end
219
+
220
+ end
@@ -0,0 +1,99 @@
1
+ require 'collins/errors'
2
+
3
+ module Collins
4
+
5
+ class InvalidPowerStatus < CollinsError; end
6
+
7
+ class PowerUnit
8
+ include Collins::Util
9
+
10
+ attr_accessor :key, :value, :type, :label, :position, :is_required, :unique
11
+
12
+ def initialize model = {}
13
+ hash = symbolize_hash(model).inject({}) do |result, (k,v)|
14
+ result[k.downcase] = v
15
+ result
16
+ end
17
+ @key = hash[:key].to_s
18
+ @value = hash[:value].to_s
19
+ @type = hash[:type].to_s
20
+ @label = hash[:label].to_s
21
+ @position = hash[:position].to_s.to_i
22
+ @is_required = hash[:is_required]
23
+ @unique = hash[:unique]
24
+ end
25
+
26
+ def is_required?
27
+ @is_required == true
28
+ end
29
+ def unique?
30
+ @unique == true
31
+ end
32
+ end
33
+
34
+ class Power
35
+
36
+ include Collins::Util
37
+
38
+ attr_accessor :unit_id, :units
39
+
40
+ class << self
41
+ def from_json json
42
+ return [] if (json.nil? or json.empty?)
43
+ if not json.is_a?(Array) then
44
+ json = [json]
45
+ end
46
+ json.map { |j| Collins::Power.new j }
47
+ end
48
+ def normalize_action action
49
+ case action.to_s.downcase.to_sym
50
+ when :off, :poweroff
51
+ "powerOff"
52
+ when :on, :poweron
53
+ "powerOn"
54
+ when :powersoft
55
+ "powerSoft"
56
+ when :soft, :rebootsoft
57
+ "rebootSoft"
58
+ when :hard, :reboothard
59
+ "rebootHard"
60
+ when :status, :powerstate
61
+ "powerState"
62
+ when :verify
63
+ "verify"
64
+ when :identify
65
+ "identify"
66
+ else
67
+ raise InvalidPowerStatus.new("#{action} is not a valid power status")
68
+ end
69
+ end
70
+ end
71
+
72
+ def initialize model = {}
73
+ hash = symbolize_hash(model).inject({}) do |result, (k,v)|
74
+ result[k.downcase] = v
75
+ result
76
+ end
77
+ @unit_id = hash[:unit_id].to_s.to_i
78
+ @units = (hash[:units] || []).map {|u| Collins::PowerUnit.new(u)}
79
+ end
80
+
81
+ def keys
82
+ units.map{|u| u.key }
83
+ end
84
+ def values
85
+ units.map{|u| u.value}
86
+ end
87
+ def types
88
+ units.map{|u| u.type}
89
+ end
90
+ def labels
91
+ units.map{|u| u.label}
92
+ end
93
+ def positions
94
+ units.map{|u| u.position}
95
+ end
96
+
97
+ end
98
+
99
+ end