lambit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,411 @@
1
+ # encoding: UTF-8
2
+
3
+ using Lambit::Common::StringHelper
4
+ using Lambit::Common::HashHelper
5
+
6
+ module Lambit::Commands
7
+ module Lambdas
8
+ def self.run(cmd, opts, args)
9
+ handler = handler_for cmd
10
+ output, exitstatus = handler.run opts, args
11
+
12
+ # Send Subcommand output to STDOUT if :debug
13
+ if Lambit.is_debug?
14
+ puts output unless output.nil? || output.empty?
15
+ end
16
+
17
+ # Return exit status
18
+ exitstatus
19
+ end
20
+
21
+ def self.normalize_cmd(cmd)
22
+ cmd.to_s.downcase
23
+ end
24
+
25
+ def self.handler_for(cmd)
26
+ if @handlers
27
+ @handlers[normalize_cmd(cmd)]
28
+ else
29
+ raise 'Uh Oh!'
30
+ end
31
+ end
32
+
33
+ def self.register_handler_for(cmd, handler=nil)
34
+ normalized_cmd = normalize_cmd(cmd)
35
+ handler = self.const_get(normalized_cmd.classify) if handler.nil?
36
+
37
+ @handlers ||= {}
38
+ @handlers[normalized_cmd] = handler
39
+ end
40
+
41
+ class Base < Lambit::Commands::Common::Base
42
+ attr_reader :tmpdir, :project_path, :config
43
+ attr_accessor :workspace
44
+
45
+ def initialize(opts, args)
46
+ super
47
+ @tmpdir = opts['tmpdir']
48
+ @workspace = opts['workspace']
49
+ @project_path = opts['project-path']
50
+ @config = Lambit.config
51
+ end
52
+ end
53
+
54
+ class Lambdas < Base
55
+ attr_reader :lambdas, :regexp
56
+ attr_accessor :lambda_config, :function_name, :index, :common_opts
57
+
58
+ def initialize(opts, args)
59
+ super
60
+ @regexp = opts['regexp']
61
+ @lambdas = self.config['lambdas']
62
+ end
63
+
64
+ def parse_hash(hash)
65
+ hash.update(hash) do |k, v|
66
+ if v.respond_to?(:has_key?)
67
+ parse_hash(v)
68
+ elsif v.respond_to?(:each)
69
+ v.flatten.each { |x| parse_hash(x) if x.respond_to?(:has_key?) }
70
+ else
71
+ if v.respond_to?(:to_str)
72
+ eval('"' + v + '"')
73
+ else
74
+ v
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ def filter
81
+ if regexp.nil? || regexp.empty?
82
+ yield
83
+ elsif function_name.match Regexp.new(regexp)
84
+ yield
85
+ end
86
+ end
87
+
88
+ def process
89
+ Lambit.logger.info "Processing Lambda: #{function_name}"
90
+ Lambit.logger.info "Using Workspace: #{workspace}"
91
+ end
92
+
93
+ def command
94
+ self.lambdas.each do |object|
95
+ @lambda_config = Marshal.load(Marshal.dump(object))
96
+ @function_name = @lambda_config['lambda_function']['function_name']
97
+ @workspace = File.join(tmpdir, Lambit.config['name'], function_name)
98
+ @common_opts = {'workspace' => workspace}
99
+ filter { process }
100
+ end
101
+
102
+ return '', self.exitstatus
103
+ end
104
+
105
+ protected
106
+
107
+ def graceful_continue
108
+ begin
109
+ yield
110
+ rescue Exception => e
111
+ if Lambit.is_debug?
112
+ Lambit.logger.error e
113
+ else
114
+ Lambit.logger.error e.message
115
+ end
116
+ end
117
+ end
118
+
119
+ def verbose_msg_for(title, opts, args=nil)
120
+ Lambit.logger.info "#{title} with: #{opts}, #{args}" if Lambit.is_verbose?
121
+ end
122
+ end
123
+
124
+ class BuildLambdas < Lambdas
125
+ def create_workspace
126
+ # TODO: Create Workspaces (src and pkg)
127
+ opts = common_opts
128
+ args = []
129
+ title = "Create Workspace"
130
+
131
+ verbose_msg_for(title, opts, args)
132
+ Lambit::Commands::Common.run :create_workspace_command, common_opts, args unless Lambit.is_dry_run?
133
+ end
134
+
135
+ def package_templates
136
+ lambda_config['templates'].each do |tmpl_name, tmpl_config|
137
+ opts = common_opts.merge('project_path' => self.project_path)
138
+ args = [tmpl_name, tmpl_config]
139
+ title = "Create Templates"
140
+
141
+ verbose_msg_for(title, opts, args)
142
+ Lambit::Commands::Build.run :package_templates_command, opts, args unless Lambit.is_dry_run?
143
+ end if lambda_config['templates']
144
+ end
145
+
146
+ def package_pips
147
+ lambda_config['required_pips'].each do |required_pip|
148
+ opts = common_opts
149
+ args = [required_pip]
150
+ title = "Install pip"
151
+
152
+ verbose_msg_for(title, opts, args)
153
+ Lambit::Commands::Build.run :package_pip_command, opts, args unless Lambit.is_dry_run?
154
+ end if lambda_config['required_pips']
155
+ end
156
+
157
+ def package_source
158
+ opts = common_opts.merge('project_path' => self.project_path)
159
+ args = []
160
+ title = "Package Source"
161
+
162
+ verbose_msg_for(title, opts, args)
163
+ Lambit::Commands::Build.run :package_source_command, opts, args unless Lambit.is_dry_run?
164
+ end
165
+
166
+ def compress_package
167
+ opts = common_opts
168
+ args = []
169
+ title = "Compress Package"
170
+
171
+ verbose_msg_for(title, opts, args)
172
+ Lambit::Commands::Build.run :compress_package_command, common_opts, args unless Lambit.is_dry_run?
173
+ end
174
+
175
+ def process
176
+ super
177
+ # Create Workspace
178
+ graceful_continue { create_workspace }
179
+
180
+ # Package Templates
181
+ graceful_continue { package_templates }
182
+
183
+ # Package Pip(s)
184
+ graceful_continue { package_pips }
185
+
186
+ # Package Source
187
+ graceful_continue { package_source }
188
+
189
+ # Compress Package
190
+ graceful_continue { compress_package }
191
+ end
192
+ end
193
+
194
+ register_handler_for :build_lambdas
195
+
196
+ class CreateLambdas < Lambdas
197
+ def create_lambda
198
+ opt_hash = lambda_config['lambda_function'].merge 'code': {'zip_file': IO.read("#{workspace}/package.zip")}
199
+ opt_hashv = lambda_config['lambda_function'].merge('code': {'zip_file': 'IO.read("#{workspace}/package.zip"'})
200
+ opts = opt_hash.symbolize_keys
201
+ optsv = opt_hashv.symbolize_keys
202
+ title = "Deploy"
203
+
204
+ verbose_msg_for(title, optsv)
205
+ Lambit::Aws::Lambda::Function.new(opts).create_function unless Lambit.is_dry_run?
206
+ end
207
+
208
+ def process
209
+ super
210
+ graceful_continue { create_lambda }
211
+ end
212
+ end
213
+
214
+ register_handler_for :create_lambdas
215
+
216
+ class DeleteLambdas < Lambdas
217
+ def delete_lambda
218
+ opt_hash = lambda_config['lambda_function'].symbolize_keys
219
+ opts = opt_hash.symbolize_keys
220
+ title = "Delete"
221
+
222
+ verbose_msg_for(title, opts)
223
+ Lambit::Aws::Lambda::Function.new(opts).delete_function unless Lambit.is_dry_run?
224
+ end
225
+
226
+ def process
227
+ super
228
+ graceful_continue { delete_lambda }
229
+ end
230
+ end
231
+
232
+ register_handler_for :delete_lambdas
233
+
234
+ class AddEventSourcesLambdas < Lambdas
235
+ def add_lambda_permissions
236
+ lambda_config['lambda_permissions'].each_with_index do |permission, index|
237
+ @index = index
238
+ opt_hash = parse_hash(permission)
239
+ opts = opt_hash.symbolize_keys
240
+ title = "Add Lambda Permission"
241
+
242
+ verbose_msg_for(title, opts)
243
+ Lambit::Aws::Lambda::Permission.new(opts).add unless Lambit.is_dry_run?
244
+ end if lambda_config['lambda_permissions']
245
+ end
246
+
247
+ def add_s3_bucket_notification_configurations
248
+ lambda_config['s3_bucket_notification_configurations'].each_with_index do |configuration, index|
249
+ @index = index
250
+ opt_hash = parse_hash(configuration)
251
+ opts = opt_hash.symbolize_keys_deep
252
+ title = "Add S3 Bucket Configurations"
253
+
254
+ verbose_msg_for(title, opts)
255
+ Lambit::Aws::S3::BucketNotificationConfiguration.new(opts).add unless Lambit.is_dry_run?
256
+ end if lambda_config['s3_bucket_notification_configurations']
257
+ end
258
+
259
+ def put_cloudwatch_event_rules
260
+ lambda_config['cloudwatch_event_rules'].each do |rule|
261
+ opt_hash = parse_hash(rule)
262
+ opts = rule.merge(opt_hash).symbolize_keys
263
+ title = "Add CloudWatch Event Rule"
264
+
265
+ verbose_msg_for(title, opts)
266
+ Lambit::Aws::CloudWatchEvents::Rule.new(opts).put_rule unless Lambit.is_dry_run?
267
+ end if lambda_config['cloudwatch_event_rules']
268
+ end
269
+
270
+ def add_cloudwatch_event_targets
271
+ lambda_config['cloudwatch_event_targets'].each_with_index do |targets, index|
272
+ @index = index
273
+ opt_hash = parse_hash(targets)
274
+ opts = opt_hash.symbolize_keys_deep
275
+ title = "Add CloudWatch Event Targets"
276
+
277
+ verbose_msg_for(title, opts)
278
+ Lambit::Aws::CloudWatchEvents::Rule.new(opts).put_targets unless Lambit.is_dry_run?
279
+ end if lambda_config['cloudwatch_event_targets']
280
+ end
281
+
282
+ def process
283
+ super
284
+ # Add Lambda Permissions
285
+ graceful_continue { add_lambda_permissions }
286
+
287
+ # Add S3 Bucket Notification Configurations
288
+ graceful_continue { add_s3_bucket_notification_configurations }
289
+
290
+ # Put CloudWatch Event Rules
291
+ graceful_continue { put_cloudwatch_event_rules }
292
+
293
+ # Add CloudWatch Event Targets
294
+ graceful_continue { add_cloudwatch_event_targets }
295
+ end
296
+ end
297
+
298
+ register_handler_for :add_event_sources_lambdas
299
+
300
+ class RemoveEventSourcesLambdas < Lambdas
301
+ def remove_lambda_permissions
302
+ lambda_config['lambda_permissions'].each_with_index do |permission, index|
303
+ @index = index
304
+ opt_hash = parse_hash(permission)
305
+ opts = opt_hash.symbolize_keys
306
+ title = "Remove Lambda Permissions"
307
+
308
+ verbose_msg_for(title, opts)
309
+ Lambit::Aws::Lambda::Permission.new(opts).remove unless Lambit.is_dry_run?
310
+ end if lambda_config['lambda_permissions']
311
+ end
312
+
313
+ def remove_s3_bucket_notification_configurations
314
+ lambda_config['s3_bucket_notification_configurations'].each_with_index do |configuration, index|
315
+ @index = index
316
+ opt_hash = parse_hash(configuration)
317
+ opts = opt_hash.symbolize_keys_deep
318
+ title = "Remove S3 Bucket Configurations"
319
+
320
+ verbose_msg_for(title, opts)
321
+ Lambit::Aws::S3::BucketNotificationConfiguration.new(opts).remove unless Lambit.is_dry_run?
322
+ end if lambda_config['s3_bucket_notification_configurations']
323
+ end
324
+
325
+ def remove_cloudwatch_event_targets
326
+ lambda_config['cloudwatch_event_targets'].each_with_index do |targets, index|
327
+ @index = index
328
+ opt_hash = parse_hash(targets)
329
+ opts = opt_hash.symbolize_keys_deep
330
+ title = "Remove CloudWatch Event Targets"
331
+
332
+ verbose_msg_for(title, opts)
333
+ Lambit::Aws::CloudWatchEvents::Rule.new(opts).remove_targets unless Lambit.is_dry_run?
334
+ end if lambda_config['cloudwatch_event_targets']
335
+ end
336
+
337
+ def remove_cloudwatch_event_rules
338
+ lambda_config['cloudwatch_event_rules'].each do |rule|
339
+ @index = index
340
+ opt_hash = parse_hash(rule)
341
+ opts = opt_hash.symbolize_keys
342
+ title = "Remove CloudWatch Event Rules"
343
+
344
+ verbose_msg_for(title, opts)
345
+ Lambit::Aws::CloudWatchEvents::Rule.new(opts).delete_rule unless Lambit.is_dry_run?
346
+ end if lambda_config['cloudwatch_event_rules']
347
+ end
348
+
349
+ def process
350
+ super
351
+ # Remove Lambda Permissions
352
+ graceful_continue { remove_lambda_permissions }
353
+
354
+ # Remove S3 Bucket Notification Configurations
355
+ graceful_continue { remove_s3_bucket_notification_configurations }
356
+
357
+ # Remove CloudWatch Event Targets
358
+ graceful_continue { remove_cloudwatch_event_targets }
359
+
360
+ # Remove CloudWatch Event Rules
361
+ graceful_continue { remove_cloudwatch_event_rules }
362
+ end
363
+ end
364
+
365
+ register_handler_for :remove_event_sources_lambdas
366
+
367
+ class AddAlarmsLambdas < Lambdas
368
+ def add_alarms
369
+ lambda_config['cloudwatch_alarms'].each_with_index do |alarm_config, index|
370
+ @index = index
371
+ opt_hash = parse_hash(alarm_config)
372
+ opts = opt_hash.symbolize_keys_deep
373
+ title = "Remove CloudWatch Alarms"
374
+
375
+ verbose_msg_for(title, opts)
376
+ Lambit::Aws::CloudWatch::Alarm.new(opts).put_metric_alarm unless Lambit.is_dry_run?
377
+ end
378
+ end
379
+
380
+ def process
381
+ super
382
+ graceful_continue { add_alarms }
383
+ end
384
+ end
385
+
386
+ register_handler_for :add_alarms_lambdas
387
+
388
+ class DeleteAlarmsLambdas < Lambdas
389
+ def delete_alarms
390
+ alarm_names = []
391
+
392
+ lambda_config['cloudwatch_alarms'].each_with_index do |alarm_config, index|
393
+ alarm_hash = parse_hash(alarm_config)
394
+ alarm_names << alarm_hash['alarm_name']
395
+ end
396
+
397
+ opts = {:alarm_names => alarm_names}
398
+ title = "Delete CloudWatch Alarms"
399
+ verbose_msg_for(title, opts)
400
+ Lambit::Aws::CloudWatch::Alarm.new(opts).delete_alarms unless Lambit.is_dry_run?
401
+ end
402
+
403
+ def process
404
+ super
405
+ graceful_continue { delete_alarms }
406
+ end
407
+ end
408
+
409
+ register_handler_for :delete_alarms_lambdas
410
+ end
411
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: UTF-8
2
+
3
+ using Lambit::Common::StringHelper
4
+
5
+ module Lambit::Commands
6
+ module Subcommands
7
+ def self.run(cmd, opts, args)
8
+ handler = handler_for cmd
9
+ output, exitstatus = handler.run opts, args
10
+
11
+ # Send Subcommand output to STDOUT if :debug
12
+ if Lambit.is_debug?
13
+ puts output unless output.nil? || output.empty?
14
+ end
15
+
16
+ # Return exit status
17
+ exitstatus
18
+ end
19
+
20
+ def self.normalize_cmd(cmd)
21
+ cmd.to_s.downcase
22
+ end
23
+
24
+ def self.handler_for(cmd)
25
+ if @handlers
26
+ @handlers[normalize_cmd(cmd)]
27
+ else
28
+ raise 'Uh Oh!'
29
+ end
30
+ end
31
+
32
+ def self.register_handler_for(cmd, handler=nil)
33
+ normalized_cmd = normalize_cmd(cmd)
34
+ handler = self.const_get(normalized_cmd.classify) if handler.nil?
35
+
36
+ @handlers ||= {}
37
+ @handlers[normalized_cmd] = handler
38
+ end
39
+
40
+ class Base
41
+ attr_reader :subcommand
42
+ attr_reader :dry_run
43
+ attr_reader :exitstatus
44
+
45
+ def initialize(opts, args)
46
+ @dry_run = opts['dry-run']
47
+ @exitstatus = 1
48
+ end
49
+
50
+ def self.run(opts, args)
51
+ output, exitstatus = self.new(opts, args).run
52
+ return output, exitstatus
53
+ end
54
+
55
+ def subcommand
56
+ @subcommand = nil
57
+ end
58
+
59
+ def output(stdout)
60
+ stdout
61
+ end
62
+
63
+ def run
64
+ raise "subcommand can't be nil" if subcommand.nil?
65
+
66
+ if dry_run
67
+ stdout = "DRY RUN: Subcommand => #{subcommand}"
68
+ @exitstatus = 0
69
+ else
70
+ # puts "Running: Subcommand => #{subcommand}"
71
+ stdout = `#{subcommand}`
72
+ @exitstatus = $?.exitstatus
73
+ end
74
+
75
+ return output(stdout), self.exitstatus
76
+ end
77
+
78
+ def successful?
79
+ self.exitstatus == 0
80
+ end
81
+
82
+ def is_successful?(status)
83
+ status == 0
84
+ end
85
+ end
86
+ end
87
+ end