awx 0.5.1 → 0.6.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/aws/aws_cloudformation.rb +23 -7
- data/lib/aws/aws_outputter.rb +15 -11
- data/lib/aws/aws_profile.rb +13 -9
- data/lib/aws/aws_reports.rb +18 -16
- data/lib/awx.rb +76 -30
- data/lib/core/deployments.rb +65 -0
- data/lib/core/replacer.rb +282 -0
- data/lib/routes/{aws_cloudformation_create.rb → cloudformation_create.rb} +221 -116
- data/lib/routes/{aws_cloudformation_delete.rb → cloudformation_delete.rb} +1 -1
- data/lib/routes/{aws_cloudformation_detect_drift.rb → cloudformation_detect_drift.rb} +1 -1
- data/lib/routes/{aws_deploy.rb → deploy_deprecated.rb} +11 -8
- data/lib/routes/{aws_dynamo_db.rb → dynamo_db.rb} +1 -1
- data/lib/routes/infrastructure.rb +45 -0
- data/lib/routes/{aws_list.rb → list.rb} +20 -5
- data/lib/routes/ssh.rb +70 -0
- data/lib/routes/{aws_switch.rb → switch.rb} +1 -1
- data/lib/routes/upload.rb +49 -0
- data/lib/version.rb +1 -1
- data/opt/awx/deployment-schema.yml +57 -0
- data/opt/awx/reports.yml +105 -37
- data/opt/config/schema.yml +22 -0
- data/opt/config/template.yml +9 -1
- metadata +17 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 387197029107fc3f0061d3a18ed29c4cfb411540
|
4
|
+
data.tar.gz: 51d23676040bac0444f4ac73f261fd48e08f0e24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f96e2cc1fe271437e8422cd3866bc4f9d9c0474a4ca4d392e0f7e15788ee02ac0fa3f5348f5611d105e39f3b3aeaaee7879f7a5ee7dbad4917c330a17e3393d1
|
7
|
+
data.tar.gz: f0a15ab29c5674987ebacef867fef0d0ab320e8e5d684e3d9f13b653cf03dd38a0b3b441ac1008681b1c2c3ebf901e1223efc18cbd74063f47acfce9b251e74e
|
@@ -5,22 +5,29 @@ module App
|
|
5
5
|
# Gets the path to the root of the cloudformation templates in blufin-secrets repo.
|
6
6
|
# @return string
|
7
7
|
def self.get_cloudformation_path
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
if App::AWSProfile::get_profile[App::AWSProfile::CLOUDFORMATION]['Templates'].has_key?('Local')
|
9
|
+
path = App::AWSProfile::get_profile['CloudFormation']['Templates']['Local']['Path']
|
10
|
+
Blufin::Terminal::error("CloudFormation path not found: #{Blufin::Terminal::format_directory(path)}", 'This probably means directories got renamed or code got changed.', true) unless Blufin::Files::path_exists(path)
|
11
|
+
else
|
12
|
+
path = download_s3_templates
|
13
|
+
end
|
11
14
|
path
|
12
15
|
end
|
13
16
|
|
14
17
|
# Uploads a cloudformation template to S3 (so we can create a stack from it).
|
15
18
|
# Returns the S3 URL.
|
16
19
|
# @return string
|
17
|
-
def self.upload_cloudformation_template(source, category, template)
|
20
|
+
def self.upload_cloudformation_template(source, category, template, filename_override: nil)
|
18
21
|
raise RuntimeError, "File does not exist: #{source}" unless Blufin::Files::file_exists(source)
|
19
22
|
tmp_file = "/tmp/aws-cf-upload-#{category}-#{template}-#{Blufin::Strings::random_string}.yml"
|
20
23
|
Blufin::Terminal::execute("cp #{source} #{tmp_file}", text: "Preparing template: \x1B[38;5;240m#{tmp_file}\x1B[0m")
|
21
|
-
|
22
|
-
bucket_path
|
23
|
-
|
24
|
+
bucket_path = get_s3_bucket_path
|
25
|
+
bucket_path = bucket_path == '' ? '' : "#{bucket_path}/"
|
26
|
+
if filename_override.nil?
|
27
|
+
template_filename = "#{category}-#{template}-#{DateTime.now.strftime('%Y%m%d-%H%M%S')}.yml"
|
28
|
+
else
|
29
|
+
template_filename = filename_override
|
30
|
+
end
|
24
31
|
App::AWSCli::s3_upload(tmp_file, App::AWSProfile::get_profile['CloudFormation']['Uploads']['S3Bucket']['Name'], "#{bucket_path}#{template_filename}")
|
25
32
|
# Return the S3 bucket URL.
|
26
33
|
"#{get_s3_bucket_url}/#{template_filename}"
|
@@ -63,6 +70,15 @@ module App
|
|
63
70
|
results
|
64
71
|
end
|
65
72
|
|
73
|
+
# Downloads templates from S3 into /tmp folder (and returns path to /tmp folder).
|
74
|
+
# @return string
|
75
|
+
def self.download_s3_templates(use_cache = true)
|
76
|
+
raise RuntimeError, "Missing key in #{App::CONFIG_FILE}: #{App::AWSProfile::CLOUDFORMATION}->Templates->S3Bucket" unless App::AWSProfile::get_profile[App::AWSProfile::CLOUDFORMATION]['Templates'].has_key?('S3Bucket')
|
77
|
+
s3 = App::AWSProfile::get_profile[App::AWSProfile::CLOUDFORMATION]['Templates']['S3Bucket']
|
78
|
+
tmp_path = Blufin::AWS::download_s3_data(s3['Name'], s3['Path'], profile: App::AWSProfile::get_profile[App::AWSProfile::PROFILE], region: s3['Region'], use_cache: use_cache)
|
79
|
+
tmp_path
|
80
|
+
end
|
81
|
+
|
66
82
|
end
|
67
83
|
|
68
84
|
end
|
data/lib/aws/aws_outputter.rb
CHANGED
@@ -55,8 +55,12 @@ module App
|
|
55
55
|
row do
|
56
56
|
column('')
|
57
57
|
column_data.each do |title, data|
|
58
|
-
color
|
59
|
-
|
58
|
+
color = data[:color].nil? ? 'default' : data[:color]
|
59
|
+
if data[:key] =~ /^Tags\./
|
60
|
+
value = App::AWSReports::extract_tag(item, data[:key])
|
61
|
+
else
|
62
|
+
value = get_value(data[:key], item)
|
63
|
+
end
|
60
64
|
value, color = get_formatter(data[:formatter], resource: resource, color: color).call(value) unless data[:formatter].nil?
|
61
65
|
column(value, :color => get_color(color))
|
62
66
|
end
|
@@ -110,16 +114,17 @@ module App
|
|
110
114
|
cop = 'light-green'
|
111
115
|
cop = 'purple' if data[:type_internal] == :autocomplete
|
112
116
|
cop = 'light-grey' if data[:type_internal] == :system || [
|
113
|
-
AppCommand::
|
114
|
-
AppCommand::
|
115
|
-
AppCommand::
|
116
|
-
AppCommand::
|
117
|
-
AppCommand::
|
117
|
+
AppCommand::CloudFormationCreate::OPTION_STACK_NAME,
|
118
|
+
AppCommand::CloudFormationCreate::OPTION_PROJECT_ID,
|
119
|
+
AppCommand::CloudFormationCreate::OPTION_DESCRIPTION,
|
120
|
+
AppCommand::CloudFormationCreate::OPTION_TERM_PROTECT,
|
121
|
+
AppCommand::CloudFormationCreate::OPTION_TIMEOUT,
|
122
|
+
AppCommand::CloudFormationCreate::OPTION_OWNER
|
118
123
|
].include?(data[:parameter])
|
119
124
|
# In case you want to change color in future, currently this is redundant.
|
120
125
|
cod = data[:type_internal] == :system ? 'default' : 'default'
|
121
126
|
cot = data[:type_internal] == :system ? 'default' : 'default'
|
122
|
-
cot = data[:type] == AppCommand::
|
127
|
+
cot = data[:type] == AppCommand::CloudFormationCreate::SPECIAL ? 'light-grey' : cot
|
123
128
|
row do
|
124
129
|
column('')
|
125
130
|
column(data[:parameter], :color => get_color(cop))
|
@@ -207,7 +212,7 @@ module App
|
|
207
212
|
[n, color]
|
208
213
|
},
|
209
214
|
'epoch-date' => Proc.new { |n|
|
210
|
-
[DateTime.strptime(n.to_s, '%s'), color]
|
215
|
+
[DateTime.strptime(n.to_i.to_s, '%s'), color]
|
211
216
|
},
|
212
217
|
'region' => Proc.new { |n|
|
213
218
|
preferred_regions = resource.nil? ? [] : resource[App::AWSReports::KEY_REGIONS_PREFERRED]
|
@@ -222,8 +227,7 @@ module App
|
|
222
227
|
zone_color = color
|
223
228
|
ns = n.split('/')
|
224
229
|
[ns[ns.length - 1], zone_color]
|
225
|
-
}
|
226
|
-
|
230
|
+
}
|
227
231
|
}
|
228
232
|
raise RuntimeError, "Key not found: #{key}" unless key.nil? || formatters.has_key?(key)
|
229
233
|
return formatters.keys if key.nil?
|
data/lib/aws/aws_profile.rb
CHANGED
@@ -51,11 +51,12 @@ module App
|
|
51
51
|
|
52
52
|
# Validate CloudFormation data (if exist).
|
53
53
|
if @@profile.has_key?(CLOUDFORMATION)
|
54
|
-
|
55
|
-
|
54
|
+
if @@profile[CLOUDFORMATION]['Templates'].has_key?('Local')
|
55
|
+
cloudformation_template_path = @@profile[CLOUDFORMATION]['Templates']['Local']['Path']
|
56
|
+
errors << "Path not found: #{Blufin::Terminal::format_invalid(cloudformation_template_path)}" unless Blufin::Files::path_exists(cloudformation_template_path)
|
57
|
+
end
|
56
58
|
s3_region = @@profile[CLOUDFORMATION]['Uploads']['S3Bucket']['Region']
|
57
59
|
default_regions = @@profile[CLOUDFORMATION]['Defaults']['Regions']
|
58
|
-
errors << "Path not found: #{Blufin::Terminal::format_invalid(cloudformation_template_path)}" unless Blufin::Files::path_exists(cloudformation_template_path)
|
59
60
|
errors << "Invalid region: #{Blufin::Terminal::format_invalid(s3_region)}" unless App::AWS::VALID_REGIONS.include?(s3_region)
|
60
61
|
errors << "Need atleast 1 default region for: #{Blufin::Terminal::format_invalid('Profiles[].CloudFormation.Defaults.Regions')}" if default_regions.nil? || !default_regions.any?
|
61
62
|
default_regions.each do |default_region|
|
@@ -124,20 +125,22 @@ module App
|
|
124
125
|
@@ssh_users.each do |user, pub_key|
|
125
126
|
Blufin::Terminal::error("Public key not found for user: #{Blufin::Terminal::format_invalid(user)}", "Expected file to exist: #{Blufin::Terminal::format_directory("#{user}.pub", false)}", true) if pub_key.nil?
|
126
127
|
end
|
128
|
+
raise RuntimeError, 'SSHUser Hash is empty. Atleast one user is required.' unless @@ssh_users.is_a?(Hash) && @@ssh_users.any?
|
127
129
|
@@ssh_users
|
128
130
|
end
|
129
131
|
|
130
132
|
# Gets Users from S3.
|
131
133
|
# Can be called multiple times (which you might do if you want to invalidate the cache).
|
132
|
-
# @return
|
134
|
+
# @return string
|
133
135
|
def self.download_s3_ssh_users(use_cache = true)
|
134
136
|
if @@profile.has_key?(SSH_KEYS)
|
135
|
-
s3
|
136
|
-
tmp_path
|
137
|
-
|
137
|
+
s3 = @@profile[SSH_KEYS]['S3Bucket']
|
138
|
+
tmp_path = Blufin::AWS::download_s3_data(s3['Name'], s3['Path'], profile: @@profile[PROFILE], region: s3['Region'], use_cache: use_cache)
|
139
|
+
tmp_path_files = Blufin::Files::get_files_in_dir(tmp_path)
|
140
|
+
users = []
|
138
141
|
# Gets a unique list of users (since every user has 2 files, private and public key).
|
139
|
-
if Blufin::Files::path_exists(tmp_path)
|
140
|
-
|
142
|
+
if Blufin::Files::path_exists(tmp_path) && tmp_path_files.is_a?(Array) && tmp_path_files.any?
|
143
|
+
tmp_path_files.each do |file|
|
141
144
|
users << Blufin::Files::extract_file_name(file, false).gsub(/\.pub$/i, '')
|
142
145
|
end
|
143
146
|
end
|
@@ -148,6 +151,7 @@ module App
|
|
148
151
|
pub_key = "#{tmp_path}/#{user}.pub"
|
149
152
|
@@ssh_users[user] = Blufin::Files::file_exists(pub_key) ? pub_key : nil
|
150
153
|
end
|
154
|
+
tmp_path
|
151
155
|
|
152
156
|
end
|
153
157
|
|
data/lib/aws/aws_reports.rb
CHANGED
@@ -63,20 +63,11 @@ module App
|
|
63
63
|
:formatter => 'region'
|
64
64
|
}
|
65
65
|
data[KEY_COLUMNS].each_with_index do |column, idx|
|
66
|
-
title =
|
67
|
-
key =
|
68
|
-
width =
|
69
|
-
color = 'default'
|
70
|
-
formatter =
|
71
|
-
column.each do |column_inner|
|
72
|
-
column_inner.each do |k, v|
|
73
|
-
title = v if k == 'title'
|
74
|
-
key = v if k == 'key'
|
75
|
-
width = v if k == 'width'
|
76
|
-
color = v if k == 'color'
|
77
|
-
formatter = v if k == 'formatter'
|
78
|
-
end
|
79
|
-
end
|
66
|
+
title = column['title']
|
67
|
+
key = column['key']
|
68
|
+
width = column['width']
|
69
|
+
color = column['color'].nil? ? 'default' : column['color']
|
70
|
+
formatter = column['formatter']
|
80
71
|
['Region'].each do |reserved_column|
|
81
72
|
raise RuntimeError, "#{resource}.#{KEY_COLUMNS}[#{idx}] \xe2\x86\x92 #{reserved_column} is a reserved column." if title.downcase == reserved_column.downcase
|
82
73
|
end
|
@@ -112,7 +103,8 @@ module App
|
|
112
103
|
# Make sure formatter exists.
|
113
104
|
App::AWSOutputter::get_formatter(export['valueFormatter']) if export.has_key?('valueFormatter')
|
114
105
|
export.each { |key, val| raise RuntimeError, "Unexpected key: #{key} (#{val})" unless %w(id value valueFormatter description).include?(key) }
|
115
|
-
export_map[
|
106
|
+
export_map[resource] = [] unless export_map.has_key?(resource)
|
107
|
+
export_map[resource] << export['id']
|
116
108
|
end
|
117
109
|
end
|
118
110
|
end
|
@@ -216,7 +208,7 @@ module App
|
|
216
208
|
results.each do |result|
|
217
209
|
value = result[export['value']]
|
218
210
|
value = App::AWSOutputter::get_formatter(export['valueFormatter']).call(value)[0] if export.has_key?('valueFormatter')
|
219
|
-
sort = result[export['description']] # Used for sorting.
|
211
|
+
sort = export['description'] =~ /^Tags\.[A-Za-z0-9]+$/ ? extract_tag(result, export['description']) : result[export['description']] # Used for sorting.
|
220
212
|
if export.has_key?('description')
|
221
213
|
text = "#{value.rjust(values.max_by(&:length).length.to_i, ' ')} \x1B[38;5;246m\xe2\x80\x94 \x1B[38;5;240m#{sort}\x1B[0m"
|
222
214
|
else
|
@@ -287,6 +279,16 @@ module App
|
|
287
279
|
Blufin::Terminal::error("Root key not found in AWS response: #{Blufin::Terminal::format_invalid(root_key)}", data.to_yaml.split("\n"), true) unless data.has_key?(root_key)
|
288
280
|
end
|
289
281
|
|
282
|
+
# If sort/description is => 'Tags.XXX' this will extract that tag.
|
283
|
+
# @return String
|
284
|
+
def self.extract_tag(data, tag_name)
|
285
|
+
return 'N/A' unless data.is_a?(Hash)
|
286
|
+
return 'N/A' unless data.has_key?('Tags')
|
287
|
+
tag_name = tag_name.gsub(/^Tags\./, '')
|
288
|
+
data['Tags'].each { |tag| return tag['Value'] if tag['Key'] == tag_name }
|
289
|
+
return 'N/A'
|
290
|
+
end
|
291
|
+
|
290
292
|
end
|
291
293
|
|
292
294
|
end
|
data/lib/awx.rb
CHANGED
@@ -14,11 +14,11 @@ Dir["#{File.dirname(__FILE__)}/routes/**/*.rb"].each { |file| load(file) }
|
|
14
14
|
|
15
15
|
module App
|
16
16
|
|
17
|
-
GEM_NAME
|
18
|
-
SCHEMA_FILE
|
17
|
+
GEM_NAME = 'awx'
|
18
|
+
SCHEMA_FILE = "#{App::Opt::get_base_path}#{App::Opt::OPT_PATH}/config/schema.yml"
|
19
19
|
TEMPLATE_FILE = "#{App::Opt::get_base_path}#{App::Opt::OPT_PATH}/config/template.yml"
|
20
|
-
CONFIG_FILE
|
21
|
-
SECRET
|
20
|
+
CONFIG_FILE = '~/.awx.yml'
|
21
|
+
SECRET = 'gts8cxeCn1EkzxH3ASXwnz7nboOnf6AjnQhqdjQp8kzxH7q7Ne'
|
22
22
|
|
23
23
|
def self.execute
|
24
24
|
|
@@ -44,38 +44,36 @@ module App
|
|
44
44
|
TEMPLATE
|
45
45
|
awx.description 'An abstraction layer built around the AWS-cli (written by: Albert Rannetsperger)'
|
46
46
|
|
47
|
-
# c -
|
48
|
-
if ARGV[0] != 'setup' && ARGV[0] != 'x' && App::AWSProfile::get_profile.has_key?(
|
47
|
+
# c - CLOUD FORMATION
|
48
|
+
if ARGV[0] != 'setup' && ARGV[0] != 'x' && App::AWSProfile::get_profile.has_key?(App::AWSProfile::CLOUDFORMATION)
|
49
49
|
awx.command :cloudformation, :aliases => [:c] do |awx_cloudformation|
|
50
50
|
awx_cloudformation.summary 'Create, list and delete cloud-formation stacks'
|
51
|
-
# c -
|
51
|
+
# c - CLOUD FORMATION CREATE
|
52
52
|
awx_cloudformation.command :create, :aliases => [:c] do |awx_cloudformation_create|
|
53
53
|
awx_cloudformation_create.summary 'Create stack'
|
54
54
|
awx_cloudformation_create.options do |opts|
|
55
55
|
opts.opt :clear_cache, 'Clear cache', :short => '-c', :long => '--clear-cache', :type => :boolean
|
56
56
|
opts.opt :rerun, "Re-run previous with cached values (if exists) \xe2\x80\x94 #{Blufin::Terminal::format_invalid('@NotImplemented')}", :short => '-r', :long => '--re-run', :type => :boolean
|
57
|
-
|
58
|
-
# TODO AWX PROFILE - Must support S3.
|
59
|
-
if Blufin::Files::path_exists("#{File.expand_path(App::AWSProfile::get_profile['CloudFormation']['Templates']['Local']['Path'])}/test")
|
57
|
+
if Blufin::Files::path_exists("#{File.expand_path(App::AWSCloudFormation::get_cloudformation_path)}/test")
|
60
58
|
opts.opt :test, 'Run through test-template.', :short => '-t', :long => '--test', :type => :boolean
|
61
59
|
end
|
62
60
|
end
|
63
61
|
awx_cloudformation_create.action do |opts, args|
|
64
|
-
AppCommand::
|
62
|
+
AppCommand::CloudFormationCreate.new(opts, args).execute
|
65
63
|
end
|
66
64
|
end
|
67
|
-
# d -
|
65
|
+
# d - CLOUD FORMATION DETECT-DRIFT
|
68
66
|
awx_cloudformation.command :detect_drift, :aliases => [:d] do |awx_cloudformation_detect_drift|
|
69
67
|
awx_cloudformation_detect_drift.summary 'Detect drift (currently for all stacks)'
|
70
68
|
awx_cloudformation_detect_drift.action do |opts, args|
|
71
|
-
AppCommand::
|
69
|
+
AppCommand::CloudFormationDetectDrift.new(opts, args).execute
|
72
70
|
end
|
73
71
|
end
|
74
|
-
# D -
|
72
|
+
# D - CLOUD FORMATION DELETE
|
75
73
|
awx_cloudformation.command :delete, :aliases => [:D] do |awx_cloudformation_delete|
|
76
74
|
awx_cloudformation_delete.summary 'Delete stack'
|
77
75
|
awx_cloudformation_delete.action do |opts, args|
|
78
|
-
AppCommand::
|
76
|
+
AppCommand::CloudFormationDelete.new(opts, args).execute
|
79
77
|
end
|
80
78
|
end
|
81
79
|
awx_cloudformation.action do
|
@@ -86,28 +84,38 @@ TEMPLATE
|
|
86
84
|
|
87
85
|
# d - DYNAMO-DB
|
88
86
|
if ARGV[0] != 'setup' && ARGV[0] != 'x' && Blufin::Config::get.has_key?('DynamoDBPath')
|
89
|
-
awx.command :dynamodb, :aliases => [:
|
90
|
-
|
91
|
-
|
92
|
-
AppCommand::
|
87
|
+
awx.command :dynamodb, :aliases => [:d] do |dynamodb|
|
88
|
+
dynamodb.summary 'Run a local instance of DynamoDB'
|
89
|
+
dynamodb.action do |opts, args|
|
90
|
+
AppCommand::DynamoDB.new(opts, args).execute
|
93
91
|
end
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
97
|
-
#
|
95
|
+
# d - DEPLOY (DEPRECATED)
|
98
96
|
if ARGV[0] != 'setup' && ARGV[0] != 'x' && (App::AWSProfile::get_profile.has_key?('Projects'))
|
99
|
-
awx.command :
|
100
|
-
|
101
|
-
|
97
|
+
awx.command :deploy_deprecated, :aliases => [:d] do |deploy_deprecated|
|
98
|
+
deploy_deprecated.summary "Deploy application(s) to AWS #{Blufin::Terminal::format_invalid('@deprecated')}"
|
99
|
+
deploy_deprecated.options do |opts|
|
102
100
|
opts.opt :skip_build, 'Skip build', :short => '-S', :long => '--skip-build', :type => :boolean
|
103
101
|
end
|
104
|
-
|
105
|
-
AppCommand::
|
102
|
+
deploy_deprecated.action do |opts, args|
|
103
|
+
AppCommand::DeployDeprecated.new(opts, args).execute
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# i - INFRASTRUCTURE
|
109
|
+
if ARGV[0] != 'setup' && ARGV[0] != 'x' && (App::AWSProfile::get_profile.has_key?('Projects')) && (App::AWSProfile::get_profile.has_key?('Deployments'))
|
110
|
+
awx.command :infrastructure, :aliases => [:i] do |infrastructure|
|
111
|
+
infrastructure.summary 'View, modify & deploy application(s) to pre-defined infrastructure'
|
112
|
+
infrastructure.action do |opts, args|
|
113
|
+
AppCommand::Infrastructure.new(opts, args).execute
|
106
114
|
end
|
107
115
|
end
|
108
116
|
end
|
109
117
|
|
110
|
-
# l -
|
118
|
+
# l - LIST
|
111
119
|
awx.command :list, :aliases => [:l] do |awx_list|
|
112
120
|
awx_list.summary 'List AWS instances/resources'
|
113
121
|
awx_list.options do |opts|
|
@@ -124,17 +132,55 @@ TEMPLATE
|
|
124
132
|
opts.opt :project, "Specify a project \xe2\x80\x94 #{Blufin::Terminal::format_invalid('@NotImplemented')}", :short => '-p', :long => '--project', :type => :string
|
125
133
|
end
|
126
134
|
awx_list.action do |opts, args|
|
127
|
-
AppCommand::
|
135
|
+
AppCommand::List.new(opts, args).execute
|
128
136
|
end
|
129
137
|
end
|
130
138
|
|
131
|
-
# s -
|
139
|
+
# s - SSH
|
140
|
+
awx.command :ssh, :aliases => [:s] do |ssh|
|
141
|
+
ssh.summary 'SSH into EC2 instances'
|
142
|
+
ssh.action do |opts, args|
|
143
|
+
AppCommand::SSH.new(opts, args).execute
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# S - SWITCH
|
132
148
|
if ARGV[0] != 'setup' && ARGV[0] != 'x' && App::AWSProfile::get_profile_names.length > 1
|
133
149
|
# Only show if we have multiple profiles.
|
134
|
-
awx.command :switch, :aliases => [:
|
150
|
+
awx.command :switch, :aliases => [:S] do |switch|
|
135
151
|
switch.summary 'Switch Profiles'
|
136
152
|
switch.action do |opts, args|
|
137
|
-
AppCommand::
|
153
|
+
AppCommand::Switch.new(opts, args).execute
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# u - UPLOAD
|
159
|
+
if ARGV[0] != 'setup' && ARGV[0] != 'x' && (App::AWSProfile::get_profile.has_key?(App::AWSProfile::CLOUDFORMATION) || App::AWSProfile::get_profile.has_key?('Projects'))
|
160
|
+
awx.command :upload, :aliases => [:u] do |upload|
|
161
|
+
upload.summary 'Upload configuration(s) to S3'
|
162
|
+
# p - UPLOAD PROJECTS
|
163
|
+
if App::AWSProfile::get_profile.has_key?('Projects')
|
164
|
+
upload.command :projects, :aliases => [:p] do |upload_projects|
|
165
|
+
upload_projects.summary 'Upload Projects'
|
166
|
+
upload_projects.action do |opts, args|
|
167
|
+
args = args.unshift(AppCommand::Upload::PROJECTS)
|
168
|
+
AppCommand::Upload.new(opts, args).execute
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
# t - UPLOAD TEMPLATE
|
173
|
+
if App::AWSProfile::get_profile.has_key?(App::AWSProfile::CLOUDFORMATION)
|
174
|
+
upload.command :templates, :aliases => [:t] do |upload_templates|
|
175
|
+
upload_templates.summary 'Upload Templates'
|
176
|
+
upload_templates.action do |opts, args|
|
177
|
+
args = args.unshift(AppCommand::Upload::TEMPLATES)
|
178
|
+
AppCommand::Upload.new(opts, args).execute
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
upload.action do
|
183
|
+
system("#{App::GEM_NAME} u -h")
|
138
184
|
end
|
139
185
|
end
|
140
186
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module App
|
2
|
+
|
3
|
+
class Deployments
|
4
|
+
|
5
|
+
SCHEMA_FILE = "#{App::Opt::get_base_path}#{App::Opt::OPT_PATH}/awx/deployment-schema.yml"
|
6
|
+
|
7
|
+
@@deployments = nil
|
8
|
+
|
9
|
+
# Takes a Hash that will have all the deployment info.
|
10
|
+
# @return void
|
11
|
+
def self.init(deployments)
|
12
|
+
raise RuntimeError, 'Cannot run App::Deployments::init() more than once.' unless @@deployments.nil?
|
13
|
+
raise RuntimeError, "Need either a Local or S3Bucket key, found neither: #{deployments.keys}" unless deployments.has_key?('Local') || deployments.has_key?('S3Bucket')
|
14
|
+
@@deployments = {}
|
15
|
+
|
16
|
+
if deployments.has_key?('Local')
|
17
|
+
source_file = File.expand_path(deployments['Local']['File'])
|
18
|
+
# Throw error if source file doesn't exist.
|
19
|
+
Blufin::Terminal::error("Cannot find source file: #{Blufin::Terminal::format_directory(source_file)}") unless Blufin::Files::file_exists(source_file)
|
20
|
+
# Validate the source file against the expected schema.
|
21
|
+
process_source_file(source_file)
|
22
|
+
elsif deployments.has_key?('S3Bucket')
|
23
|
+
|
24
|
+
# TODO - Finish this once we start running this on an EC2 instance (build/deploy server).
|
25
|
+
# TODO - Whatever file we validate should be available on disk locally.
|
26
|
+
# TODO - If the source is an S3 bucket, pull it down into a /tmp folder (on EC2 instance) and validate from there.
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Validate the Deployment YML.
|
38
|
+
# @return void
|
39
|
+
def self.process_source_file(source_file)
|
40
|
+
# Skip empty file.
|
41
|
+
return if Blufin::Files::is_empty(source_file)
|
42
|
+
# Otherwise, validate file.
|
43
|
+
document, errors = Blufin::Config::validate_file(source_file, SCHEMA_FILE)
|
44
|
+
if errors && !errors.empty?
|
45
|
+
errors_output = []
|
46
|
+
errors.each { |e| errors_output << "[#{e.path}] #{e.message}" }
|
47
|
+
Blufin::Terminal::error("Your configuration file is invalid. Please fix: #{Blufin::Terminal::format_directory(source_file)}", errors)
|
48
|
+
else
|
49
|
+
begin
|
50
|
+
file_parsed = YAML.load_file(source_file)
|
51
|
+
rescue => e
|
52
|
+
Blufin::Terminal::error("Failed to parse config file: #{Blufin::Terminal::format_directory(source_file)}", e.message)
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO NOW - FINISH THIS...
|
56
|
+
puts file_parsed.to_yaml
|
57
|
+
exit
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|