awx 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,37 @@
1
+ module AppCommand
2
+
3
+ class AWSCloudFormationDelete < ::Convoy::ActionCommand::Base
4
+
5
+ def execute
6
+
7
+ begin
8
+
9
+ @opts = command_options
10
+ @args = arguments
11
+
12
+ opts_validate
13
+ opts_routing
14
+
15
+ rescue => e
16
+
17
+ Blufin::Terminal::print_exception(e)
18
+
19
+ end
20
+
21
+ end
22
+
23
+ def opts_validate
24
+
25
+ end
26
+
27
+ def opts_routing
28
+
29
+ # TODO - IMPLEMENT
30
+
31
+ raise RuntimeError, 'Not yet implemented! Delete.'
32
+
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,44 @@
1
+ module AppCommand
2
+
3
+ class AWSCloudFormationDetectDrift < ::Convoy::ActionCommand::Base
4
+
5
+ def execute
6
+
7
+ begin
8
+
9
+ @opts = command_options
10
+ @args = arguments
11
+
12
+ @regions = []
13
+ @threads = []
14
+
15
+ opts_validate
16
+ opts_routing
17
+
18
+ rescue => e
19
+
20
+ Blufin::Terminal::print_exception(e)
21
+
22
+ end
23
+
24
+ end
25
+
26
+ def opts_validate
27
+
28
+ @regions = App::AWSValidator::get_and_validate_regions(@opts[:region_given])
29
+
30
+ end
31
+
32
+ def opts_routing
33
+
34
+ # TODO - IMPLEMENT
35
+
36
+ raise RuntimeError, 'Not yet implemented! Detect Drift.'
37
+
38
+
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,122 @@
1
+ require 'json'
2
+ require 'uri'
3
+
4
+ module AppCommand
5
+
6
+ class AWSLambda < ::Convoy::ActionCommand::Base
7
+
8
+ VALID_METHODS = %w(GET POST PUT DELETE)
9
+
10
+ def execute
11
+
12
+ begin
13
+
14
+ @opts = command_options
15
+ @args = arguments
16
+
17
+ @project = @args[0]
18
+ @project_path = nil
19
+ @uri = @args[1]
20
+ @method = @args[2].nil? ? nil : @args[2].upcase
21
+ @file_payload = @opts[:payload_file]
22
+ @file_headers = @opts[:headers_file].nil? ? 'default' : @opts[:headers_file]
23
+ @headers = nil
24
+ @payload = nil
25
+
26
+ @valid_projects = {
27
+ 'bb' => App::Config.param(ConfigUnique::PATH_TO_LAMBDA_BERT),
28
+ 'ew' => App::Config.param(ConfigUnique::PATH_TO_LAMBDA_EWORLD)
29
+ }
30
+
31
+ opts_validate
32
+ opts_routing
33
+
34
+ rescue => e
35
+
36
+ Blufin::Terminal::print_exception(e)
37
+
38
+ end
39
+
40
+ end
41
+
42
+ def opts_validate
43
+
44
+ nil_errors = []
45
+ nil_errors << "#{Blufin::Terminal::format_highlight('1st')} parameter must be #{Blufin::Terminal::format_action('project')}. Valid projects are: #{@valid_projects.keys.join(', ')}" if @project.nil?
46
+ nil_errors << "#{Blufin::Terminal::format_highlight('2nd')} parameter must be #{Blufin::Terminal::format_action('uri')} aka: route to Lambda handler" if @uri.nil? || @uri.strip == ''
47
+ nil_errors << "#{Blufin::Terminal::format_highlight('3rd')} parameter must be #{Blufin::Terminal::format_action('method')}. Valid methods are: #{VALID_METHODS.join(', ')}" if @uri.nil? || @uri.strip == ''
48
+
49
+ # Catch NULL errors first.
50
+ Blufin::Terminal::error('Please fix the following errors:', nil_errors) if nil_errors.any?
51
+
52
+ # Validate project alias.
53
+ Blufin::Terminal::error("#{Blufin::Terminal::format_action('project')} #{Blufin::Terminal::format_highlight(@project.nil? || @project.strip == '' ? 'nil' : @project)} is invalid. Valid project(s) are:", @valid_projects.keys, true) unless @valid_projects.keys.include?(@project)
54
+
55
+ # Validate project path.
56
+ @project_path = @valid_projects[@project]
57
+ Blufin::Terminal::error("#{Blufin::Terminal::format_action('project path')} doesn't exist: #{Blufin::Terminal::format_directory(@project_path)}") unless Blufin::Files::path_exists(@project_path)
58
+
59
+ # Validate HTTP Method.
60
+ Blufin::Terminal::error("#{Blufin::Terminal::format_action('http')} method #{Blufin::Terminal::format_highlight(@method.nil? || @method.strip == '' ? 'nil' : @method)} is invalid. Valid methods are:", VALID_METHODS, true) unless VALID_METHODS.include?(@method)
61
+
62
+ # Validate headers file.
63
+ unless Blufin::Files::file_exists(@file_headers)
64
+ file_headers_alt = "#{@project_path}/json/headers/#{@file_headers.strip.gsub(/(\.json)$/i, '')}.json"
65
+ if Blufin::Files::file_exists(file_headers_alt)
66
+ @file_headers = file_headers_alt
67
+ h_buffer = ''
68
+ Blufin::Files::read_file(@file_headers).each { |line| h_buffer = "#{h_buffer}#{line.gsub("\n", '').strip}" }
69
+ begin
70
+ JSON.parse(h_buffer)
71
+ @headers = h_buffer
72
+ rescue => e
73
+ Blufin::Terminal::error("Failed to parse JSON from #{Blufin::Terminal::format_action('header file')}: #{Blufin::Terminal::format_directory(@file_headers)}", e.message)
74
+ end
75
+ else
76
+ Blufin::Terminal::error("Neither of the following #{Blufin::Terminal::format_action('headers files')} exist:", [@file_headers, file_headers_alt], true)
77
+ end
78
+ end
79
+
80
+ # Validate payload file.
81
+ unless @file_payload.nil?
82
+ unless Blufin::Files::file_exists(@file_payload)
83
+ file_payload_alt = "#{@project_path}/json/payload/#{@file_payload.strip.gsub(/(\.json)$/i, '')}.json"
84
+ if Blufin::Files::file_exists(file_payload_alt)
85
+ @file_payload = file_payload_alt
86
+ p_buffer = ''
87
+ Blufin::Files::read_file(@file_payload).each { |line| p_buffer = "#{p_buffer}#{line.gsub("\n", '').strip}" }
88
+ begin
89
+ JSON.parse(p_buffer)
90
+ @payload = p_buffer
91
+ rescue => e
92
+ Blufin::Terminal::error("Failed to parse JSON from #{Blufin::Terminal::format_action('payload file')}: #{Blufin::Terminal::format_directory(@file_payload)}", e.message)
93
+ end
94
+ else
95
+ Blufin::Terminal::error("Neither of the following #{Blufin::Terminal::format_action('headers files')} exist:", [@file_payload, file_payload_alt], true)
96
+ end
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ def opts_routing
103
+
104
+ headers = @headers.nil? ? nil : ",\"headers\":#{@headers}"
105
+ payload = @payload.nil? ? nil : ",\"body\":\"#{URI::encode(@payload)}\""
106
+
107
+ cmd = "sls invoke local -f main -d '{\"resource\":\"/#{@uri}\",\"path\":\"/#{@uri}\",\"httpMethod\":\"#{@method}\"#{headers}#{payload},\"pathParameters\":{\"hash\":\"cae695cfa2c33ad92ea17e1a03fba99cb9e734dbd4cc4eb8f143bf45e06e81a7rHhP4G070Rzke2O5Vg12A==\"}}'"
108
+ res = Blufin::Terminal::command_capture(cmd, @project_path, true, false)
109
+
110
+ begin
111
+ jsn = JSON.parse(res[0].strip.gsub(/\n$/, '').gsub('\"', '"').gsub('"{', '{').gsub('}"', '}'))
112
+ sts = jsn['statusCode'].to_i
113
+ Blufin::Terminal::custom('Lambda Response', 54, "Status: \x1B[38;5;#{sts == 200 ? 46 : 196}m#{sts}\x1B[0m", JSON.pretty_generate(jsn['body']).split("\n"), true)
114
+ rescue
115
+ Blufin::Terminal::custom('Lambda Response', 54, "Detected #{Blufin::Terminal::format_highlight('console.log()')} or unparseable output:", res[0].split("\n"), true)
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,234 @@
1
+ module AppCommand
2
+
3
+ class AWSList < ::Convoy::ActionCommand::Base
4
+
5
+ def execute
6
+
7
+ begin
8
+
9
+ @opts = command_options
10
+ @args = arguments
11
+
12
+ @resource = nil
13
+ @silent = @opts[:json] || @opts[:json_prompt] || @opts[:yaml]
14
+ @regions = App::AWSCli::get_regions
15
+ @terminal_width = Blufin::Terminal::get_terminal_width
16
+ @data = nil
17
+ @table_widths = {}
18
+ @export_map = {}
19
+ @columns = {}
20
+
21
+ @columns, @data, @export_map, @table_widths = App::AWSReports::parse_metadata(@regions)
22
+
23
+ opts_validate
24
+ opts_routing
25
+
26
+ rescue => e
27
+
28
+ Blufin::Terminal::print_exception(e)
29
+
30
+ end
31
+
32
+ end
33
+
34
+ def opts_validate
35
+
36
+ Blufin::Routes::only_one_of(@opts, [:json, :json_prompt, :yaml])
37
+
38
+ # TODO - Implement!
39
+ if @opts[:region] || @opts[:environment] || @opts[:project]
40
+ raise RuntimeError, 'Not yet implemented!'
41
+ end
42
+
43
+ # Throw error if -m is set with any other flas.
44
+ Blufin::Terminal::error("When #{Blufin::Terminal::format_flag('m')} is set, no other flags can be set.", "Found: #{Blufin::Routes::flags_set(@opts).to_i - 1} other flag(s).", true) if @opts[:metadata] && Blufin::Routes::flags_set(@opts).to_i > 1
45
+
46
+ # For resources with exports, this enables you to pass the -r flag as both AcmCertificates or AcmCertificateARN (and it will resolve to the same API call).
47
+ if @opts[:json_prompt]
48
+ @opts[:resource] = @export_map[@opts[:resource]] if @export_map.has_key?(@opts[:resource])
49
+ end
50
+
51
+ # Validate that resource exists (if passed from command-line).
52
+ unless @opts[:resource].nil?
53
+ if @opts[:resource].downcase == App::AWSReports::CONST_ALL
54
+ Blufin::Terminal::error("The #{Blufin::Terminal::format_flag('v')} cannot be set when listing all resources.") if @opts[:verbose]
55
+ Blufin::Terminal::error("The #{Blufin::Terminal::format_flag('j')} cannot be set when listing all resources.") if @opts[:json]
56
+ Blufin::Terminal::error("The #{Blufin::Terminal::format_flag('j')} cannot be set when listing all resources.") if @opts[:json_prompt]
57
+ Blufin::Terminal::error("The #{Blufin::Terminal::format_flag('y')} cannot be set when listing all resources.") if @opts[:yaml]
58
+ @resource = App::AWSReports::CONST_ALL
59
+ else
60
+ Blufin::Terminal::error("Invalid: #{Blufin::Terminal::format_invalid(@opts[:resource])} . Available resources are:", @data.keys, true) unless @data.has_key?(@opts[:resource])
61
+ @resource = @data[@opts[:resource]]
62
+ end
63
+ end
64
+
65
+ # If response is JSON/YAML, Resource must be explicitly specified.
66
+ if @opts[:json] || @opts[:json_prompt] || @opts[:yaml]
67
+ flag = 'j' if @opts[:json]
68
+ flag = 'J' if @opts[:json_prompt]
69
+ flag = 'y' if @opts[:yaml]
70
+ Blufin::Terminal::error("Must specify #{Blufin::Terminal::format_highlight('resource')} explicitly (using #{Blufin::Terminal::format_flag('r')}) if #{Blufin::Terminal::format_flag(flag)} is set.") if @opts[:resource].nil?
71
+ if @opts[:json_prompt]
72
+ Blufin::Terminal::error("Resource must have #{Blufin::Terminal::format_highlight('export')} defined if #{Blufin::Terminal::format_flag(flag)} is set.") unless @resource.has_key?(App::AWSReports::KEY_EXPORT)
73
+ end
74
+ end
75
+ end
76
+
77
+ def opts_routing
78
+
79
+ system('clear') unless @silent
80
+
81
+ # Display metadata and exit (if -m flag is set)
82
+ if @opts[:metadata]
83
+ App::AWSReports::get_auto_fetch_resources(@data).each do |title, data|
84
+ output = []
85
+ output << "\x1B[38;5;240m AWS-CLI Command:\x1B[38;5;106m #{data[:resource][App::AWSReports::KEY_CLI]['command']}" if data[:resource].has_key?(App::AWSReports::KEY_CLI) && data[:resource][App::AWSReports::KEY_CLI].has_key?('command')
86
+ output << "\x1B[38;5;240m Region(s):\x1B[38;5;94m #{data[:resource][App::AWSReports::KEY_REGIONS].join(', ')}" if data[:resource].has_key?(App::AWSReports::KEY_REGIONS)
87
+ output << "\x1B[38;5;240mPreferred Region(s):\x1B[38;5;94m #{data[:resource][App::AWSReports::KEY_REGIONS_PREFERRED].join(', ')}" if data[:resource].has_key?(App::AWSReports::KEY_REGIONS_PREFERRED)
88
+ Blufin::Terminal::custom(data[:resource_title], 55, "Exports: #{Blufin::Terminal::format_highlight(title)}", output)
89
+ end
90
+ puts
91
+ exit
92
+ end
93
+
94
+ # Select Key (if not already specified using the --resource flag)
95
+ if @resource.nil?
96
+ resource_title = Blufin::Terminal::prompt_select('Select AWS Resource(s) to list:', @data.keys)
97
+ @resource = @data[resource_title]
98
+ else
99
+ resource_title = @opts[:resource]
100
+ end
101
+
102
+ # TODO - REMOVE CACHING
103
+ cache_file = '/tmp/aws-uber-results-cache.txt'
104
+ if !@opts[:resource].nil? && @opts[:resource].downcase == App::AWSReports::CONST_ALL
105
+
106
+ if false && Blufin::Files::file_exists(cache_file)
107
+
108
+ # TODO - REMOVE CACHING
109
+ uber_results = {}
110
+ puts
111
+ puts " \x1B[38;5;196mGetting regional_response from cache: #{Blufin::Terminal::format_directory(cache_file)}\x1B[0m"
112
+ eval("uber_results = #{Blufin::Files::read_file(cache_file)[0]}")
113
+
114
+ else
115
+
116
+ # Get and display all resources.
117
+ uber_results = {}
118
+ cmd_color = 240
119
+ threads = []
120
+ no_fit = []
121
+ puts
122
+ @data.each do |resource_title, resource|
123
+ # Skip tables that don't fit.
124
+ fit_res = fits_in_terminal(resource_title)
125
+ unless fit_res[0]
126
+ no_fit << "\x1B[38;5;196m#{resource_title}\x1B[38;5;240m (required: #{fit_res[1]} / actual: #{fit_res[2]})"
127
+ next
128
+ end
129
+ sleep(0.01)
130
+ cmd_regions = @regions.join(',')
131
+ cmd_regions = resource[App::AWSReports::KEY_REGIONS].join(',') if resource.has_key?(App::AWSReports::KEY_REGIONS)
132
+ cmd_regions = "\x1B[38;5;#{cmd_color}m[\x1B[38;5;246m#{cmd_regions}\x1B[38;5;#{cmd_color}m]\x1B[0m"
133
+ puts " \x1B[38;5;70m$ \x1B[38;5;#{cmd_color}maws #{resource[App::AWSReports::KEY_CLI][App::AWSReports::KEY_COMMAND]} --region #{cmd_regions}\x1B[0m"
134
+ threads << Thread.new {
135
+ uber_results[resource_title] = App::AWSReports::get_aws_data(@regions, resource, resource_title, silent: true)
136
+ }
137
+ end
138
+ # If some tables don't fit, output a warning.
139
+ sleep(0.01)
140
+ if no_fit.any?
141
+ Blufin::Terminal::warning("The following resource(s) will be omitted because they won't fit in the terminal window.", no_fit)
142
+ else
143
+ puts
144
+ end
145
+ Blufin::Terminal::execute_proc('AWS - Fetching data...', Proc.new {
146
+ threads.each { |thread| thread.join }
147
+ })
148
+
149
+ # TODO - REMOVE CACHING
150
+ Blufin::Files::write_file(cache_file, [uber_results.inspect])
151
+
152
+ end
153
+
154
+ puts
155
+ @data.each do |resource_title, resource|
156
+ if uber_results.has_key?(resource_title)
157
+ output_aws_data(uber_results[resource_title], resource, resource_title, silent: false)
158
+ end
159
+ end
160
+
161
+ else
162
+
163
+ # Bomb-out if the output does not fit in Terminal.
164
+ if !@opts[:json] && !@opts[:json_prompt] && !@opts[:yaml] && !fits_in_terminal(resource_title)[0]
165
+ Blufin::Terminal::error("Output for #{Blufin::Terminal::format_highlight(resource_title)} \x1B[38;5;240m(#{Blufin::Terminal::format_action(@table_widths[resource_title])}\x1B[38;5;240m-width)\x1B[0m does not fit in Terminal \x1B[38;5;240m(#{Blufin::Terminal::format_action(@terminal_width)}\x1B[38;5;240m-width)\x1B[0m", 'Please make your terminal wider and try again.', true)
166
+ end
167
+
168
+ # TODO - REMOVE CACHING
169
+ cache_file = "/tmp/aws-results-#{resource_title}-cache.txt"
170
+ if false && Blufin::Files::file_exists(cache_file)
171
+
172
+ # TODO - REMOVE CACHING
173
+ puts
174
+ puts " \x1B[38;5;196mGetting regional_response from cache: #{Blufin::Terminal::format_directory(cache_file)}\x1B[0m"
175
+ results = {}
176
+ eval("results = #{Blufin::Files::read_file(cache_file)[0]}")
177
+
178
+ else
179
+ results = App::AWSReports::get_aws_data(@regions, @resource, resource_title, silent: @silent)
180
+
181
+ # TODO - REMOVE CACHING
182
+ Blufin::Files::write_file(cache_file, [results.inspect])
183
+ end
184
+
185
+ # Get and display a single resource.
186
+ output_aws_data(results, @resource, resource_title, silent: @silent)
187
+ end
188
+
189
+ end
190
+
191
+ private
192
+
193
+ # This outputs the AWS results depending on the flags passed.
194
+ # @return void
195
+ def output_aws_data(results, resource, resource_title, silent: false)
196
+ if @opts[:json]
197
+ puts JSON.pretty_generate(results)
198
+ elsif @opts[:json_prompt]
199
+ puts JSON.pretty_generate(App::AWSReports::parse_results_for_prompt(resource, results))
200
+ elsif @opts[:yaml]
201
+ Blufin::Terminal::code_highlight(results.to_yaml, 'yml', 4)
202
+ else
203
+ unless silent
204
+ if @columns.has_key?(resource_title)
205
+ if @opts[:verbose]
206
+ display_raw_output(results)
207
+ puts
208
+ puts
209
+ end
210
+ App::AWSOutputter::display(resource_title, resource, @columns[resource_title], results, @table_widths[resource_title], @opts, @args)
211
+ else
212
+ Blufin::Terminal::warning("No column(s) defined for resource: #{Blufin::Terminal::format_highlight(resource_title)}", 'Displaying raw AWS output.')
213
+ display_raw_output(results)
214
+ puts
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ # @return void
221
+ def display_raw_output(output)
222
+ output.to_yaml.split("\n").each { |line| puts " \x1B[38;5;240m#{line}\x1B[0m" }
223
+ end
224
+
225
+ # Returns true/false depending if this table fits in the terminal or not.
226
+ # @return []bool, required_width, actual_width]
227
+ def fits_in_terminal(resource_title)
228
+ table_width_adjusted = @table_widths[resource_title] + 2 + 2 + 20 # 2/2 = margins, 20 = * wildcard.
229
+ [@terminal_width >= table_width_adjusted, table_width_adjusted, @terminal_width]
230
+ end
231
+
232
+ end
233
+
234
+ end
@@ -0,0 +1,31 @@
1
+ module AppCommand
2
+
3
+ class Setup < ::Convoy::ActionCommand::Base
4
+
5
+ def execute
6
+
7
+ begin
8
+
9
+ if File.exists?(File.expand_path(App::Config::CONFIG_FILE))
10
+
11
+ App::Config::config_file_edit
12
+ App::Config::config_params_get
13
+ App::Config::config_params_validate(true)
14
+
15
+ else
16
+
17
+ App::Config.initialize
18
+
19
+ end
20
+
21
+ rescue => e
22
+
23
+ Blufin::Terminal::print_exception(e)
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end