awx 0.1.0 → 0.2.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.
@@ -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