lambit 0.0.1

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,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