blufin-lib 1.6.1 → 1.7.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/lib/blufin-lib.rb +1 -0
- data/lib/core/aws.rb +44 -0
- data/lib/core/projects.rb +137 -172
- data/lib/core/strings.rb +6 -2
- data/lib/core/terminal.rb +50 -45
- data/lib/core/tools.rb +36 -0
- data/lib/core/validate.rb +1 -1
- data/lib/version.rb +1 -1
- data/opt/awx/project-schema.yml +68 -66
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e5791167393d7968f07af6998fd44e3e01682b0
|
4
|
+
data.tar.gz: 7d86180cd83561d70d074d2d1c7e7b4d10145e71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 466b61784d9767ca6d7e32b4277f809dd7b1b79c6f97b9dc183274392d064a102451abbdaf20b9c710223b9c5565b4ed223db7b79f242081ffb7540fc3786ae3
|
7
|
+
data.tar.gz: d3bc26127ee11355383cf88b8a3eca92ab406196cd449ddfbd2430dd9f4235795cb3bd8bcec80e91bb47081ecd0d1ce47094895247f2e48b6d13f8d9e5aa6f18
|
data/lib/blufin-lib.rb
CHANGED
data/lib/core/aws.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Blufin
|
2
|
+
|
3
|
+
module AWS
|
4
|
+
|
5
|
+
# Pulls a file from S3 and saves it to the /tmp folder.
|
6
|
+
# To avoid making multiple calls, caching is turned on by default.
|
7
|
+
# @return string (path to tmp file).
|
8
|
+
def self.download_s3_data(bucket_name, bucket_path, file: nil, profile: nil, region: nil, use_cache: true)
|
9
|
+
raise RuntimeError, 'profile cannot be nil.' if profile.nil?
|
10
|
+
raise RuntimeError, 'region cannot be nil.' if region.nil?
|
11
|
+
bucket_path = Blufin::Strings::remove_surrounding_slashes(bucket_path).strip
|
12
|
+
bucket_path_tmp = bucket_path.length > 0 ? "-#{bucket_path.gsub('/', '-')}" : ''
|
13
|
+
bucket_path_s3 = bucket_path.length > 0 ? "/#{bucket_path}" : ''
|
14
|
+
unless file.nil?
|
15
|
+
bucket_path_tmp = "#{bucket_path_tmp}-#{file}"
|
16
|
+
bucket_path_s3 = "#{bucket_path_s3}/#{file}"
|
17
|
+
end
|
18
|
+
tmp_location = "/tmp/awx-s3-cache-#{bucket_name}#{bucket_path_tmp}"
|
19
|
+
# If path/file exists and we're using cached values, simply return.
|
20
|
+
if file.nil?
|
21
|
+
return tmp_location if Blufin::Files::path_exists(tmp_location) && use_cache && Blufin::Files::get_files_in_dir(tmp_location).any?
|
22
|
+
else
|
23
|
+
return tmp_location if Blufin::Files::file_exists(tmp_location) && use_cache
|
24
|
+
end
|
25
|
+
begin
|
26
|
+
# Clear out all (possibly stale) files.
|
27
|
+
raise RuntimeError unless Blufin::Terminal::execute_proc("Wiping temp-folder: #{Blufin::Terminal::format_directory(tmp_location)}", Proc.new {
|
28
|
+
system("rm -rf #{tmp_location}") if file.nil?
|
29
|
+
system("rm #{tmp_location}") unless file.nil?
|
30
|
+
Blufin::Files::create_directory(tmp_location)
|
31
|
+
}, verbose: true)
|
32
|
+
raise RuntimeError unless Blufin::Terminal::execute("aws s3 cp s3://#{bucket_name}#{bucket_path_s3} #{tmp_location} --recursive --profile #{profile} --region #{region}", verbose: true)
|
33
|
+
tmp_location
|
34
|
+
rescue
|
35
|
+
system("rm -rf #{tmp_location}") if file.nil?
|
36
|
+
system("rm #{tmp_location}") unless file.nil?
|
37
|
+
Blufin::Terminal::error("Unable to download from S3 bucket: #{Blufin::Terminal::format_highlight("s3://#{bucket_name}#{bucket_path_s3}")}", "Either the bucket doesn't exist, you don't have permissions or something else is wrong...", true, false)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/core/projects.rb
CHANGED
@@ -2,79 +2,75 @@ module Blufin
|
|
2
2
|
|
3
3
|
class Projects
|
4
4
|
|
5
|
-
SCHEMA_FILE
|
6
|
-
SCRIPT_RUN
|
7
|
-
SCRIPT_TEST
|
8
|
-
SCRIPT_BUILD
|
9
|
-
SCRIPT_DEPLOY
|
10
|
-
RUN_SCRIPTS
|
11
|
-
TEST_SCRIPTS
|
12
|
-
BUILD_SCRIPTS
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
ALIAS = 'Alias'
|
33
|
-
DOMAIN = 'Domain'
|
5
|
+
SCHEMA_FILE = "#{Blufin::Base::get_base_path}#{Blufin::Base::OPT_PATH}/awx/project-schema.yml"
|
6
|
+
SCRIPT_RUN = 'run'
|
7
|
+
SCRIPT_TEST = 'test'
|
8
|
+
SCRIPT_BUILD = 'build'
|
9
|
+
SCRIPT_DEPLOY = 'deploy'
|
10
|
+
RUN_SCRIPTS = 'RunScripts'
|
11
|
+
TEST_SCRIPTS = 'TestScripts'
|
12
|
+
BUILD_SCRIPTS = 'BuildScripts'
|
13
|
+
ID = 'Id'
|
14
|
+
PROJECT_ID = 'ProjectId'
|
15
|
+
PROJECT = 'Project'
|
16
|
+
TYPE = 'Type'
|
17
|
+
REPOSITORY = 'Repository'
|
18
|
+
DEPLOYMENT = 'Deployment'
|
19
|
+
DEPLOYMENT_BUCKET = 'Bucket'
|
20
|
+
DEPLOYMENT_FILES = 'Files'
|
21
|
+
RUN = 'Run'
|
22
|
+
TEST = 'Test'
|
23
|
+
BUILD = 'Build'
|
24
|
+
COMMANDS = 'Commands'
|
25
|
+
API = 'API'
|
26
|
+
CRON = 'Cron'
|
27
|
+
WORKER = 'Worker'
|
28
|
+
LAMBDA = 'Lambda'
|
29
|
+
TITLE = 'Title'
|
30
|
+
ALIAS = 'Alias'
|
31
|
+
DOMAIN = 'Domain'
|
34
32
|
PROJECT_NAME_PASCAL_CASE = 'ProjectNamePascalCase'
|
35
|
-
PROJECT_NAME
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
PROJECT_NAME = 'ProjectName'
|
34
|
+
PORT = 'Port'
|
35
|
+
PORTS = 'Ports'
|
36
|
+
STAGE = 'Stage'
|
37
|
+
TYPE_ALEXA = 'alexa'
|
38
|
+
TYPE_API = 'api'
|
39
|
+
TYPE_LAMBDA = 'lambda'
|
40
|
+
TYPE_UI = 'ui'
|
41
|
+
VALID_TYPES = [
|
41
42
|
TYPE_ALEXA,
|
42
43
|
TYPE_API,
|
43
44
|
TYPE_LAMBDA,
|
44
45
|
TYPE_UI,
|
45
46
|
]
|
46
47
|
|
47
|
-
@@projects
|
48
|
+
@@projects = nil
|
48
49
|
@@project_names = []
|
49
|
-
@@scripts
|
50
|
-
@@
|
51
|
-
@@
|
52
|
-
@@environments = []
|
50
|
+
@@scripts = nil
|
51
|
+
@@apis = nil
|
52
|
+
@@lambdas = nil
|
53
53
|
|
54
|
-
# Takes a Hash that
|
54
|
+
# Takes a Hash that needs to have a 'Projects' key.
|
55
55
|
# This can come from both .awx.yml['Profiles'] or .blufin.yml (root).
|
56
56
|
# @return void
|
57
|
-
def self.init(
|
57
|
+
def self.init(projects)
|
58
58
|
raise RuntimeError, 'Cannot run Blufin::Projects::init() more than once.' unless @@projects.nil? && @@scripts.nil?
|
59
|
+
raise RuntimeError, "Need either a Local or S3Bucket key, found neither: #{projects.keys}" unless projects.has_key?('Local') || projects.has_key?('S3Bucket')
|
59
60
|
@@projects = {}
|
60
|
-
@@scripts
|
61
|
-
if
|
62
|
-
|
63
|
-
# Throw error if
|
64
|
-
Blufin::Terminal::error("
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
Blufin::Terminal::error("Cannot find source file: #{Blufin::Terminal::format_directory(source_file)}") unless Blufin::Files::file_exists(source_file)
|
69
|
-
# Validate the source file against the expected schema.
|
70
|
-
process_source_file(source_file)
|
71
|
-
elsif projects.has_key?('S3Bucket')
|
61
|
+
@@scripts = {}
|
62
|
+
if projects.has_key?('Local')
|
63
|
+
source_file = File.expand_path(projects['Local']['File'])
|
64
|
+
# Throw error if source file doesn't exist.
|
65
|
+
Blufin::Terminal::error("Cannot find source file: #{Blufin::Terminal::format_directory(source_file)}") unless Blufin::Files::file_exists(source_file)
|
66
|
+
# Validate the source file against the expected schema.
|
67
|
+
process_source_file(source_file)
|
68
|
+
elsif projects.has_key?('S3Bucket')
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
# TODO - Finish this once we start running this on an EC2 instance (build/deploy server).
|
71
|
+
# TODO - Whatever file we validate should be available on disk locally.
|
72
|
+
# TODO - If the source is an S3 bucket, pull it down into a /tmp folder (on EC2 instance) and validate from there.
|
76
73
|
|
77
|
-
end
|
78
74
|
end
|
79
75
|
end
|
80
76
|
|
@@ -102,38 +98,10 @@ module Blufin
|
|
102
98
|
@@apis
|
103
99
|
end
|
104
100
|
|
105
|
-
# Gets
|
106
|
-
# @return Array
|
107
|
-
def self.get_environments
|
108
|
-
@@environments
|
109
|
-
end
|
110
|
-
|
111
|
-
# Get matching deployments for parameters.
|
101
|
+
# Gets Lambda(s).
|
112
102
|
# @return Hash
|
113
|
-
def self.
|
114
|
-
|
115
|
-
@@deployments = {}
|
116
|
-
if @@projects.is_a?(Hash) && @@projects.has_key?(project)
|
117
|
-
project = @@projects[project]
|
118
|
-
project.each do |deployment_id, data|
|
119
|
-
if data.is_a?(Hash) && data.has_key?(SERVERS)
|
120
|
-
servers = data[SERVERS]
|
121
|
-
if servers.is_a?(Array)
|
122
|
-
servers.each do |server|
|
123
|
-
if server.has_key?(REGION) && server[REGION] == region
|
124
|
-
if server.has_key?(STACK) && server[STACK] == stack
|
125
|
-
if server.has_key?(ENVIRONMENTS) && server[ENVIRONMENTS].include?(environment)
|
126
|
-
@@deployments[deployment_id] = data
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
@@deployments
|
103
|
+
def self.get_lambdas
|
104
|
+
@@lambdas
|
137
105
|
end
|
138
106
|
|
139
107
|
# Maps root-level property to enum.
|
@@ -145,8 +113,6 @@ module Blufin
|
|
145
113
|
return TEST_SCRIPTS
|
146
114
|
elsif [BUILD_SCRIPTS, BUILD].include?(script_type)
|
147
115
|
return BUILD_SCRIPTS
|
148
|
-
elsif [DEPLOY_SCRIPTS, DEPLOY].include?(script_type)
|
149
|
-
return DEPLOY_SCRIPTS
|
150
116
|
else
|
151
117
|
raise RuntimeError, "Unhandled script type: #{script_type}"
|
152
118
|
end
|
@@ -175,13 +141,13 @@ module Blufin
|
|
175
141
|
end
|
176
142
|
|
177
143
|
# Buffer script(s).
|
178
|
-
[RUN_SCRIPTS, TEST_SCRIPTS, BUILD_SCRIPTS
|
144
|
+
[RUN_SCRIPTS, TEST_SCRIPTS, BUILD_SCRIPTS].each do |script_type|
|
179
145
|
if file_parsed.has_key?(script_type)
|
180
146
|
if file_parsed[script_type].is_a?(Array)
|
181
|
-
script_key
|
147
|
+
script_key = script_key_mapper(script_type)
|
182
148
|
@@scripts[script_key] = {} unless @@scripts.has_key?(script_key)
|
183
149
|
file_parsed[script_type].each do |script|
|
184
|
-
script_id = script[
|
150
|
+
script_id = script[ID]
|
185
151
|
# Throw error if duplicate script is found for type.
|
186
152
|
Blufin::Terminal::error("#{Blufin::Terminal::format_highlight("#{script_type} - #{script_id}")} \xe2\x80\x94 Duplicate script found: #{Blufin::Terminal::format_invalid(script_id)}") if @@scripts[script_key].has_key?(script_id)
|
187
153
|
@@scripts[script_key][script_id] = script
|
@@ -205,112 +171,102 @@ module Blufin
|
|
205
171
|
file_parsed['Projects'].each do |project|
|
206
172
|
# Validate keys are in specific order.
|
207
173
|
expected = {
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
SERVERS => false,
|
219
|
-
API => false
|
174
|
+
PROJECT_ID => true,
|
175
|
+
PROJECT => true,
|
176
|
+
TYPE => true,
|
177
|
+
REPOSITORY => true,
|
178
|
+
RUN => false,
|
179
|
+
TEST => false,
|
180
|
+
BUILD => false,
|
181
|
+
API => false,
|
182
|
+
LAMBDA => false,
|
183
|
+
DEPLOYMENT => false
|
220
184
|
}
|
221
185
|
Blufin::Validate::assert_valid_keys(expected, project.keys, source_file)
|
222
|
-
project_id
|
186
|
+
project_id = project[PROJECT_ID]
|
223
187
|
project_name = project[PROJECT]
|
224
188
|
project_type = project[TYPE]
|
225
|
-
|
226
189
|
@@project_names << project_name
|
227
|
-
|
228
190
|
# Validate Type.
|
229
191
|
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Invalid Project Type: #{Blufin::Terminal::format_invalid(project_type)}. Valid types are:", VALID_TYPES, true) unless VALID_TYPES.include?(project_type)
|
230
192
|
# Validate Script(s).
|
231
|
-
[RUN, TEST, BUILD
|
193
|
+
[RUN, TEST, BUILD].each do |script_type|
|
232
194
|
if project.has_key?(script_type)
|
233
195
|
# Validate the LAMBDA functions don't need build scripts.
|
234
|
-
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Project type: #{Blufin::Terminal::format_highlight(TYPE_LAMBDA)}
|
235
|
-
if project[script_type].is_a?(
|
236
|
-
script_key
|
196
|
+
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Project type: #{Blufin::Terminal::format_highlight(TYPE_LAMBDA)} does not require #{Blufin::Terminal::format_invalid(script_type)} script(s).", 'This type of project does not support this.', true) if [BUILD].include?(script_type) && project_type == TYPE_LAMBDA
|
197
|
+
if project[script_type].is_a?(Hash)
|
198
|
+
script_key = script_key_mapper(script_type)
|
237
199
|
valid_scripts = []
|
238
200
|
valid_scripts = @@scripts[script_key].keys if @@scripts.has_key?(script_key)
|
239
|
-
project[script_type]
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
end
|
201
|
+
script = project[script_type]
|
202
|
+
script_name = script['Script']
|
203
|
+
unless valid_scripts.include?(script_name)
|
204
|
+
error = valid_scripts.any? ? 'Valid values are:' : "There currently are no #{script_key} script(s) defined."
|
205
|
+
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 #{Blufin::Terminal::format_highlight(script_type)} \xe2\x80\x94 Invalid script reference: #{Blufin::Terminal::format_invalid(script_name)}. #{error}", valid_scripts)
|
245
206
|
end
|
246
207
|
end
|
247
208
|
end
|
248
209
|
end
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
targets[environment] = {} unless targets.has_key?(environment)
|
258
|
-
targets[environment] = {
|
259
|
-
:region => region,
|
260
|
-
:stack => stack,
|
261
|
-
}
|
262
|
-
@@environments << environment
|
263
|
-
end
|
264
|
-
end
|
265
|
-
project[TARGETS] = targets
|
210
|
+
|
211
|
+
# Validate Deployment property.
|
212
|
+
if project.has_key?(DEPLOYMENT)
|
213
|
+
expected = {
|
214
|
+
DEPLOYMENT_BUCKET => true,
|
215
|
+
DEPLOYMENT_FILES => true
|
216
|
+
}
|
217
|
+
Blufin::Validate::assert_valid_keys(expected, project[DEPLOYMENT].keys, source_file)
|
266
218
|
end
|
267
|
-
|
219
|
+
|
220
|
+
# Validate API property.
|
268
221
|
if project_type == TYPE_API
|
269
|
-
# Make sure we have the API
|
222
|
+
# Make sure we have the API property.
|
270
223
|
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Missing property: #{Blufin::Terminal::format_highlight(API)}", "This property is required for project(s) with type: #{API}", true) unless project.has_key?(API)
|
271
|
-
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Missing property: #{Blufin::Terminal::format_highlight(PORT_RANGE)}", "This property is required for project(s) with type: #{API}", true) unless project.has_key?(PORT_RANGE)
|
272
224
|
# Validate keys are in specific order.
|
273
225
|
expected = {
|
274
|
-
TITLE
|
275
|
-
ALIAS
|
276
|
-
DOMAIN
|
277
|
-
PROJECT_NAME
|
278
|
-
PROJECT_NAME_PASCAL_CASE => true
|
226
|
+
TITLE => true,
|
227
|
+
ALIAS => true,
|
228
|
+
DOMAIN => true,
|
229
|
+
PROJECT_NAME => true,
|
230
|
+
PROJECT_NAME_PASCAL_CASE => true,
|
231
|
+
PORTS => true
|
279
232
|
}
|
280
233
|
Blufin::Validate::assert_valid_keys(expected, project[API].keys, source_file)
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
ALIAS => project[API][ALIAS],
|
286
|
-
PROJECT_NAME => project[API][PROJECT_NAME],
|
287
|
-
PROJECT_NAME_PASCAL_CASE => project[API][PROJECT_NAME_PASCAL_CASE],
|
288
|
-
DOMAIN => project[API][DOMAIN],
|
289
|
-
PORT_RANGE => project[PORT_RANGE]
|
234
|
+
expected_ports = {
|
235
|
+
API => true,
|
236
|
+
CRON => true,
|
237
|
+
WORKER => true
|
290
238
|
}
|
239
|
+
Blufin::Validate::assert_valid_keys(expected_ports, project[API][PORTS].keys, source_file)
|
240
|
+
validate_ports([project[API][PORTS][API], project[API][PORTS][CRON], project[API][PORTS][WORKER]], project_id, used_ports)
|
241
|
+
# Add ports to used_ports.
|
242
|
+
used_ports[project[API][PORTS][API]] = project_id
|
243
|
+
used_ports[project[API][PORTS][CRON]] = project_id
|
244
|
+
used_ports[project[API][PORTS][WORKER]] = project_id
|
245
|
+
@@apis = {} if @@apis.nil?
|
246
|
+
@@apis[project[PROJECT_ID]] = project[API]
|
291
247
|
else
|
292
248
|
# Make sure we DON'T have the API key.
|
293
249
|
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Property not supported: #{Blufin::Terminal::format_invalid(API)}", "This property is only allowed for project(s) with type: #{API}", true) if project.has_key?(API)
|
294
250
|
end
|
295
251
|
|
296
|
-
# Validate
|
297
|
-
if
|
298
|
-
|
299
|
-
#
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
Blufin::
|
306
|
-
|
307
|
-
(prs[0].to_i..prs[1].to_i).each do |i|
|
308
|
-
if used_ports.has_key?(i)
|
309
|
-
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Port overlap detected for range: #{Blufin::Terminal::format_invalid(port_range)}", ["The conflicting project is: #{used_ports[i]}"])
|
310
|
-
end
|
311
|
-
end
|
252
|
+
# Validate Lambda property.
|
253
|
+
if project_type == TYPE_LAMBDA
|
254
|
+
# Make sure we have the Lambda
|
255
|
+
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Missing property: #{Blufin::Terminal::format_highlight(LAMBDA)}", "This property is required for project(s) with type: #{LAMBDA}", true) unless project.has_key?(LAMBDA)
|
256
|
+
# Validate keys are in specific order.
|
257
|
+
expected = {
|
258
|
+
PORT => true,
|
259
|
+
STAGE => true
|
260
|
+
}
|
261
|
+
Blufin::Validate::assert_valid_keys(expected, project[LAMBDA].keys, source_file)
|
262
|
+
validate_ports([project[LAMBDA][PORT]], project_id, used_ports)
|
312
263
|
# Add ports to used_ports.
|
313
|
-
|
264
|
+
used_ports[project[LAMBDA][PORT]] = project_id
|
265
|
+
@@lambdas = {} if @@lambdas.nil?
|
266
|
+
@@lambdas[project[PROJECT_ID]] = project[LAMBDA]
|
267
|
+
else
|
268
|
+
# Make sure we DON'T have the Lambda key.
|
269
|
+
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Property not supported: #{Blufin::Terminal::format_invalid(LAMBDA)}", "This property is only allowed for project(s) with type: #{LAMBDA}", true) if project.has_key?(LAMBDA)
|
314
270
|
end
|
315
271
|
|
316
272
|
@@projects[project_name] = {} unless @@projects.has_key?(project_name)
|
@@ -318,9 +274,18 @@ module Blufin
|
|
318
274
|
@@projects[project_name][project_id] = project
|
319
275
|
|
320
276
|
end
|
277
|
+
@@project_names.uniq!
|
278
|
+
@@project_names.sort!
|
279
|
+
end
|
280
|
+
end
|
321
281
|
|
322
|
-
|
323
|
-
|
282
|
+
# Validate the ports. Make sure none of the ports conflict with other projects.
|
283
|
+
# @return void
|
284
|
+
def self.validate_ports(ports, project_id, used_ports)
|
285
|
+
ports.each do |port|
|
286
|
+
if used_ports.has_key?(port)
|
287
|
+
Blufin::Terminal::error("#{project_id} \xe2\x80\x94 Duplicate port detected: #{Blufin::Terminal::format_invalid(port)} ", ["The conflicting project is: #{Blufin::Terminal::format_highlight(used_ports[port])}"])
|
288
|
+
end
|
324
289
|
|
325
290
|
end
|
326
291
|
|
data/lib/core/strings.rb
CHANGED
@@ -89,8 +89,12 @@ module Blufin
|
|
89
89
|
# Generate Random string.
|
90
90
|
# Currently returns something like: 1ec6c763
|
91
91
|
# @return String
|
92
|
-
def self.random_string
|
93
|
-
|
92
|
+
def self.random_string(x = 1)
|
93
|
+
rs = ''
|
94
|
+
x.times do
|
95
|
+
rs = "#{rs}#{SecureRandom.uuid.split('-')[0].downcase}"
|
96
|
+
end
|
97
|
+
rs
|
94
98
|
end
|
95
99
|
|
96
100
|
private
|
data/lib/core/terminal.rb
CHANGED
@@ -12,15 +12,15 @@ module Blufin
|
|
12
12
|
|
13
13
|
extend Columnist
|
14
14
|
|
15
|
-
MSG_INFO
|
16
|
-
MSG_WARNING
|
17
|
-
MSG_ERROR
|
18
|
-
MSG_TODO
|
19
|
-
MSG_AUTOMATIC
|
20
|
-
MSG_GENERATED
|
21
|
-
MSG_PROCESSED
|
22
|
-
MSG_PROGRESS
|
23
|
-
MSG_CUSTOM
|
15
|
+
MSG_INFO = 'info'
|
16
|
+
MSG_WARNING = 'warning'
|
17
|
+
MSG_ERROR = 'error'
|
18
|
+
MSG_TODO = 'todo'
|
19
|
+
MSG_AUTOMATIC = 'automatic'
|
20
|
+
MSG_GENERATED = 'generated'
|
21
|
+
MSG_PROCESSED = 'processed'
|
22
|
+
MSG_PROGRESS = 'progress'
|
23
|
+
MSG_CUSTOM = 'custom'
|
24
24
|
MSG_CUSTOM_AUTO_PAD = 'custom_auto_pad'
|
25
25
|
|
26
26
|
# Runs a series of commands in the terminal.
|
@@ -79,8 +79,8 @@ module Blufin
|
|
79
79
|
# See: https://github.com/piotrmurach/tty-spinner/blob/master/lib/tty/spinner/formats.rb (for spinner options).
|
80
80
|
# @return void
|
81
81
|
def self.execute(command, path = nil, capture: false, verbose: true, text: nil)
|
82
|
-
text
|
83
|
-
t1
|
82
|
+
text = text.is_a?(String) ? text : command
|
83
|
+
t1 = Time.now
|
84
84
|
spinner = TTY::Spinner.new("[:spinner] \x1B[38;5;208m#{text}#{!path.nil? ? " \x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;240m#{path}" : nil}\x1B[0m", format: :dots) if verbose
|
85
85
|
spinner.auto_spin if verbose
|
86
86
|
path = File.expand_path('~/') if path.nil?
|
@@ -89,7 +89,7 @@ module Blufin
|
|
89
89
|
else
|
90
90
|
res = system("cd #{path} && #{command} > /tmp/execute-output")
|
91
91
|
end
|
92
|
-
t2
|
92
|
+
t2 = Time.now
|
93
93
|
delta = "#{'%.3f' % (t2 - t1).abs}s"
|
94
94
|
if res || capture
|
95
95
|
spinner.success("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;46mComplete \x1B[38;5;240m(#{delta})\x1B[0m\x1B[0m") if verbose
|
@@ -108,12 +108,12 @@ module Blufin
|
|
108
108
|
def self.execute_proc(title, proc, verbose: true)
|
109
109
|
raise RuntimeError, "Expected String, instead got:#{title.class}" unless title.is_a?(String)
|
110
110
|
raise RuntimeError, "Expected proc to be an instance of Proc, instead got: #{proc.class}" unless proc.is_a?(Proc)
|
111
|
-
t1
|
111
|
+
t1 = Time.now
|
112
112
|
spinner = nil
|
113
113
|
spinner = TTY::Spinner.new("[:spinner] \x1B[38;5;208m#{title}\x1B[0m", format: :dots) if verbose
|
114
114
|
spinner.auto_spin if verbose
|
115
|
-
res
|
116
|
-
t2
|
115
|
+
res = proc.call
|
116
|
+
t2 = Time.now
|
117
117
|
delta = "#{'%.3f' % (t2 - t1).abs}s"
|
118
118
|
spinner.success("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;46mComplete \x1B[38;5;240m(#{delta})\x1B[0m\x1B[0m") if verbose && res
|
119
119
|
spinner.error("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;196mFailed (#{delta})\x1B[0m") if verbose && !res
|
@@ -159,7 +159,7 @@ module Blufin
|
|
159
159
|
# Displays error and exits script by default.
|
160
160
|
# @return void
|
161
161
|
def self.abort(title = nil, message = nil, exit_script = true, preceding_blank_line = false)
|
162
|
-
title
|
162
|
+
title = 'Abandon ship!' if title.nil?
|
163
163
|
message = "You have chosen to \x1B[38;5;196mABORT\x1B[38;5;240m the script." if message.nil?
|
164
164
|
Blufin::Terminal::error(title, message, exit_script, preceding_blank_line, 'ABORT')
|
165
165
|
end
|
@@ -250,7 +250,7 @@ module Blufin
|
|
250
250
|
# Returns command name in consistent, uniform manner.
|
251
251
|
# @return String
|
252
252
|
def self.format_command(command_name)
|
253
|
-
"\x1B[38;5;
|
253
|
+
"\x1B[38;5;70m$ \x1B[38;5;240m#{command_name}\x1B[0m"
|
254
254
|
end
|
255
255
|
|
256
256
|
# Returns directory name in consistent, uniform manner.
|
@@ -284,16 +284,16 @@ module Blufin
|
|
284
284
|
def self.format_highlight(highlighted_text, capitalize = false, target: nil)
|
285
285
|
case target
|
286
286
|
when 'cf' # CloudFormation
|
287
|
-
color
|
287
|
+
color = 82
|
288
288
|
color_end = "\x1B[38;5;246m"
|
289
289
|
when 'cf-ctt' # CloudFormation (Creation Time Title)
|
290
|
-
color
|
290
|
+
color = 196
|
291
291
|
color_end = "\x1B[38;5;246m"
|
292
292
|
when 'cf-ct' # CloudFormation (Creation Time)
|
293
|
-
color
|
293
|
+
color = 82
|
294
294
|
color_end = "\x1B[38;5;246m"
|
295
295
|
else
|
296
|
-
color
|
296
|
+
color = 117
|
297
297
|
color_end = "\x1B[0m"
|
298
298
|
end
|
299
299
|
if capitalize
|
@@ -326,7 +326,7 @@ module Blufin
|
|
326
326
|
# Gives a prompt where 'y/Y' will return TRUE, 'n/N' will return false, and ANY other key will do nothing.
|
327
327
|
# @return void
|
328
328
|
def self.prompt_yes_no(title = nil, message = nil, confirmation_message = nil, preceding_blank_line = true)
|
329
|
-
title
|
329
|
+
title = 'Please confirm YES or NO.' if title.nil?
|
330
330
|
confirmation_message = 'Would you like to continue?' if confirmation_message.nil?
|
331
331
|
puts if preceding_blank_line
|
332
332
|
puts " \x1B[38;5;231m\x1B[48;5;55m Confirm \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
|
@@ -423,16 +423,26 @@ module Blufin
|
|
423
423
|
if options[0].is_a?(String)
|
424
424
|
prompt.select(display_prompt_text(question), options, per_page: per_page)
|
425
425
|
elsif options[0].is_a?(Hash)
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
426
|
+
options_fixed = []
|
427
|
+
options.each do |option|
|
428
|
+
raise RuntimeError, "Expected option to be Hash, instead got: (#{option.class}) #{option.inspect}" unless option.is_a?(Hash)
|
429
|
+
raise RuntimeError, 'Option is missing key => :text' unless option.has_key?(:text)
|
430
|
+
raise RuntimeError, 'Option is missing key => :value' unless option.has_key?(:value)
|
431
|
+
raise RuntimeError, "Expected :disabled option to be String, instead got: #{option[:disabled].class}" if option.has_key?(:disabled) && !option[:disabled].is_a?(String) && !option[:disabled].nil?
|
432
|
+
v = option[:value]
|
433
|
+
v = 'true' if option[:value].is_a?(TrueClass)
|
434
|
+
v = 'false' if option[:value].is_a?(FalseClass)
|
435
|
+
options_fixed << {:text => option[:text], :value => v}
|
436
|
+
end
|
437
|
+
result = prompt.select(display_prompt_text(question), per_page: per_page) do |menu|
|
438
|
+
options_fixed.each do |option|
|
432
439
|
menu.choice option[:text], option[:value] unless option.has_key?(:disabled)
|
433
440
|
menu.choice option[:text], option[:value], disabled: "\x1B[38;5;196m#{option[:disabled]}\x1B[0m" if option.has_key?(:disabled)
|
434
441
|
end
|
435
442
|
end
|
443
|
+
return true if result == 'true'
|
444
|
+
return false if result == 'false'
|
445
|
+
return result
|
436
446
|
else
|
437
447
|
raise RuntimeError, "Expected options Array to consist of either Strings or Hashes, instead got: #{options.inspect}"
|
438
448
|
end
|
@@ -493,8 +503,8 @@ module Blufin
|
|
493
503
|
def self.prompt_expand(question, options)
|
494
504
|
raise RuntimeError, "Expected Array, instead got #{options.class}" unless options.is_a?(Array)
|
495
505
|
options.each do |option|
|
496
|
-
found_key
|
497
|
-
found_name
|
506
|
+
found_key = false
|
507
|
+
found_name = false
|
498
508
|
found_value = false
|
499
509
|
option.each do |k, v|
|
500
510
|
case k
|
@@ -560,11 +570,11 @@ module Blufin
|
|
560
570
|
# @return void
|
561
571
|
def self.print_files_written(array_of_paths_or_files, message = nil, limit = 10, preceding_blank_line = true)
|
562
572
|
raise RuntimeError, "Expected Array of files, instead got: #{array_of_paths_or_files.class}" unless array_of_paths_or_files.is_a?(Array)
|
563
|
-
message
|
564
|
-
limit
|
573
|
+
message = "Wrote the following #{Blufin::Terminal::format_highlight('files/directories')}" if message.nil?
|
574
|
+
limit = limit.nil? ? 99999999999 : limit.to_i
|
565
575
|
file_output = []
|
566
|
-
file_count
|
567
|
-
file_more
|
576
|
+
file_count = 0
|
577
|
+
file_more = 0
|
568
578
|
array_of_paths_or_files.compact!
|
569
579
|
array_of_paths_or_files.sort!
|
570
580
|
array_of_paths_or_files.each do |path_or_file|
|
@@ -594,13 +604,13 @@ module Blufin
|
|
594
604
|
# @return void
|
595
605
|
def self.code_highlight(string, type, indent = 5)
|
596
606
|
raise RuntimeError, "Expected String, instead got:#{string.class}" unless string.is_a?(String)
|
597
|
-
type
|
607
|
+
type = type.downcase
|
598
608
|
types = {
|
599
|
-
'yml'
|
609
|
+
'yml' => Rouge::Lexers::YAML.new,
|
600
610
|
'json' => Rouge::Lexers::JSON.new
|
601
611
|
}
|
602
612
|
raise RuntimeError, "Lexer not defined for type: #{type}" unless types.has_key?(type)
|
603
|
-
repeat
|
613
|
+
repeat = ' ' * indent
|
604
614
|
formatter = Rouge::Formatters::Terminal256.new
|
605
615
|
formatter.format(types[type].lex(string)).split("\n").each do |line|
|
606
616
|
puts "#{repeat}#{line}"
|
@@ -619,14 +629,9 @@ module Blufin
|
|
619
629
|
else
|
620
630
|
messages = message.split("\n")
|
621
631
|
end
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
row do
|
626
|
-
column('', :align => 'left', :width => 4)
|
627
|
-
column("\x1B[38;5;240m#{new_line}\x1B[0m", :align => 'left', :width => 180)
|
628
|
-
end
|
629
|
-
end
|
632
|
+
messages.each do |line|
|
633
|
+
new_line = line.nil? ? '' : line.to_s.gsub("\x1B[0m", "\x1B[38;5;240m")
|
634
|
+
puts " \x1B[38;5;240m#{new_line}\x1B[0m"
|
630
635
|
end
|
631
636
|
puts
|
632
637
|
end
|
data/lib/core/tools.rb
CHANGED
@@ -102,6 +102,42 @@ module Blufin
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
+
# Returns a value based on OS. If any of the values are nil, throws an Exception.
|
106
|
+
# Linux supports both LINUX and UNIX enums.
|
107
|
+
# @return string
|
108
|
+
def self.value_based_on_os(mac: nil, windows: nil, linux: nil)
|
109
|
+
begin
|
110
|
+
case Blufin::Tools::os
|
111
|
+
when Blufin::Tools::OS_WINDOWS
|
112
|
+
raise RuntimeError if windows.nil?
|
113
|
+
return windows
|
114
|
+
when Blufin::Tools::OS_MAC
|
115
|
+
raise RuntimeError if mac.nil?
|
116
|
+
return mac
|
117
|
+
when Blufin::Tools::OS_LINUX
|
118
|
+
raise RuntimeError if linux.nil?
|
119
|
+
return linux
|
120
|
+
when Blufin::Tools::OS_UNIX
|
121
|
+
raise RuntimeError if linux.nil?
|
122
|
+
return linux
|
123
|
+
else
|
124
|
+
raise RuntimeError
|
125
|
+
end
|
126
|
+
rescue => e
|
127
|
+
Blufin::Terminal::error("This command/operation is not yet supported on: #{Blufin::Terminal::format_highlight(Blufin::Tools::os)}", e.split("\n"), true)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Throws uniform error for non-supported os'.
|
132
|
+
# @return void
|
133
|
+
def self.os_not_supported(array_of_os)
|
134
|
+
raise RuntimeError, "Expected Array, instead got: #{array_of_os.class}" unless array_of_os.is_a?(Array)
|
135
|
+
array_of_os.each { |os| raise RuntimeError, "Unsupported OS value: #{Blufin::Terminal::format_invalid(os)}" unless [OS_MAC, OS_WINDOWS, OS_LINUX, OS_UNIX].include?(os) }
|
136
|
+
current_os = os
|
137
|
+
if array_of_os.include?(current_os)
|
138
|
+
Blufin::Terminal::error("#{Blufin::Terminal::format_highlight(current_os.capitalize)} is not supported to run this command/operation.", 'Someone needs to program it and make it compatible.')
|
139
|
+
end
|
140
|
+
end
|
105
141
|
|
106
142
|
end
|
107
143
|
|
data/lib/core/validate.rb
CHANGED
@@ -9,7 +9,6 @@ module Blufin
|
|
9
9
|
# @return null - If errors, will raise exception.
|
10
10
|
def self.assert_valid_keys(expected, actual, description)
|
11
11
|
raise RuntimeError, "Expected Hash, instead got: #{expected.class}" unless expected.is_a?(Hash)
|
12
|
-
raise RuntimeError, "Expected Array, instead got: #{actual.class}" unless actual.is_a?(Array)
|
13
12
|
errors = []
|
14
13
|
required_keys = []
|
15
14
|
optional_keys = []
|
@@ -48,4 +47,5 @@ module Blufin
|
|
48
47
|
end
|
49
48
|
|
50
49
|
end
|
50
|
+
|
51
51
|
end
|
data/lib/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
BLUFIN_LIB_VERSION = '1.
|
1
|
+
BLUFIN_LIB_VERSION = '1.7.0'
|
data/opt/awx/project-schema.yml
CHANGED
@@ -36,85 +36,66 @@ mapping:
|
|
36
36
|
required: yes
|
37
37
|
sequence:
|
38
38
|
- type: str
|
39
|
-
DeployScripts:
|
40
|
-
type: seq
|
41
|
-
sequence:
|
42
|
-
- type: map
|
43
|
-
mapping:
|
44
|
-
Id:
|
45
|
-
required: yes
|
46
|
-
Commands:
|
47
|
-
type: seq
|
48
|
-
required: yes
|
49
|
-
sequence:
|
50
|
-
- type: str
|
51
39
|
Projects:
|
52
40
|
type: seq
|
53
41
|
required: yes
|
54
42
|
sequence:
|
55
43
|
- type: map
|
56
44
|
mapping:
|
57
|
-
|
58
|
-
required: yes
|
59
|
-
Type:
|
45
|
+
ProjectId:
|
60
46
|
required: yes
|
61
47
|
Project:
|
62
48
|
required: yes
|
63
|
-
|
64
|
-
required: yes
|
65
|
-
RepoPath:
|
49
|
+
Type:
|
66
50
|
required: yes
|
67
|
-
|
51
|
+
Repository:
|
52
|
+
type: map
|
53
|
+
mapping:
|
54
|
+
Local:
|
55
|
+
Remote:
|
56
|
+
required: yes
|
57
|
+
ProjectRoot:
|
58
|
+
required: yes
|
68
59
|
Run:
|
69
|
-
type:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
Script:
|
76
|
-
required: yes
|
60
|
+
type: map
|
61
|
+
mapping:
|
62
|
+
Path:
|
63
|
+
required: yes
|
64
|
+
Script:
|
65
|
+
required: yes
|
77
66
|
Test:
|
78
|
-
type:
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
Script:
|
85
|
-
required: yes
|
67
|
+
type: map
|
68
|
+
mapping:
|
69
|
+
Path:
|
70
|
+
required: yes
|
71
|
+
Script:
|
72
|
+
required: yes
|
86
73
|
Build:
|
87
|
-
type:
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
required: yes
|
113
|
-
Environments:
|
114
|
-
type: seq
|
115
|
-
required: yes
|
116
|
-
sequence:
|
117
|
-
- type: str
|
74
|
+
type: map
|
75
|
+
mapping:
|
76
|
+
Path:
|
77
|
+
required: yes
|
78
|
+
Script:
|
79
|
+
required: yes
|
80
|
+
Deployment:
|
81
|
+
type: map
|
82
|
+
mapping:
|
83
|
+
Bucket:
|
84
|
+
type: map
|
85
|
+
required: yes
|
86
|
+
mapping:
|
87
|
+
Name:
|
88
|
+
required: yes
|
89
|
+
Region:
|
90
|
+
required: yes
|
91
|
+
Files:
|
92
|
+
type: seq
|
93
|
+
required: yes
|
94
|
+
sequence:
|
95
|
+
- type: map
|
96
|
+
mapping:
|
97
|
+
Path:
|
98
|
+
Files:
|
118
99
|
API:
|
119
100
|
type: map
|
120
101
|
mapping:
|
@@ -127,4 +108,25 @@ mapping:
|
|
127
108
|
ProjectName:
|
128
109
|
required: yes
|
129
110
|
ProjectNamePascalCase:
|
111
|
+
required: yes
|
112
|
+
Ports:
|
113
|
+
type: map
|
114
|
+
required: yes
|
115
|
+
mapping:
|
116
|
+
API:
|
117
|
+
type: number
|
118
|
+
required: yes
|
119
|
+
Cron:
|
120
|
+
type: number
|
121
|
+
required: yes
|
122
|
+
Worker:
|
123
|
+
type: number
|
124
|
+
required: yes
|
125
|
+
Lambda:
|
126
|
+
type: map
|
127
|
+
mapping:
|
128
|
+
Port:
|
129
|
+
type: number
|
130
|
+
required: yes
|
131
|
+
Stage:
|
130
132
|
required: yes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blufin-lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert Rannetsperger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: highline
|
@@ -130,6 +130,7 @@ extra_rdoc_files: []
|
|
130
130
|
files:
|
131
131
|
- lib/blufin-lib.rb
|
132
132
|
- lib/core/arrays.rb
|
133
|
+
- lib/core/aws.rb
|
133
134
|
- lib/core/base.rb
|
134
135
|
- lib/core/config.rb
|
135
136
|
- lib/core/datetime_utils.rb
|
@@ -158,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
158
159
|
requirements:
|
159
160
|
- - ">="
|
160
161
|
- !ruby/object:Gem::Version
|
161
|
-
version: '2.
|
162
|
+
version: '2.3'
|
162
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
164
|
requirements:
|
164
165
|
- - ">="
|
@@ -166,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
167
|
version: '0'
|
167
168
|
requirements: []
|
168
169
|
rubyforge_project:
|
169
|
-
rubygems_version: 2.
|
170
|
+
rubygems_version: 2.5.1
|
170
171
|
signing_key:
|
171
172
|
specification_version: 4
|
172
173
|
summary: Blufin Lib
|