collins_client 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'collins/api/util/errors'
|
2
|
+
|
3
|
+
module Collins; module Api; module Util
|
4
|
+
|
5
|
+
module Responses
|
6
|
+
include Collins::Api::Util::Errors
|
7
|
+
|
8
|
+
protected
|
9
|
+
def parse_response response, options
|
10
|
+
do_raise = options[:raise] != false
|
11
|
+
if options.include?(:expects) && ![options[:expects]].flatten.include?(response.code) then
|
12
|
+
handle_error(response) if do_raise
|
13
|
+
if options.include?(:default) then
|
14
|
+
return options[:default]
|
15
|
+
else
|
16
|
+
raise UnexpectedResponseError.new("Expected code #{options[:expects]}, got #{response.code}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
handle_error(response) if do_raise
|
20
|
+
json = response.parsed_response
|
21
|
+
if options.include?(:as) then
|
22
|
+
case options[:as]
|
23
|
+
when :asset
|
24
|
+
json = Collins::Asset.from_json(json)
|
25
|
+
when :bare_asset
|
26
|
+
json = Collins::Asset.from_json(json, true)
|
27
|
+
when :data
|
28
|
+
json = json["data"]
|
29
|
+
when :status
|
30
|
+
json = json["data"]["SUCCESS"]
|
31
|
+
when :message
|
32
|
+
json = json["data"]["MESSAGE"]
|
33
|
+
when :paginated
|
34
|
+
json = json["data"]["Data"]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
if block_given? then
|
38
|
+
yield(json)
|
39
|
+
else
|
40
|
+
json
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end # Responses module
|
45
|
+
|
46
|
+
end; end; end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
require 'collins/address'
|
2
|
+
require 'collins/ipmi'
|
3
|
+
require 'collins/power'
|
4
|
+
require 'collins/state'
|
5
|
+
require 'date'
|
6
|
+
|
7
|
+
module Collins
|
8
|
+
|
9
|
+
# Represents the basic notion of a collins asset
|
10
|
+
class Asset
|
11
|
+
|
12
|
+
# Default time format when displaying dates associated with an asset
|
13
|
+
DATETIME_FORMAT = "%F %T"
|
14
|
+
|
15
|
+
# Asset finder related parameter descriptions
|
16
|
+
# @note these exist here instead of the API module for convenience
|
17
|
+
module Find
|
18
|
+
# Find API parameters that are dates
|
19
|
+
# @return [Array<String>] Date related query parameters
|
20
|
+
DATE_PARAMS = [
|
21
|
+
"createdAfter", "createdBefore", "updatedAfter", "updatedBefore"
|
22
|
+
]
|
23
|
+
# Find API parameters that are not dates
|
24
|
+
# This list exists so that when assets are being queries, we know what keys in the find hash
|
25
|
+
# are attributes of the asset (such as hostname), and which are nort (such as sort or page).
|
26
|
+
# @return [Array,<String>] Non-date related query parameters that are 'reserved'
|
27
|
+
GENERAL_PARAMS = [
|
28
|
+
"details", "tag", "type", "status", "page", "size", "sort", "state", "operation", "remoteLookup"
|
29
|
+
]
|
30
|
+
# @return [Array<String>] DATE_PARAMS plus GENERAL_PARAMS
|
31
|
+
ALL_PARAMS = DATE_PARAMS + GENERAL_PARAMS
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def to_a
|
35
|
+
Collins::Asset::Find::ALL_PARAMS
|
36
|
+
end
|
37
|
+
def valid? key
|
38
|
+
to_a.include?(key.to_s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
include Collins::Util
|
44
|
+
|
45
|
+
# @return [Array<CollinsAddress>] Addresses associated with asset
|
46
|
+
attr_reader :addresses
|
47
|
+
# @return [DateTime,NilClass] Timestamp. Can be nil
|
48
|
+
attr_reader :created, :updated, :deleted
|
49
|
+
# @return [Fixnum] Asset ID or 0
|
50
|
+
attr_reader :id
|
51
|
+
# @return [Collins::Ipmi] IPMI information
|
52
|
+
attr_reader :ipmi
|
53
|
+
# @return [String] multi-collins location
|
54
|
+
attr_reader :location
|
55
|
+
# @return [Collins::Power] Power configuration information
|
56
|
+
attr_reader :power
|
57
|
+
# @return [Collins::AssetState] Asset state, or nil
|
58
|
+
attr_reader :state
|
59
|
+
# @return [String] Asset status, or empty string
|
60
|
+
attr_reader :status
|
61
|
+
# @return [String] Asset tag, or empty string
|
62
|
+
attr_reader :tag
|
63
|
+
# @return [String] Asset type, or empty string
|
64
|
+
attr_reader :type
|
65
|
+
# @return [Hash] All additional asset metadata
|
66
|
+
attr_reader :extras
|
67
|
+
|
68
|
+
class << self
|
69
|
+
# Given a Hash deserialized from JSON, convert to an Asset
|
70
|
+
# @param [Hash] json_hash Asset representation
|
71
|
+
# @param [Boolean] bare_asset Exists for API compatability, largely not needed
|
72
|
+
# @return [Collins::Asset] The asset
|
73
|
+
# @raise [Collins::CollinsError] If the specified hash is invalid
|
74
|
+
def from_json json_hash, bare_asset = false
|
75
|
+
(raise Collins::CollinsError.new("Invalid JSON specified for Asset.from_json")) if (json_hash.nil? || !json_hash.is_a?(Hash))
|
76
|
+
json = deep_copy_hash json_hash
|
77
|
+
json = if json["data"] then json["data"] else json end
|
78
|
+
if bare_asset or !json.include?("ASSET") then
|
79
|
+
asset = Collins::Asset.new json
|
80
|
+
else
|
81
|
+
asset = Collins::Asset.new json.delete("ASSET")
|
82
|
+
end
|
83
|
+
asset.send('ipmi='.to_sym, Collins::Ipmi.from_json(json.delete("IPMI")))
|
84
|
+
asset.send('addresses='.to_sym, Collins::Address.from_json(json.delete("ADDRESSES")))
|
85
|
+
asset.send('power='.to_sym, Collins::Power.from_json(json.delete("POWER")))
|
86
|
+
asset.send('location=', json.delete("LOCATION"))
|
87
|
+
asset.send('extras=', json)
|
88
|
+
asset
|
89
|
+
end
|
90
|
+
|
91
|
+
# Convenience method for parsing asset ISO8601 date times
|
92
|
+
# @param [String] s the ISO8601 datetime
|
93
|
+
# @return [DateTime]
|
94
|
+
def format_date_string s
|
95
|
+
parsed = DateTime.parse(s)
|
96
|
+
parsed.strftime("%FT%T")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Create an Asset
|
101
|
+
# @param [Hash] opts Asset parameters
|
102
|
+
# @option opts [String] :tag The asset tag
|
103
|
+
# @option opts [String] :created The creation DateTime
|
104
|
+
# @option opts [Fixnum] :id The ID of the asset
|
105
|
+
# @option opts [String] :status The asset status
|
106
|
+
# @option opts [String] :type The asset type
|
107
|
+
# @option opts [String] :updated The update DateTime
|
108
|
+
# @option opts [String] :deleted The delete DateTime
|
109
|
+
def initialize opts = {}
|
110
|
+
@extras = {}
|
111
|
+
@addresses = []
|
112
|
+
if opts.is_a?(String) then
|
113
|
+
model = {:tag => opts}
|
114
|
+
else
|
115
|
+
model = opts
|
116
|
+
end
|
117
|
+
hash = symbolize_hash(model).inject({}) do |result, (k,v)|
|
118
|
+
result[k.downcase] = v
|
119
|
+
result
|
120
|
+
end
|
121
|
+
@created = parse_datetime hash.delete(:created).to_s
|
122
|
+
@id = hash.delete(:id).to_s.to_i
|
123
|
+
@status = hash.delete(:status).to_s
|
124
|
+
@tag = hash.delete(:tag).to_s
|
125
|
+
@type = hash.delete(:type).to_s
|
126
|
+
@state = Collins::AssetState.from_json(hash.delete(:state))
|
127
|
+
@updated = parse_datetime hash.delete(:updated).to_s
|
128
|
+
@deleted = parse_datetime hash.delete(:deleted).to_s
|
129
|
+
hash.each {|k,v| @extras[k] = v}
|
130
|
+
end
|
131
|
+
|
132
|
+
# @return [Collins::Address,NilClass] First available backend address
|
133
|
+
def backend_address
|
134
|
+
backend_addresses.first if backend_address?
|
135
|
+
end
|
136
|
+
# @return [Boolean] True if asset has a backend address
|
137
|
+
def backend_address?
|
138
|
+
backend_addresses.length > 0
|
139
|
+
end
|
140
|
+
# @return [Array<Collins::Address>] Array of backend addresses
|
141
|
+
def backend_addresses
|
142
|
+
addresses.select{|a| a.is_private?}
|
143
|
+
end
|
144
|
+
|
145
|
+
# @deprecated Users are encouraged to use {#backend_address}
|
146
|
+
# @return [String,NilClass] Address of first available backend address
|
147
|
+
def backend_ip_address
|
148
|
+
backend_address.address if backend_address?
|
149
|
+
end
|
150
|
+
# @deprecated Users are encouraged to uses {#backend_addresses}
|
151
|
+
# @return [Array<String>] Backend IP addresses
|
152
|
+
def backend_ip_addresses
|
153
|
+
backend_addresses.map{|a| a.address}
|
154
|
+
end
|
155
|
+
|
156
|
+
# @return [Collins::Address,NilClass] First available public address
|
157
|
+
def public_address
|
158
|
+
public_addresses.first if public_address?
|
159
|
+
end
|
160
|
+
# @return [Boolean] True if asset has a public address
|
161
|
+
def public_address?
|
162
|
+
public_addresses.length > 0
|
163
|
+
end
|
164
|
+
# @return [Array<Collins::Address>] Array of public addresses
|
165
|
+
def public_addresses
|
166
|
+
addresses.select{|a| a.is_public?}
|
167
|
+
end
|
168
|
+
|
169
|
+
# @deprecated Users are encouraged to use {#public_address}
|
170
|
+
# @return [String,NilClass] Address of first available public address
|
171
|
+
def public_ip_address
|
172
|
+
public_address.address if public_address?
|
173
|
+
end
|
174
|
+
# @deprecated Users are encouraged to uses {#public_addresses}
|
175
|
+
# @return [Array<String>] Public IP addresses
|
176
|
+
def public_ip_addresses
|
177
|
+
public_addresses.map{|a| a.address}
|
178
|
+
end
|
179
|
+
|
180
|
+
# @return [String,NilClass] Netmask of first available backend address
|
181
|
+
def backend_netmask
|
182
|
+
backend_address.netmask if backend_address?
|
183
|
+
end
|
184
|
+
# @return [Array<String>] Array of backend netmasks
|
185
|
+
def backend_netmasks
|
186
|
+
backend_addresses.map{|i| i.netmask}
|
187
|
+
end
|
188
|
+
|
189
|
+
# Return the gateway address for the specified pool, or the first gateway
|
190
|
+
# @note If there is no address in the specified pool, the gateway of the first usable address is
|
191
|
+
# used, which may not be desired.
|
192
|
+
# @param [String] pool The address pool to find a gateway on
|
193
|
+
# @return [String] Gateway address, or nil
|
194
|
+
def gateway_address pool = "default"
|
195
|
+
address = addresses.select{|a| a.pool == pool}.map{|a| a.gateway}.first
|
196
|
+
return address if address
|
197
|
+
if addresses.length > 0 then
|
198
|
+
addresses.first.gateway
|
199
|
+
else
|
200
|
+
nil
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# @return [Object,NilClass] See {#method_missing}
|
205
|
+
def get_attribute name
|
206
|
+
extract(extras, "ATTRIBS", "0", name.to_s.upcase)
|
207
|
+
end
|
208
|
+
|
209
|
+
# @return [Fixnum] Number of CPU's found
|
210
|
+
def cpu_count
|
211
|
+
(extract(extras, "HARDWARE", "CPU") || []).length
|
212
|
+
end
|
213
|
+
# @return [Array<Hash>] CPU information
|
214
|
+
def cpus
|
215
|
+
extract(extras, "HARDWARE", "CPU") || []
|
216
|
+
end
|
217
|
+
|
218
|
+
# @return [Array<Hash>] Disk information
|
219
|
+
def disks
|
220
|
+
extract(extras, "HARDWARE", "DISK") || []
|
221
|
+
end
|
222
|
+
# @return [Array<Hash>] Memory information
|
223
|
+
def memory
|
224
|
+
extract(extras, "HARDWARE", "MEMORY") || []
|
225
|
+
end
|
226
|
+
|
227
|
+
# @return [Array<Hash>] NIC information
|
228
|
+
def nics
|
229
|
+
extract(extras, "HARDWARE", "NIC") || []
|
230
|
+
end
|
231
|
+
# @return [Fixnum] Number of physical interfaces
|
232
|
+
def physical_nic_count
|
233
|
+
nics.length
|
234
|
+
end
|
235
|
+
# @return [Array<String>] MAC addresses associated with assets
|
236
|
+
def mac_addresses
|
237
|
+
nics.map{|n| n["MAC_ADDRESS"]}.select{|a| !a.nil?}
|
238
|
+
end
|
239
|
+
|
240
|
+
# @return [String] Human readable asset with no meta attributes
|
241
|
+
def to_s
|
242
|
+
updated_t = format_datetime(updated, "Never")
|
243
|
+
created_t = format_datetime(created, "Never")
|
244
|
+
ipmi_i = ipmi.nil? ? "No IPMI Data" : ipmi.to_s
|
245
|
+
"Asset(id = #{id}, tag = #{tag}, status = #{status}, type = #{type}, created = #{created_t}, updated = #{updated_t}, ipmi = #{ipmi_i}, state = #{state.to_s})"
|
246
|
+
end
|
247
|
+
|
248
|
+
def respond_to? name
|
249
|
+
if extract(extras, "ATTRIBS", "0", name.to_s.upcase).nil? then
|
250
|
+
super
|
251
|
+
else
|
252
|
+
true
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
protected
|
257
|
+
# We do not allow these to be externally writable since we won't actually update any of the data
|
258
|
+
attr_writer :addresses, :created, :id, :ipmi, :location, :power, :state, :status, :tag, :type, :updated, :extras
|
259
|
+
|
260
|
+
# Convenience method for {#get_attribute}
|
261
|
+
#
|
262
|
+
# This 'magic' method allows you to retrieve attributes on an asset, or check if an attribute
|
263
|
+
# exists via a predicate method.
|
264
|
+
#
|
265
|
+
# @example
|
266
|
+
# real_asset.hostname # => "foo"
|
267
|
+
# bare_asset.hostname # => nil
|
268
|
+
# real_asset.hostname? # => true
|
269
|
+
# bare_asset.hostname? # => false
|
270
|
+
#
|
271
|
+
# @note This is never called directly
|
272
|
+
# @return [NilClass,Object] Nil if attribute not found, otherwise the attribute value
|
273
|
+
def method_missing(m, *args, &block)
|
274
|
+
name = m.to_s.upcase
|
275
|
+
is_bool = name.end_with?('?')
|
276
|
+
if is_bool then
|
277
|
+
name = name.sub('?', '')
|
278
|
+
respond_to?(name)
|
279
|
+
else
|
280
|
+
extract(extras, "ATTRIBS", "0", name)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
def parse_datetime value
|
285
|
+
return nil if (value.nil? or value.empty?)
|
286
|
+
DateTime.parse value
|
287
|
+
end
|
288
|
+
|
289
|
+
def format_datetime value, default
|
290
|
+
if value then
|
291
|
+
value.strftime(DATETIME_FORMAT)
|
292
|
+
else
|
293
|
+
default
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Convenience method for finding something in a (potentially) deep hash
|
298
|
+
def extract(hash, *args)
|
299
|
+
begin
|
300
|
+
tmp = hash
|
301
|
+
args.each do |arg|
|
302
|
+
tmp = tmp[arg]
|
303
|
+
end
|
304
|
+
tmp
|
305
|
+
rescue
|
306
|
+
nil
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Collins
|
2
|
+
|
3
|
+
# Convenience class for making collins calls for only a single asset
|
4
|
+
class AssetClient
|
5
|
+
|
6
|
+
def initialize asset, client, logger
|
7
|
+
@asset = asset
|
8
|
+
if asset.is_a?(Collins::Asset) then
|
9
|
+
@tag = asset.tag
|
10
|
+
else
|
11
|
+
@tag = asset
|
12
|
+
end
|
13
|
+
@client = client
|
14
|
+
@logger = logger
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"AssetClient(asset = #{@tag}, client = #{@client})"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Fill in the missing asset parameter on the dynamic method if needed
|
22
|
+
#
|
23
|
+
# If {Collins::Client} responds to the method, and the method requires an `asset_or_tag`, we
|
24
|
+
# insert the asset specified during initialization into the args array. If the method does not
|
25
|
+
# require an `asset_or_tag`, we simply proxy the method call as is. If {Collins::Client} does
|
26
|
+
# not respond to the method, we defer to `super`.
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# collins_client.get('some_tag') # => returns that asset
|
30
|
+
# collins_client.with_asset('some_tag').get # => returns that same asset
|
31
|
+
#
|
32
|
+
# @note this method should never be called directly
|
33
|
+
def method_missing meth, *args, &block
|
34
|
+
if @client.respond_to?(meth) then
|
35
|
+
method_parameters = @client.class.instance_method(meth).parameters
|
36
|
+
asset_idx = method_parameters.find_index do |item|
|
37
|
+
item[1] == :asset_or_tag
|
38
|
+
end
|
39
|
+
if asset_idx.nil? then
|
40
|
+
@client.send(meth, *args, &block)
|
41
|
+
else
|
42
|
+
args_with_asset = args.insert(asset_idx, @tag)
|
43
|
+
logger.debug("Doing #{meth}(#{args_with_asset.join(',')}) for #{@tag}")
|
44
|
+
@client.send(meth, *args_with_asset, &block)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
super
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def respond_to? meth, include_private = false
|
52
|
+
@client.respond_to?(meth)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'collins/api'
|
2
|
+
require 'collins/asset_client'
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
module Collins
|
6
|
+
|
7
|
+
# Primary interface for interacting with collins
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# client = Collins::Client.new :host => '...', :username => '...', :password => '...'
|
11
|
+
# client.get 'asset_tag'
|
12
|
+
class Client
|
13
|
+
|
14
|
+
# @see Collins::Api#headers
|
15
|
+
attr_reader :headers
|
16
|
+
# @see Collins::Api#host
|
17
|
+
attr_reader :host
|
18
|
+
# @see Collins::Api#locations
|
19
|
+
attr_reader :locations
|
20
|
+
# @see Collins::Api#logger
|
21
|
+
attr_reader :logger
|
22
|
+
# @see Collins::Api#timeout_i
|
23
|
+
attr_reader :timeout_i
|
24
|
+
# @see Collins::Api#password
|
25
|
+
attr_reader :password
|
26
|
+
# @return [Boolean] strict mode throws exceptions when unexpected responses occur
|
27
|
+
attr_reader :strict
|
28
|
+
# @see Collins::Api#username
|
29
|
+
attr_reader :username
|
30
|
+
|
31
|
+
include HTTParty
|
32
|
+
include Collins::Api
|
33
|
+
include Collins::Util
|
34
|
+
|
35
|
+
# Create a collins client instance
|
36
|
+
# @param [Hash] options host, username and password are required
|
37
|
+
# @option options [String] :host a scheme, hostname and port (e.g. https://hostname)
|
38
|
+
# @option options [Logger] :logger a logger to use, one is created if none is specified
|
39
|
+
# @option options [Fixnum] :timeout (10) timeout in seconds to wait for a response
|
40
|
+
# @option options [String] :username username for authentication
|
41
|
+
# @option options [String] :password password for authentication
|
42
|
+
# @option options [String] :managed_process see {#manage_process}
|
43
|
+
# @option options [Boolean] :strict (false) see {#strict}
|
44
|
+
def initialize options = {}
|
45
|
+
config = symbolize_hash options
|
46
|
+
@locations = {}
|
47
|
+
@headers = {}
|
48
|
+
@host = fix_hostname(config.fetch(:host, ""))
|
49
|
+
@logger = get_logger config.merge(:progname => 'Collins_Client')
|
50
|
+
@timeout_i = config.fetch(:timeout, 10).to_i
|
51
|
+
@username = config.fetch(:username, "")
|
52
|
+
@password = config.fetch(:password, "")
|
53
|
+
@strict = config.fetch(:strict, false)
|
54
|
+
@managed_process = config.fetch(:managed_process, nil)
|
55
|
+
require_non_empty(@host, "Collins::Client host must be specified")
|
56
|
+
require_non_empty(@username, "Collins::Client username must be specified")
|
57
|
+
require_non_empty(@password, "Collins::Client password must be specified")
|
58
|
+
end
|
59
|
+
|
60
|
+
# Interact with a collins managed process
|
61
|
+
# @param [String] name Name of process
|
62
|
+
# @raise [CollinsError] if no managed process is specified/found
|
63
|
+
# @return [Collins::ManagedState::Mixin] see mixin for more information
|
64
|
+
def manage_process name = nil
|
65
|
+
name = @managed_process if name.nil?
|
66
|
+
if name then
|
67
|
+
begin
|
68
|
+
Collins.const_get(name).new(self).run
|
69
|
+
rescue Exception => e
|
70
|
+
raise CollinsError.new(e.message)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
raise CollinsError.new("No managed process specified")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [String] Collins::Client(host = hostname)
|
78
|
+
def to_s
|
79
|
+
"Collins::Client(host = #{@host})"
|
80
|
+
end
|
81
|
+
|
82
|
+
# @see Collins::Api#strict?
|
83
|
+
def strict? default = false
|
84
|
+
@strict || default
|
85
|
+
end
|
86
|
+
|
87
|
+
# Use the specified asset for subsequent method calls
|
88
|
+
# @param [Collins::Asset,String] asset The asset to use for operations
|
89
|
+
# @return [Collins::AssetClient] Provides most of the same methods as {Collins::Client} but with no need to specfiy the asset for those methods
|
90
|
+
def with_asset asset
|
91
|
+
Collins::AssetClient.new(asset, self, @logger)
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
def fix_hostname hostname
|
96
|
+
hostname.is_a?(String) ? hostname.gsub(/\/+$/, '') : hostname
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|