cloud_powers 0.2.7.23 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.test.env.example +6 -6
- data/.travis.yml +1 -1
- data/README +190 -0
- data/cloud_powers.gemspec +4 -4
- data/lib/cloud_powers.rb +3 -13
- data/lib/cloud_powers/aws_resources.rb +21 -4
- data/lib/cloud_powers/creatable.rb +122 -0
- data/lib/cloud_powers/helpers.rb +58 -0
- data/lib/cloud_powers/helpers/lang_help.rb +288 -0
- data/lib/cloud_powers/helpers/logic_help.rb +152 -0
- data/lib/cloud_powers/helpers/path_help.rb +90 -0
- data/lib/cloud_powers/node.rb +69 -68
- data/lib/cloud_powers/node/instance.rb +52 -0
- data/lib/cloud_powers/resource.rb +44 -0
- data/lib/cloud_powers/storage.rb +27 -14
- data/lib/{stubs → cloud_powers/stubs}/aws_stubs.rb +37 -14
- data/lib/cloud_powers/synapse/broadcast.rb +117 -0
- data/lib/cloud_powers/synapse/broadcast/channel.rb +44 -0
- data/lib/cloud_powers/synapse/pipe.rb +211 -0
- data/lib/cloud_powers/synapse/pipe/stream.rb +41 -0
- data/lib/cloud_powers/synapse/queue.rb +357 -0
- data/lib/cloud_powers/synapse/queue/board.rb +61 -95
- data/lib/cloud_powers/synapse/queue/poller.rb +29 -0
- data/lib/cloud_powers/synapse/synapse.rb +10 -12
- data/lib/cloud_powers/synapse/web_soc.rb +13 -0
- data/lib/cloud_powers/synapse/web_soc/soc_client.rb +52 -0
- data/lib/cloud_powers/synapse/web_soc/soc_server.rb +48 -0
- data/lib/cloud_powers/version.rb +1 -1
- data/lib/cloud_powers/zenv.rb +13 -12
- metadata +24 -13
- data/lib/cloud_powers/context.rb +0 -275
- data/lib/cloud_powers/delegator.rb +0 -113
- data/lib/cloud_powers/helper.rb +0 -453
- data/lib/cloud_powers/synapse/websocket/websocclient.rb +0 -53
- data/lib/cloud_powers/synapse/websocket/websocserver.rb +0 -46
- data/lib/cloud_powers/workflow_factory.rb +0 -160
data/lib/cloud_powers/helper.rb
DELETED
@@ -1,453 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'pathname'
|
4
|
-
require 'uri'
|
5
|
-
require 'syslog/logger'
|
6
|
-
require_relative 'smash_error'
|
7
|
-
|
8
|
-
module Smash
|
9
|
-
module CloudPowers
|
10
|
-
module Helper
|
11
|
-
|
12
|
-
# Sets an Array of instance variables, individually to a value that a
|
13
|
-
# user given block returns.
|
14
|
-
#
|
15
|
-
# Parameters
|
16
|
-
#
|
17
|
-
# * keys +Array+
|
18
|
-
# * * each object will be used as the name for the instance variable that
|
19
|
-
# your block returns
|
20
|
-
# +block+ (optional)
|
21
|
-
# * this block is called for each object in the Array and is used as the value
|
22
|
-
# for the instance variable that is being named and created for each key
|
23
|
-
# Returns Array
|
24
|
-
# * each object will either be the result of `#instance_variable_set(key, value)`
|
25
|
-
# or instance_variable_get(key)
|
26
|
-
# Example
|
27
|
-
# keys = ['foo', 'bar', 'yo']
|
28
|
-
#
|
29
|
-
# attr_map!(keys) { |key| sleep 1; "#{key}:#{Time.now.to_i}" }
|
30
|
-
# # => ['foo:1475434058', 'bar:1475434059', 'yo:1475434060']
|
31
|
-
#
|
32
|
-
# puts @bar
|
33
|
-
# # => 'bar:1475434059'
|
34
|
-
def attr_map!(keys)
|
35
|
-
keys.map do |key|
|
36
|
-
new_i_var = to_i_var(key)
|
37
|
-
value = yield key if block_given?
|
38
|
-
instance_variable_set(new_i_var, value) unless instance_variable_get(new_i_var)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# This is a way to find out if you are trying to work with a resource
|
43
|
-
# available to CloudPowers
|
44
|
-
#
|
45
|
-
# Returns <Array>
|
46
|
-
# Use +.constants+ to find all the modules and classes available.
|
47
|
-
#
|
48
|
-
# Notes
|
49
|
-
# * TODO: make this smartly pick up all the objects, within reason and
|
50
|
-
# considering need, that we have access to
|
51
|
-
def available_resources
|
52
|
-
[:Task].concat(Smash::CloudPowers.constants)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Does its best job at guessing where this method was called from, in terms
|
56
|
-
# of where it is located on the file system. It helps track down where a
|
57
|
-
# project root is etc.
|
58
|
-
#
|
59
|
-
# Returns
|
60
|
-
# +String+
|
61
|
-
#
|
62
|
-
# Notes
|
63
|
-
# * Uses +$0+ to figure out what the current file is
|
64
|
-
def called_from
|
65
|
-
File.expand_path(File.dirname($0))
|
66
|
-
end
|
67
|
-
|
68
|
-
# creates a default logger
|
69
|
-
#
|
70
|
-
# Parameters
|
71
|
-
# * log_to +String+ (optional) - location to send logging information to; default is STDOUT
|
72
|
-
#
|
73
|
-
# Returns
|
74
|
-
# +Logger+
|
75
|
-
#
|
76
|
-
# Notes
|
77
|
-
# * TODO: at least make this have overridable defaults
|
78
|
-
def create_logger(log_to = STDOUT)
|
79
|
-
logger = Logger.new(log_to)
|
80
|
-
logger.datetime_format = '%Y-%m-%d %H:%M:%S'
|
81
|
-
logger
|
82
|
-
end
|
83
|
-
|
84
|
-
# Allows you to modify all keys, including nested, with a block that you pass.
|
85
|
-
# If no block is passed, a copy is returned.
|
86
|
-
#
|
87
|
-
# Parameters
|
88
|
-
# * params +Hash+|+Array+ - hash to be modified
|
89
|
-
# * +block+ (optional) - a block to be used to modify each key should
|
90
|
-
# modify the key and return that value so it can be used in the copy
|
91
|
-
#
|
92
|
-
# Returns
|
93
|
-
# +Hash+|+Array+ - a copy of the given Array or Hash, with all Hash keys modified
|
94
|
-
#
|
95
|
-
# Example
|
96
|
-
# hash = { 'foo' => 'v1', 'bar' => { fleep: { 'florp' => 'yo' } } }
|
97
|
-
# modify_keys_with(hash) { |key| key.to_sym }
|
98
|
-
# # => { foo: 'v1', bar: { fleep: { florp: 'yo' } } }
|
99
|
-
#
|
100
|
-
# Notes
|
101
|
-
# * see `#modify_keys_with()` for handling first-level keys
|
102
|
-
# * see `#pass_the_buck()` for the way nested structures are handled
|
103
|
-
# * case for different types taken from _MultiXML_ (multi_xml.rb)
|
104
|
-
# * TODO: look at optimization
|
105
|
-
def deep_modify_keys_with(params)
|
106
|
-
case params
|
107
|
-
when Hash
|
108
|
-
params.inject({}) do |carry, (k, v)|
|
109
|
-
carry.tap do |h|
|
110
|
-
if block_given?
|
111
|
-
key = yield k
|
112
|
-
|
113
|
-
value = if v.kind_of?(Hash)
|
114
|
-
deep_modify_keys_with(v) { |new_key| Proc.new.call(new_key) }
|
115
|
-
else
|
116
|
-
v
|
117
|
-
end
|
118
|
-
|
119
|
-
h[key] = value
|
120
|
-
else
|
121
|
-
h[k] = v
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
when Array
|
126
|
-
params.map{ |value| symbolize_keys(value) }
|
127
|
-
else
|
128
|
-
params
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
# Join the message and backtrace into a String with line breaks
|
133
|
-
#
|
134
|
-
# Parameters
|
135
|
-
# * error +Exception+
|
136
|
-
#
|
137
|
-
# Returns
|
138
|
-
# +String+
|
139
|
-
def format_error_message(error)
|
140
|
-
begin
|
141
|
-
[error.message, error.backtrace.join("\n")].join("\n")
|
142
|
-
rescue Exception
|
143
|
-
# if the formatting won't work, return the original exception
|
144
|
-
error
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# Gets the path from the environment and sets @log_file using the path
|
149
|
-
#
|
150
|
-
# Returns
|
151
|
-
# @log_file +String+
|
152
|
-
#
|
153
|
-
# Notes
|
154
|
-
# * See +#zfind()+
|
155
|
-
def log_file
|
156
|
-
@log_file ||= zfind('LOG_FILE')
|
157
|
-
end
|
158
|
-
|
159
|
-
# Returns An instance of Logger, cached as @logger@log_file path <String>
|
160
|
-
#
|
161
|
-
# Returns
|
162
|
-
# +Logger+
|
163
|
-
#
|
164
|
-
# Notes
|
165
|
-
# * See +#create_logger+
|
166
|
-
def logger
|
167
|
-
@logger ||= create_logger
|
168
|
-
end
|
169
|
-
|
170
|
-
# Allows you to modify all first-level keys with a block that you pass.
|
171
|
-
# If no block is passed, a copy is returned.
|
172
|
-
#
|
173
|
-
# Parameters
|
174
|
-
# * params +Hash+|+Array+
|
175
|
-
# * block (optional) - should modify the key and return that value so it can be used in the copy
|
176
|
-
#
|
177
|
-
# Returns
|
178
|
-
# +Hash+|+Array+ - a copy of the given Array or Hash, with all Hash keys modified
|
179
|
-
#
|
180
|
-
# Example
|
181
|
-
# hash = { 'foo' => 'v1', 'bar' => { fleep: { 'florp' => 'yo' } } }
|
182
|
-
# modify_keys_with(hash) { |k| k.to_sym }
|
183
|
-
# # => { :foo => 'v1', :bar => { fleep: { 'florp' => 'yo' } } }
|
184
|
-
#
|
185
|
-
# Notes
|
186
|
-
# * see +#deep_modify_keys_with()+ for handling nested keys
|
187
|
-
# * case for different types taken from _MultiXML_ (multi_xml.rb)
|
188
|
-
def modify_keys_with(params)
|
189
|
-
params.inject({}) do |carry, (k, v)|
|
190
|
-
carry.tap do |h|
|
191
|
-
key = block_given? ? (yield k) : k
|
192
|
-
h[key] = v
|
193
|
-
end
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
# Lets you retry a piece of logic with 1 second sleep in between attempts
|
198
|
-
# until another bit of logic does what it's supposed to, kind of like
|
199
|
-
# continuing to poll something and doing something when a package is ready
|
200
|
-
# to be taken and processed.
|
201
|
-
#
|
202
|
-
# Parameters
|
203
|
-
# * allowed_attempts +Number+|+Infinity(default)+ - The number of times
|
204
|
-
# the loop should be allowed to...well, loop, before a failed retry occurs.
|
205
|
-
# * &test +Block+ - A predicate method or block of code that is callable
|
206
|
-
# is used to test if the block being retried is successful yet.
|
207
|
-
# * []
|
208
|
-
#
|
209
|
-
# Example
|
210
|
-
# check_stuff = lambda { |params| return true }
|
211
|
-
# smart_retry(3, check_stuff(params)) { do_stuff_that_needs_to_be_checked }
|
212
|
-
def smart_retry(test, allowed_attempts = Float::INFINITY)
|
213
|
-
result = yield if block_given?
|
214
|
-
tries = 1
|
215
|
-
until test.call(result) || tries >= allowed_attempts
|
216
|
-
result = yield if block_given?
|
217
|
-
tries += 1
|
218
|
-
sleep 1
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
# Gives a common home for tasks to live so they can be easily grouped and
|
223
|
-
# found. This method will create nested directories, based on the
|
224
|
-
# <tt>#project_root()</tt> method and an additional 'lib/tasks' directory.
|
225
|
-
# If no project root has been set by the time this method is called, a new
|
226
|
-
# directory will be created relative to the gem's project root.
|
227
|
-
#
|
228
|
-
# Returns
|
229
|
-
# +String+
|
230
|
-
#
|
231
|
-
# Notes
|
232
|
-
# * # If no project root has been set by the time this method is called, a new
|
233
|
-
# directory will be created relative to the gem's project root. This might
|
234
|
-
# have deeper implications than you want to deal with so it's always a good
|
235
|
-
# idea to set your project root as soon as you can.
|
236
|
-
# * TODO: find a way to have this method figure out the actual project's
|
237
|
-
# root, as opposed to just making common <i>"good"</i> assumptions.
|
238
|
-
def task_home
|
239
|
-
string_th = FileUtils.mkdir_p("#{project_root}/lib/tasks/").first
|
240
|
-
@task_home ||= Pathname.new(string_th).realpath.to_s
|
241
|
-
end
|
242
|
-
|
243
|
-
# Gives the path from the project root to lib/tasks[/#{file}.rb]
|
244
|
-
#
|
245
|
-
# Parameters
|
246
|
-
# * file +String+ (optional) (default is '') - name of a file
|
247
|
-
#
|
248
|
-
# Returns
|
249
|
-
# * path/file +String+ if +file+ parameter is given. return has
|
250
|
-
# '.rb' extension included
|
251
|
-
# * file +String+ if +file+ parameter is not given it will return the <tt>#task_require_path()</tt>
|
252
|
-
#
|
253
|
-
# Notes
|
254
|
-
# * See <tt>#task_home</tt>
|
255
|
-
def task_path(file = '')
|
256
|
-
return task_home if file.empty?
|
257
|
-
Pathname.new("#{task_home}/#{file}").to_s
|
258
|
-
end
|
259
|
-
|
260
|
-
|
261
|
-
# Check if the task file exists in the task directory
|
262
|
-
#
|
263
|
-
# Parameters
|
264
|
-
# * file +String+
|
265
|
-
#
|
266
|
-
# Returns
|
267
|
-
# +Boolean+
|
268
|
-
#
|
269
|
-
# Notes
|
270
|
-
# * See +#task_home()+
|
271
|
-
def task_exist?(file)
|
272
|
-
begin
|
273
|
-
File.new("#{task_home}/#{file}")
|
274
|
-
true
|
275
|
-
rescue Errno::ENOENT
|
276
|
-
false
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
# Gives the path from the project root to lib/tasks[/file]
|
281
|
-
#
|
282
|
-
# Parameters String (optional)
|
283
|
-
# * file_name name of a file
|
284
|
-
#
|
285
|
-
# Returns
|
286
|
-
# * path/file +String+ if +file_name+ was given
|
287
|
-
# * path to task_directory if +file_name+ was <i>not</i> given
|
288
|
-
#
|
289
|
-
# Notes
|
290
|
-
# * Neither path nor file will have a file extension
|
291
|
-
# * See <tt>#task_home</tt>
|
292
|
-
def task_require_path(file_name = '')
|
293
|
-
begin
|
294
|
-
file_sans_extension = File.basename(file_name, '.*')
|
295
|
-
(Pathname.new(task_home) + file_sans_extension).to_s
|
296
|
-
rescue Errno::ENOENT
|
297
|
-
nil
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
# Change strings into camelCase
|
302
|
-
#
|
303
|
-
# Parameters
|
304
|
-
# * var +String+
|
305
|
-
#
|
306
|
-
# Returns
|
307
|
-
# +String+
|
308
|
-
def to_camel(var)
|
309
|
-
var = var.to_s unless var.kind_of? String
|
310
|
-
step_one = to_snake(var)
|
311
|
-
step_two = to_pascal(step_one)
|
312
|
-
step_two[0, 1].downcase + step_two[1..-1]
|
313
|
-
end
|
314
|
-
|
315
|
-
# Change strings into a hyphen delimited phrase
|
316
|
-
#
|
317
|
-
# Parameters
|
318
|
-
# * var +String+
|
319
|
-
#
|
320
|
-
# Returns
|
321
|
-
# +String+
|
322
|
-
def to_hyph(var)
|
323
|
-
var = var.to_s unless var.kind_of? String
|
324
|
-
|
325
|
-
var.gsub(/:{2}|\//, '-').
|
326
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
327
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
328
|
-
gsub(/\s+/, '-').
|
329
|
-
tr("_", "-").
|
330
|
-
gsub(/^\W/, '').
|
331
|
-
downcase
|
332
|
-
end
|
333
|
-
|
334
|
-
# Change strings into an i-var format
|
335
|
-
#
|
336
|
-
# Parameters
|
337
|
-
# * var +String+
|
338
|
-
#
|
339
|
-
# Returns
|
340
|
-
# +String+
|
341
|
-
def to_i_var(var)
|
342
|
-
var = var.to_s unless var.kind_of? String
|
343
|
-
/^\W*@\w+/ =~ var ? to_snake(var) : "@#{to_snake(var)}"
|
344
|
-
end
|
345
|
-
|
346
|
-
# Change strings into PascalCase
|
347
|
-
#
|
348
|
-
# Parameters
|
349
|
-
# * var +String+
|
350
|
-
#
|
351
|
-
# Returns
|
352
|
-
# +String+
|
353
|
-
def to_pascal(var)
|
354
|
-
var = var.to_s unless var.kind_of? String
|
355
|
-
var.gsub(/^(.{1})|\W.{1}|\_.{1}/) { |s| s.gsub(/[^a-z0-9]+/i, '').capitalize }
|
356
|
-
end
|
357
|
-
|
358
|
-
# Change strings into a ruby_file_name with extension
|
359
|
-
#
|
360
|
-
# Parameters
|
361
|
-
# * var +String+
|
362
|
-
#
|
363
|
-
# Returns
|
364
|
-
# +String+
|
365
|
-
#
|
366
|
-
# Notes
|
367
|
-
# * given_string.rb
|
368
|
-
# * includes ruby file extension
|
369
|
-
# * see #to_snake()
|
370
|
-
def to_ruby_file_name(name)
|
371
|
-
name[/\.rb$/].nil? ? "#{to_snake(name)}.rb" : "#{to_snake(name)}"
|
372
|
-
end
|
373
|
-
|
374
|
-
# Change strings into PascalCase
|
375
|
-
#
|
376
|
-
# Parameters
|
377
|
-
# * var +String+
|
378
|
-
#
|
379
|
-
# Returns
|
380
|
-
# +String+
|
381
|
-
#
|
382
|
-
# Notes
|
383
|
-
# * given_string
|
384
|
-
# * will not have file extensions
|
385
|
-
# * see #to_ruby_file_name()
|
386
|
-
def to_snake(var)
|
387
|
-
var = var.to_s unless var.kind_of? String
|
388
|
-
|
389
|
-
var.gsub(/:{2}|\//, '_').
|
390
|
-
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
391
|
-
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
392
|
-
gsub(/\s+/, '_').
|
393
|
-
tr("-", "_").
|
394
|
-
downcase
|
395
|
-
end
|
396
|
-
|
397
|
-
# This method provides a default overrideable message body for things like
|
398
|
-
# basic status updates.
|
399
|
-
#
|
400
|
-
# Parameters
|
401
|
-
# * instanceId +Hash+
|
402
|
-
#
|
403
|
-
# Notes
|
404
|
-
# * camel casing is used on the keys because most other languages prefer
|
405
|
-
# that and it's not a huge problem in ruby. Besides, there's some other
|
406
|
-
# handy methods in this module to get you through those issues, like
|
407
|
-
# +#to_snake()+ and or +#modify_keys_with()+
|
408
|
-
def update_message_body(opts = {})
|
409
|
-
# TODO: Better implementation of merging message bodies and config needed
|
410
|
-
unless opts.kind_of? Hash
|
411
|
-
update = opts.to_s
|
412
|
-
opts = {}
|
413
|
-
opts[:extraInfo] = { message: update }
|
414
|
-
end
|
415
|
-
updated_extra_info = opts.delete(:extraInfo) || {}
|
416
|
-
|
417
|
-
{
|
418
|
-
instanceId: @instance_id || 'none-aquired',
|
419
|
-
type: 'status-update',
|
420
|
-
content: 'running',
|
421
|
-
extraInfo: updated_extra_info
|
422
|
-
}.merge(opts)
|
423
|
-
end
|
424
|
-
|
425
|
-
# Predicate method to check if a String is parsable, as JSON
|
426
|
-
#
|
427
|
-
# Parameters
|
428
|
-
# * json +String+
|
429
|
-
#
|
430
|
-
# Returns
|
431
|
-
# +Boolean+
|
432
|
-
def valid_json?(json)
|
433
|
-
begin
|
434
|
-
JSON.parse(json)
|
435
|
-
true
|
436
|
-
rescue Exception
|
437
|
-
false
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
# Predicate method to check if a String is a valid URL
|
442
|
-
#
|
443
|
-
# Parameters
|
444
|
-
# * url +String+
|
445
|
-
#
|
446
|
-
# Returns
|
447
|
-
# +Boolean+
|
448
|
-
def valid_url?(url)
|
449
|
-
url =~ /\A#{URI::regexp}\z/
|
450
|
-
end
|
451
|
-
end
|
452
|
-
end
|
453
|
-
end
|