opensecret 0.0.2 → 0.0.4
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/Gemfile +4 -0
- data/README.md +2 -2
- data/bin/opensecret +3 -6
- data/lib/opensecret-domain.ini +23 -0
- data/lib/opensecret.rb +30 -2
- data/lib/opensecret/additions/array.rb +117 -0
- data/lib/opensecret/additions/dir.rb +35 -0
- data/lib/opensecret/additions/string.rb +312 -0
- data/lib/opensecret/commons/eco.cmdline.rb +446 -0
- data/lib/opensecret/commons/eco.faculty.rb +364 -0
- data/lib/opensecret/commons/eco.system.rb +437 -0
- data/lib/opensecret/commons/eco.systems.rb +98 -0
- data/lib/opensecret/{safe.rb → delegate.rb} +4 -2
- data/lib/opensecret/eco.do.rb +46 -0
- data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +79 -0
- data/lib/opensecret/executors/crypt.keys/crypt.keys.rb +68 -0
- data/lib/opensecret/executors/decrypt/decrypt.ini +64 -0
- data/lib/opensecret/executors/decrypt/decrypt.rb +49 -0
- data/lib/opensecret/executors/encrypt/encrypt.ini +55 -0
- data/lib/opensecret/executors/encrypt/encrypt.rb +82 -0
- data/lib/opensecret/factbase/hub-runtime.ini +123 -0
- data/lib/opensecret/factbase/known-hosts.ini +75 -0
- data/lib/opensecret/factbase/published.facts/blobbolicious-facts.ini +553 -0
- data/lib/opensecret/factbase/published.facts/credential-facts.ini +40 -0
- data/lib/opensecret/factbase/published.facts/infrastructure-facts.ini +63 -0
- data/lib/opensecret/factbase/readme.md +24 -0
- data/lib/opensecret/factbase/retired.facts/maven.database.ide.facts.ini +127 -0
- data/lib/opensecret/factbase/retired.facts/s3-upload-block-facts.ini +17 -0
- data/lib/opensecret/plugins.io/cipher/crypto.rb +174 -0
- data/lib/opensecret/plugins.io/error/eco.exceptions.rb +24 -0
- data/lib/opensecret/plugins.io/facts/fact.chars.rb +66 -0
- data/lib/opensecret/plugins.io/facts/fact.factor.rb +156 -0
- data/lib/opensecret/plugins.io/facts/fact.locator.rb +105 -0
- data/lib/opensecret/plugins.io/facts/fact.reader.rb +137 -0
- data/lib/opensecret/plugins.io/facts/fact.tree.rb +661 -0
- data/lib/opensecret/plugins.io/file/file.rb +483 -0
- data/lib/opensecret/plugins.io/git/git.flow.rb +388 -0
- data/lib/opensecret/plugins.io/logs/log.object.rb +89 -0
- data/lib/opensecret/plugins.io/logs/logging.rb +203 -0
- data/lib/opensecret/plugins.io/time/time.stamp.rb +425 -0
- data/lib/opensecret/version.rb +2 -2
- data/opensecret.gemspec +8 -13
- metadata +68 -18
@@ -0,0 +1,437 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# --- --------------------------------------------------------------------------------------- -- #
|
4
|
+
# --- Build the [services eco-system]. The app sits at the centre of the services eco-system. -- #
|
5
|
+
# --- Everything that is done -> is done for (because of, to, in spite of) the [application]. -- #
|
6
|
+
# --- --------------------------------------------------------------------------------------- -- #
|
7
|
+
# --- --------------------------------------------------------------------------- --- #
|
8
|
+
# --- The [eco service folder] contains the templates, scripts and configuration. --- #
|
9
|
+
# --- By convention the folder name (off prj root) matches the name of the class. --- #
|
10
|
+
# --- --------------------------------------------------------------------------- --- #
|
11
|
+
# --- Example => ProvisionMongoDb assets are provision.mongo.db --- #
|
12
|
+
# --- --------------------------------------------------------------------------- --- #
|
13
|
+
# --- By Convention --- #
|
14
|
+
# --- Ruby Class => EcoAppServer --- #
|
15
|
+
# --- is Found in File => eco.system.plugins/eco.app.server.rb --- #
|
16
|
+
# --- Has Assets in => provision.app.server/ --- #
|
17
|
+
# --- and Inherits from => ProvisionEcoService --- #
|
18
|
+
# --- Found in File => provision.services/provision.eco.service.rb --- #
|
19
|
+
# --- --------------------------------------------------------------------------- --- #
|
20
|
+
class EcoSystem < EcoFaculty
|
21
|
+
|
22
|
+
# -- -------------------------------------------------------------- -- #
|
23
|
+
# -- eco-system [provisioning] begins in earnest here. By making -- #
|
24
|
+
# -- a [super] call (at the beginning, middle or end) - eco-systems -- #
|
25
|
+
# -- can extend the functionality provided here. -- #
|
26
|
+
# -- -------------------------------------------------------------- -- #
|
27
|
+
# -- To prevent this code running, child classes must provide their -- #
|
28
|
+
# -- own provision along an (optional) alternative implementation. -- #
|
29
|
+
# -- -------------------------------------------------------------- -- #
|
30
|
+
def provision
|
31
|
+
|
32
|
+
super
|
33
|
+
|
34
|
+
pre_provisioning # --> Do work to gather key provisioning facts
|
35
|
+
replace_placeholders # --> Replace key facts in files within the eco folder
|
36
|
+
|
37
|
+
core_provisioning # --> Do the heavy lifting 4 provisioning the eco service
|
38
|
+
|
39
|
+
overwrite_lines # --> Replace pinpointed lines that include a string set.
|
40
|
+
replace_placeholders # --> Replace xtra key facts to prep 4 post provisioning.
|
41
|
+
post_provisioning # --> Notifying service dependents is usually done here.
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
## --- ----------------------------------------------------------------------------- --- #
|
46
|
+
## --- Provision the services eco-system (universe) with the app as the focal point. --- #
|
47
|
+
## --- ----------------------------------------------------------------------------- --- #
|
48
|
+
def pre_provisioning
|
49
|
+
|
50
|
+
read_properties
|
51
|
+
inject_reusables
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# --
|
57
|
+
# -- Implements service discovery for the provisioned eco-system services.
|
58
|
+
# --
|
59
|
+
def post_provisioning
|
60
|
+
|
61
|
+
execute_scripts
|
62
|
+
s3_upload
|
63
|
+
s3_synchronize
|
64
|
+
write_properties
|
65
|
+
sync_2s3_bucket
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
#--
|
71
|
+
#-- Get eco-system reusable directory filepaths within
|
72
|
+
#-- an array.
|
73
|
+
#--
|
74
|
+
#-- The two known directories are
|
75
|
+
#--
|
76
|
+
#-- [1] - reusable.scripts
|
77
|
+
#-- [2] - reusable.templates
|
78
|
+
#--
|
79
|
+
#--
|
80
|
+
def self.reusable_buckets
|
81
|
+
|
82
|
+
project_basedir = File.dirname( File.dirname( __FILE__ ) )
|
83
|
+
reusable_buckets = Array.new
|
84
|
+
|
85
|
+
reusable_buckets.push( File.join(project_basedir, "reusable.scripts") )
|
86
|
+
reusable_buckets.push( File.join(project_basedir, "reusable.templates") )
|
87
|
+
|
88
|
+
return reusable_buckets
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# --
|
94
|
+
# -- Gather the reusable [file] resources from the directoy bucket
|
95
|
+
# -- arrays that are declared to hold these assets.
|
96
|
+
# --
|
97
|
+
# -- The reusables are gathered only if the plugin declares a fact
|
98
|
+
# -- called [:reusables] that is an array of simple filenames.
|
99
|
+
# --
|
100
|
+
# -- This method does a recursive search to find and then copy over
|
101
|
+
# -- these reusable files into the runtime directory.
|
102
|
+
# --
|
103
|
+
# -- ------------------------------
|
104
|
+
# -- Constraint - Duplicate Names
|
105
|
+
# -- ------------------------------
|
106
|
+
# --
|
107
|
+
# -- Duplicate asset filenames introduce ambiguity in as far as
|
108
|
+
# -- reusable assets are concerned. Therefore an error will be
|
109
|
+
# -- raised if this situation arises.
|
110
|
+
# --
|
111
|
+
def inject_reusables
|
112
|
+
|
113
|
+
return unless eco_fact_exists?(:inventory) || eco_fact_exists?(:runnables)
|
114
|
+
files_map = Files.in_folders EcoSystem.reusable_buckets
|
115
|
+
reusables = e_fact(:inventory).merge( e_fact(:runnables) )
|
116
|
+
reusables.each do |source_name, target_name|
|
117
|
+
|
118
|
+
error_1 = "Cannot find reusable [#{source_name}].\n\n#{files_map.inspect}"
|
119
|
+
raise ArgumentError.new error_1 unless files_map.has_key? source_name
|
120
|
+
log.info(ere) {"Copying reusable #{source_name} => to => #{target_name}"}
|
121
|
+
source_file = File.join files_map[source_name], source_name
|
122
|
+
target_file = File.join @c[:runtime][:dir], target_name
|
123
|
+
log.info(ere) {"Source DevOps Asset => #{nickname source_file}"}
|
124
|
+
log.info(ere) {"Target DevOps Asset => #{nickname target_file}"}
|
125
|
+
|
126
|
+
FileUtils.cp source_file, target_file
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# --
|
134
|
+
# -- Use the remote host instantiated for the eco plugin.
|
135
|
+
# -- Upload the plugin folder and run the reusables.
|
136
|
+
# --
|
137
|
+
def execute_scripts
|
138
|
+
|
139
|
+
return unless eco_fact_exists? :runnables
|
140
|
+
|
141
|
+
log.info(ere) { "[collate] ---------------------------------------- --- #" }
|
142
|
+
log.info(ere) { "[collate] collate will upload and execute scripts. --- #" }
|
143
|
+
log.info(ere) { "[collate] ---------------------------------------- --- #" }
|
144
|
+
log.info(ere) { "#{pp e_fact(:runnables).values}" }
|
145
|
+
log.info(ere) { "[collate] ---------------------------------------- --- #" }
|
146
|
+
|
147
|
+
install_dos2unix = "sudo apt-get install -y dos2unix"
|
148
|
+
plugin_host = @c[:machine][:host_class]
|
149
|
+
plugin_host.runtime_dir = @c[:runtime][:dir]
|
150
|
+
|
151
|
+
plugin_host.execute_cmd install_dos2unix
|
152
|
+
plugin_host.upload_folder @c[:runtime][:dstname], @c[:runtime][:dir]
|
153
|
+
|
154
|
+
|
155
|
+
e_fact(:runnables).each_value do | script_name |
|
156
|
+
|
157
|
+
script_path = @c[:runtime][:dstname] + "/" + @c[:runtime][:dirname] + "/" + script_name
|
158
|
+
|
159
|
+
cmd1 = "chmod u+x " + script_path
|
160
|
+
cmd2 = "dos2unix " + script_path
|
161
|
+
cmd3 = script_path
|
162
|
+
|
163
|
+
#### plugin_host.execute_ansible_cmd @c[:runtime][:dir]
|
164
|
+
#### exit
|
165
|
+
|
166
|
+
|
167
|
+
plugin_host.execute_cmd cmd1
|
168
|
+
plugin_host.execute_cmd cmd2
|
169
|
+
plugin_host.execute_cmd cmd3
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
plugin_host.log_remote_host
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
# -- ----------------------------------------------------- -- #
|
179
|
+
# -- sync folder with s3 bucket under certain conditions. -- #
|
180
|
+
# -- ----------------------------------------------------- -- #
|
181
|
+
# -- Sync Conditions -- #
|
182
|
+
# -- ----------------------------------------------------- -- #
|
183
|
+
# -- [1] - running in a unix environment -- #
|
184
|
+
# -- [2] - key [s3sync.bucket.name] exists -- #
|
185
|
+
# -- [3] - key [s3sync.path.offset] exists -- #
|
186
|
+
# -- [4] - s3 bucket exists and is writeable -- #
|
187
|
+
# -- [5] - local dir exists and is readable -- #
|
188
|
+
# -- -- #
|
189
|
+
# -- ----------------------------------------------------- -- #
|
190
|
+
# -- Dependencies and Assumptions -- #
|
191
|
+
# -- ----------------------------------------------------- -- #
|
192
|
+
# -- the aws iam environment variables are set -- #
|
193
|
+
# -- the s3 bucket specified exists and is writable -- #
|
194
|
+
# -- the s3 bucket contents are deletable -- #
|
195
|
+
# -- local path offset off [plugin folder] exists -- #
|
196
|
+
# -- the [awscli] apt-get package is installed -- #
|
197
|
+
# -- ----------------------------------------------------- -- #
|
198
|
+
def s3_synchronize
|
199
|
+
|
200
|
+
return if Gem.win_platform?
|
201
|
+
return unless eco_fact_exists? :s3sync_bucket
|
202
|
+
return unless eco_fact_exists? :s3sync_folder
|
203
|
+
|
204
|
+
log.info(ere) { "[s3 sync] -------------------------------------------- --- #" }
|
205
|
+
log.info(ere) { "[s3 sync] eco plugin running on a non-windows platform --- #" }
|
206
|
+
log.info(ere) { "[s3 sync] with s3 sync parameters available. --- #" }
|
207
|
+
log.info(ere) { "[s3 sync] -------------------------------------------- --- #" }
|
208
|
+
|
209
|
+
AwsS3.instance.log_bucket_summary
|
210
|
+
AwsS3.instance.sync_with_s3 e_fact(:s3sync_bucket), e_fact(:s3sync_folder)
|
211
|
+
AwsS3.instance.log_bucket_summary
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
# --
|
217
|
+
# -- [SYNC] a local folder with a given S3 bucket at a particular
|
218
|
+
# -- folder offset location, with a specific set of sync options.
|
219
|
+
# --
|
220
|
+
# -- This behaviour is driven by a (plugin.id).s3.sync.spec.json
|
221
|
+
# -- specification file that states
|
222
|
+
# --
|
223
|
+
# -- [1] - the source folder whose contents will be sync'd up
|
224
|
+
# -- [2] - the S3 bucket name into which to sync the contents
|
225
|
+
# -- [3] - the S3 folder path offset (within the S3 bucket)
|
226
|
+
# -- [4] - sync options like delete, size-only, acl and more
|
227
|
+
# --
|
228
|
+
def sync_2s3_bucket
|
229
|
+
|
230
|
+
return unless @c.has_key?(:s3_sync) && File.exists?(@c[:s3_sync][:spec_filepath])
|
231
|
+
|
232
|
+
AwsS3.instance.log_bucket_summary
|
233
|
+
|
234
|
+
sync_directives = JSON.parse(
|
235
|
+
File.read(@c[:s3_sync][:spec_filepath]),
|
236
|
+
object_class: OpenStruct
|
237
|
+
)
|
238
|
+
|
239
|
+
sync_directives.each do | sync_directive |
|
240
|
+
|
241
|
+
log.info(ere) { "[sync] ############################################################### ### #" }
|
242
|
+
log.info(ere) { "[sync] --------------------------------------------------------------- --- #" }
|
243
|
+
log.info(ere) { "[sync] sync-ing local folder to s3 bucket [#{sync_directive.s3_bucket_name}]" }
|
244
|
+
log.info(ere) { "[sync] --------------------------------------------------------------- --- #" }
|
245
|
+
log.info(ere) { "[sync] sync source folder => #{sync_directive.local_folder}" }
|
246
|
+
log.info(ere) { "[sync] source bucket name => #{sync_directive.s3_bucket_name}" }
|
247
|
+
log.info(ere) { "[sync] mirror bucket name => #{sync_directive.bucket_b4_name}" }
|
248
|
+
log.info(ere) { "[sync] bucket offset path => #{sync_directive.offset_path}" }
|
249
|
+
log.info(ere) { "[sync] sync options array => #{sync_directive.sync_options}" }
|
250
|
+
log.info(ere) { "[sync] --------------------------------------------------------------- --- #" }
|
251
|
+
|
252
|
+
# --
|
253
|
+
# -- Is it worthwhile to copy between S3 buckets first
|
254
|
+
# -- before sync-ing up the local folder?
|
255
|
+
# --
|
256
|
+
# -- We deem it yes if (and only if)
|
257
|
+
# --
|
258
|
+
# -- a) the to-sync folder is over [10MB]
|
259
|
+
# -- b) a bucket_b4_name has been specified
|
260
|
+
# -- c) the folder to sync does [NOT] exist.
|
261
|
+
# -- d) the b4 folder [DOES] exist.
|
262
|
+
# --
|
263
|
+
# -- If so a S3 [bucket] to [bucket] mirror/copy may
|
264
|
+
# -- dramatically reduce sync time.
|
265
|
+
# --
|
266
|
+
AwsS3.instance.copy_folder_between_buckets(
|
267
|
+
sync_directive.bucket_b4_name,
|
268
|
+
sync_directive.s3_bucket_name,
|
269
|
+
sync_directive.offset_path
|
270
|
+
) if copy_b4_sync_worthwhile?( sync_directive )
|
271
|
+
|
272
|
+
|
273
|
+
AwsS3.instance.sync_local_to_s3(
|
274
|
+
sync_directive.local_folder,
|
275
|
+
sync_directive.s3_bucket_name,
|
276
|
+
sync_directive.offset_path,
|
277
|
+
sync_directive.sync_options
|
278
|
+
)
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
AwsS3.instance.log_bucket_summary
|
283
|
+
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
# --
|
288
|
+
# -- [COPY] from another s3 bucket [B4 SYNC] if [WORTHWHILE]
|
289
|
+
# --
|
290
|
+
# -- Once a month (or week) performance may be gained by copying
|
291
|
+
# -- from the previous s3 bucket before sync-ing the local folder.
|
292
|
+
# --
|
293
|
+
# -- The first [backup] of the new month/week/day is a full backup
|
294
|
+
# -- of a local folder to up-sync. This can take a lot of time for
|
295
|
+
# -- a say [7Gig] folder holding many little files.
|
296
|
+
# --
|
297
|
+
# -- -------------------
|
298
|
+
# -- S3 to S3 Mirror
|
299
|
+
# -- -------------------
|
300
|
+
# -- If we copy (mirror) the previous S3 bucket folder before the
|
301
|
+
# -- sync we gain much in performance because S3 to S3 copying is
|
302
|
+
# -- super fast - then just the delta is sync'd up.
|
303
|
+
# --
|
304
|
+
# -- -------------------------------
|
305
|
+
# -- Pre-Conditions - Copy B4 Sync
|
306
|
+
# -- -------------------------------
|
307
|
+
# --
|
308
|
+
# -- They copy/mirror before sync will occur when the
|
309
|
+
# --
|
310
|
+
# -- 1 - [sync_options.copy_b4_sync_if] flag is [true]
|
311
|
+
# -- 2 - to sync S3 folder (not bucket) does NOT exist
|
312
|
+
# -- 3 - previous periods (month/week..) folder exists
|
313
|
+
# --
|
314
|
+
# -- -------------
|
315
|
+
# -- Assumptions
|
316
|
+
# -- -------------
|
317
|
+
# -- Currently assumes the period is ALWAYS [monthly].
|
318
|
+
# -- Change this to cater for
|
319
|
+
# -- [ hourly, daily, weekly, monthly, quarterly, yearly ]
|
320
|
+
# --
|
321
|
+
def copy_b4_sync_worthwhile? sync_attr
|
322
|
+
|
323
|
+
return false if sync_attr.bucket_b4_name.nil?
|
324
|
+
|
325
|
+
sync_folder_exists =
|
326
|
+
AwsS3.instance.bucket_folder_contains_something?(
|
327
|
+
sync_attr.s3_bucket_name,
|
328
|
+
sync_attr.offset_path
|
329
|
+
)
|
330
|
+
|
331
|
+
return false if sync_folder_exists
|
332
|
+
|
333
|
+
b4_folder_exists =
|
334
|
+
AwsS3.instance.bucket_folder_contains_something?(
|
335
|
+
sync_attr.bucket_b4_name,
|
336
|
+
sync_attr.offset_path
|
337
|
+
)
|
338
|
+
|
339
|
+
return b4_folder_exists
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
# --- ---------------------------------------------------------------------------- --- #
|
345
|
+
# --- Any file in the eco folder whose name starts with [:s3][:upload_prefix] gets --- #
|
346
|
+
# --- uploaded to the S3 provisioning folder (in monthly bucket). Then the url --- #
|
347
|
+
# --- is written into the app properties database with a key that is the remaining --- #
|
348
|
+
# --- filename after the preceeding s3 prefix is removed and subsequently appended --- #
|
349
|
+
# --- appended with the string ".url" --- #
|
350
|
+
# --- ---------------------------------------------------------------------------- --- #
|
351
|
+
def s3_upload
|
352
|
+
|
353
|
+
log.info(ere) { "[s3 upload] examing files in #{@c[:runtime][:dir]}" }
|
354
|
+
|
355
|
+
# -- ------------------------------------------------------------------ -- #
|
356
|
+
# -- Scan folder for files whose names begin with the s3 upload prefix. -- #
|
357
|
+
# -- ------------------------------------------------------------------ -- #
|
358
|
+
Dir.foreach( @c[:runtime][:dir] ) do | file_name |
|
359
|
+
|
360
|
+
file_path = File.join @c[:runtime][:dir], file_name
|
361
|
+
next if File.directory? file_path
|
362
|
+
next unless file_name.start_with? @c[:s3][:upload_prefix]
|
363
|
+
|
364
|
+
read_block_facts __FILE__, __method__, :upload, :src_file_name, file_name
|
365
|
+
Dir.mkdir @c[:s3][:uploads_dir] unless File.exists? @c[:s3][:uploads_dir]
|
366
|
+
next if File.exists? @c[:upload][:dst_file_path]
|
367
|
+
|
368
|
+
FileUtils.cp @c[:upload][:src_file_path], @c[:upload][:dst_file_path]
|
369
|
+
|
370
|
+
AwsS3.instance.log_bucket_summary
|
371
|
+
|
372
|
+
log.warn(ere) { "Warning - Not uploading to S3 bucket = File ==| #{@c[:upload][:dst_file_path]}" }
|
373
|
+
log.warn(ere) { "Warning - Not adding S3 resource URL fact to app_properties fact group." }
|
374
|
+
##### === =============================================================================================
|
375
|
+
##### === Commenting this prevents uploading any file with the s3put tag.
|
376
|
+
##### === =============================================================================================
|
377
|
+
##### === s3_url = AwsS3.instance.upload_to_s3 @c[:s3][:bucket_name], @c[:upload][:dst_file_path]
|
378
|
+
##### === @c.add_fact :app_properties, @c[:upload][:app_props_key], s3_url
|
379
|
+
##### === =============================================================================================
|
380
|
+
|
381
|
+
end
|
382
|
+
|
383
|
+
end
|
384
|
+
|
385
|
+
|
386
|
+
# --
|
387
|
+
# -- [FIND] lines that include a set of configured strings and
|
388
|
+
# -- [REPLACE] then with the configured alternative.
|
389
|
+
# --
|
390
|
+
# -- This behaviour is driven by a (plugin.id).line.replace.json
|
391
|
+
# -- configuration file that states
|
392
|
+
# --
|
393
|
+
# -- [1] - the target file to change
|
394
|
+
# -- [2] - the array of words to match each line against
|
395
|
+
# -- [3] - new line replacing old if all the words match
|
396
|
+
# --
|
397
|
+
# -- -----------------------------------
|
398
|
+
# -- [Pre-Conditions] => Only act when
|
399
|
+
# -- -----------------------------------
|
400
|
+
# --
|
401
|
+
# -- 1. plugin dir has a json [targetting] configuration file
|
402
|
+
# --
|
403
|
+
# -- ---------------------------------
|
404
|
+
# -- [Dependencies and Assumptions]
|
405
|
+
# -- ---------------------------------
|
406
|
+
# --
|
407
|
+
# -- 1. json file is formatted with below keys (and value types)
|
408
|
+
# --
|
409
|
+
# -- - replace_file_path : value type => String
|
410
|
+
# -- - line_search_strings : value type => Array of Strings
|
411
|
+
# -- - replace_with_string : value type => String
|
412
|
+
# --
|
413
|
+
# -- 2. every file specified exists and is readable + writeable
|
414
|
+
# --
|
415
|
+
def overwrite_lines
|
416
|
+
|
417
|
+
return unless File.exists? @c[:overwrite][:spec_filepath]
|
418
|
+
|
419
|
+
pointers = JSON.parse(
|
420
|
+
File.read(@c[:overwrite][:spec_filepath]),
|
421
|
+
object_class: OpenStruct
|
422
|
+
)
|
423
|
+
|
424
|
+
pointers.each do | pinpoint |
|
425
|
+
|
426
|
+
Files.find_replace_lines(
|
427
|
+
pinpoint.replace_file_path,
|
428
|
+
pinpoint.line_search_strings,
|
429
|
+
pinpoint.replace_with_string
|
430
|
+
)
|
431
|
+
|
432
|
+
end
|
433
|
+
|
434
|
+
end
|
435
|
+
|
436
|
+
|
437
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# ---
|
4
|
+
# --- Build the complete services eco-system directed by the parameter service descriptors.
|
5
|
+
# --- Everything that is done -> is done for (because of, to, in spite of) the application.
|
6
|
+
# ---
|
7
|
+
class EcoSystems
|
8
|
+
|
9
|
+
# -
|
10
|
+
# -- Create one or more eco-systems if that is
|
11
|
+
# -- the wish of the commmander (interpreter).
|
12
|
+
# -
|
13
|
+
def self.create
|
14
|
+
|
15
|
+
return unless CmdLine.instance.create || CmdLine.instance.task
|
16
|
+
eco_descriptors = CmdLine.instance.key_values[:service_descriptors]
|
17
|
+
EcoSystems.new.provision_services eco_descriptors
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# --- -------------------------------------------------------------------------- --- #
|
22
|
+
# --- This input array of [service descriptors] are mapped to the below classes. --- #
|
23
|
+
# --- -------------------------------------------------------------------------- --- #
|
24
|
+
# --- the service descriptors => ["mongo.db", "properties", "rest.docs"] --- #
|
25
|
+
# --- -------------------------------------------------------------------------- --- #
|
26
|
+
# --- [eco boot] service => [mongo.db] implemented by => [MongoDb]
|
27
|
+
# --- [eco boot] service => [ properties] implemented by => [Properties]
|
28
|
+
# --- [eco boot] service => [ rest.docs] implemented by => [RestDocs]
|
29
|
+
# --- ------------------------------------------------------------------------- --- #
|
30
|
+
def provision_services service_descriptors
|
31
|
+
|
32
|
+
|
33
|
+
log.info(ere) { "------------------------------------------------------------------- --- #" }
|
34
|
+
log.info(ere) { "[service descriptor to class conversion loop] --- #" }
|
35
|
+
log.info(ere) { "------------------------------------------------------------------- --- #" }
|
36
|
+
|
37
|
+
eco_services = eco_system_classes service_descriptors
|
38
|
+
eco_services.each do |eco_service|
|
39
|
+
|
40
|
+
top_and_tail "Provision the => [#{eco_service.class.name}] eco-system."
|
41
|
+
eco_service.provision
|
42
|
+
top_and_tail "The [#{eco_service.eco_id_str}] => eco system is now [ready]."
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# --- -------------------------------------------------------------------- --- #
|
50
|
+
# --- Create the provisioner classes from the parameter descriptors array. --- #
|
51
|
+
# --- -------------------------------------------------------------------- --- #
|
52
|
+
def eco_system_classes service_descriptors
|
53
|
+
|
54
|
+
log.info(ere) { "[eco boot] service descriptors => #{service_descriptors.to_s}" }
|
55
|
+
eco_services = Array.new
|
56
|
+
|
57
|
+
service_descriptors.each do |class_desc|
|
58
|
+
|
59
|
+
class_name = SnapFlat.undo class_desc
|
60
|
+
log.info(ere) { "[eco boot] service => [#{class_desc}] implemented by => [#{class_name}]" }
|
61
|
+
|
62
|
+
begin
|
63
|
+
|
64
|
+
class_object = Object::const_get("#{class_name}").new
|
65
|
+
|
66
|
+
rescue Exception => e
|
67
|
+
|
68
|
+
log.fatal(ere) { "Exception instantiating eco-system [#{class_name}]." }
|
69
|
+
log.fatal(ere) { "Exception Message => #{e.message}" }
|
70
|
+
log.fatal(ere) { "Exception Backtrace => #{e.backtrace.inspect}" }
|
71
|
+
exit
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
eco_services.push class_object
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
return eco_services
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# --
|
85
|
+
# -- Write the header string as the meat in a highlighted
|
86
|
+
# -- lines sandwich.
|
87
|
+
# --
|
88
|
+
def top_and_tail header_str
|
89
|
+
|
90
|
+
log.info(ere) { "# ### ############################################################## ### #" }
|
91
|
+
log.info(ere) { "# ~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ #" }
|
92
|
+
log.info(ere) { "#{header_str}" }
|
93
|
+
log.info(ere) { "# ~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ #" }
|
94
|
+
log.info(ere) { "# ### ############################################################## ### #" }
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|