awx 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|