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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52520a21d53d145c1da6785673db13f6f98bb927
4
- data.tar.gz: fd8646cb8f06cf49a0cdda13e29a0dd64b3b7329
3
+ metadata.gz: 387197029107fc3f0061d3a18ed29c4cfb411540
4
+ data.tar.gz: 51d23676040bac0444f4ac73f261fd48e08f0e24
5
5
  SHA512:
6
- metadata.gz: 5c81bba7df3c682a7b732712f610ba01de5c1d217e61a0da9fe5b4d60286353bbac987539bf36ffc48664610c25da336cd9214b4d76f8cdaa065788fdf9c4e79
7
- data.tar.gz: 5b535a761bdc19a239b3eb5f8cb2a401ed9443428461fa0e8381ee701a27bb84f44c0ebf12c88faa0fb8082171c96bd97c436c3156ed164e438b7fd7e734fb9a
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
- # TODO AWX PROFILE - Must support S3.
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)
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
- template_filename = "#{category}-#{template}-#{DateTime.now.strftime('%Y%m%d-%H%M%S')}.yml"
22
- bucket_path = get_s3_bucket_path
23
- bucket_path = bucket_path == '' ? '' : "#{bucket_path}/"
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
@@ -55,8 +55,12 @@ module App
55
55
  row do
56
56
  column('')
57
57
  column_data.each do |title, data|
58
- color = data[:color].nil? ? 'default' : data[:color]
59
- value = get_value(data[:key], item)
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::AWSCloudFormationCreate::OPTION_STACK_NAME,
114
- AppCommand::AWSCloudFormationCreate::OPTION_PROJECT_ID,
115
- AppCommand::AWSCloudFormationCreate::OPTION_DESCRIPTION,
116
- AppCommand::AWSCloudFormationCreate::OPTION_TERM_PROTECT,
117
- AppCommand::AWSCloudFormationCreate::OPTION_TIMEOUT
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::AWSCloudFormationCreate::SPECIAL ? 'light-grey' : cot
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?
@@ -51,11 +51,12 @@ module App
51
51
 
52
52
  # Validate CloudFormation data (if exist).
53
53
  if @@profile.has_key?(CLOUDFORMATION)
54
- # TODO AWX PROFILE - Must support S3.
55
- cloudformation_template_path = @@profile[CLOUDFORMATION]['Templates']['Local']['Path']
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 void
134
+ # @return string
133
135
  def self.download_s3_ssh_users(use_cache = true)
134
136
  if @@profile.has_key?(SSH_KEYS)
135
- s3 = @@profile[SSH_KEYS]['S3Bucket']
136
- tmp_path = Blufin::AWS::download_s3_data(s3['Name'], s3['Path'], profile: @@profile[PROFILE], region: s3['Region'], use_cache: use_cache)
137
- users = []
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
- Blufin::Files::get_files_in_dir(tmp_path).each do |file|
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
 
@@ -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 = nil
67
- key = nil
68
- width = nil
69
- color = 'default'
70
- formatter = nil
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[export['id']] = resource
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 = 'awx'
18
- SCHEMA_FILE = "#{App::Opt::get_base_path}#{App::Opt::OPT_PATH}/config/schema.yml"
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 = '~/.awx.yml'
21
- SECRET = 'gts8cxeCn1EkzxH3ASXwnz7nboOnf6AjnQhqdjQp8kzxH7q7Ne'
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 - AWS CLOUD FORMATION
48
- if ARGV[0] != 'setup' && ARGV[0] != 'x' && App::AWSProfile::get_profile.has_key?('CloudFormation')
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 - AWS CLOUD FORMATION CREATE
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::AWSCloudFormationCreate.new(opts, args).execute
62
+ AppCommand::CloudFormationCreate.new(opts, args).execute
65
63
  end
66
64
  end
67
- # d - AWS CLOUD FORMATION DETECT-DRIFT
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::AWSCloudFormationDetectDrift.new(opts, args).execute
69
+ AppCommand::CloudFormationDetectDrift.new(opts, args).execute
72
70
  end
73
71
  end
74
- # D - AWS CLOUD FORMATION DELETE
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::AWSCloudFormationDelete.new(opts, args).execute
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 => [:db] do |db|
90
- db.summary 'Run a local instance of DynamoDB'
91
- db.action do |opts, args|
92
- AppCommand::AWSDynamoDB.new(opts, args).execute
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
- # D - DEPLOY
95
+ # d - DEPLOY (DEPRECATED)
98
96
  if ARGV[0] != 'setup' && ARGV[0] != 'x' && (App::AWSProfile::get_profile.has_key?('Projects'))
99
- awx.command :deploy, :aliases => [:D] do |deploy|
100
- deploy.summary 'Deploy application(s) to AWS'
101
- deploy.options do |opts|
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
- deploy.action do |opts, args|
105
- AppCommand::AWSDeploy.new(opts, args).execute
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 - AWS LIST
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::AWSList.new(opts, args).execute
135
+ AppCommand::List.new(opts, args).execute
128
136
  end
129
137
  end
130
138
 
131
- # s - SWITCH
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 => [:s] do |switch|
150
+ awx.command :switch, :aliases => [:S] do |switch|
135
151
  switch.summary 'Switch Profiles'
136
152
  switch.action do |opts, args|
137
- AppCommand::AWSSwitch.new(opts, args).execute
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