cloud_powers 0.2.7.23 → 1.0.0
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.
- 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
|