eleventh 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/eleventh +87 -0
  3. data/lib/eleventh.rb +151 -0
  4. metadata +103 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0372a28de281ad13d900d9655e3e1da0f21ae7a5
4
+ data.tar.gz: e105edd9947b1f4cd60df988fe98a23bb40adaf7
5
+ SHA512:
6
+ metadata.gz: acfd47ad4b59403f6aeacf62bb10852c5a9aad340c5c177e62a89ab628b9ccc6e94b2f36c53a97525865a8fa1f90abe5994eee3f3ca2b9d0dd924cfa3fb2db01
7
+ data.tar.gz: 2365d17939d494d10f8d25b2d333831e0270a73d392cd59e275f53c77a35a710a413db46a8e1a6e9d26477b30d4c6faa35581dcb1297a988f0fbe7eb54e5f567
data/bin/eleventh ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'commander/import'
5
+ require 'aws-sdk'
6
+
7
+ $:.push File.expand_path("../lib", __FILE__)
8
+ require 'eleventh'
9
+
10
+ program :version, Eleventh::VERSION
11
+ program :description, 'Synchronize locally developed Lambda functions to AWS Lambda'
12
+
13
+ program :help, 'Author', 'Michael Wood <mike@attendease.com>'
14
+ program :help, 'Website', 'https://attendease.com'
15
+ program :help_formatter, :compact
16
+
17
+ command :init do |c|
18
+ c.syntax = 'eleventh init <project> [options]'
19
+ c.description = 'Initializes a project of Lambda functions for syncing'
20
+ c.option '--project NAME', String, 'Project name'
21
+ c.option '--region REGION', String, 'AWS Region'
22
+ c.option '--profile_name YOUR_AWS_CLI_PROFILE', String, 'AWS CLI Profile'
23
+ c.option '--dest DIR', String, 'Destination directory'
24
+ c.action do |args, options|
25
+ profile_name = options.profile_name || 'default'
26
+
27
+ credentials = Aws::SharedCredentials.new(:profile_name => profile_name)
28
+
29
+ if credentials.loadable?
30
+ options.default \
31
+ :region => 'us-west-2'
32
+
33
+ project = args.first || options.project
34
+
35
+ unless project || options.region
36
+ say_error "Must specify --project NAME --region REGION --profile_name YOUR_AWS_CLI_PROFILE"
37
+ abort
38
+ end
39
+
40
+ if options.dest
41
+ initPath = File.expand_path(File.join(options.dest, project))
42
+ else
43
+ initPath = File.expand_path(File.join(Dir.pwd, project))
44
+ end
45
+
46
+ say "Amazing Web Services Config:"
47
+ say " AWS Region: #{options.region}"
48
+ say " AWS CLI Profile: #{profile_name}"
49
+ say " AWS Access Key ID: #{credentials.credentials.access_key_id}"
50
+ say " AWS Secret Access Key: #{credentials.credentials.secret_access_key}"
51
+
52
+ print "Initialize project to #{initPath}? [Y/n]: "
53
+ confirm = $stdin.gets.chomp
54
+
55
+ abort("Whoa, that was close!") if confirm.downcase == 'n'
56
+
57
+ say "Cool. Initializing project to #{initPath}..."
58
+
59
+ result = Eleventh.init_project(initPath, options.region, profile_name)
60
+
61
+ if result[:success]
62
+ say "Done."
63
+ else
64
+ say_error result[:message]
65
+ abort
66
+ end
67
+ else
68
+ say_error "You must set up your AWS CLI profile before proceeding."
69
+ abort
70
+ end
71
+ end
72
+ end
73
+
74
+ command :sync do |c|
75
+ c.syntax = 'eleventh sync [options]'
76
+ c.description = 'Synchronizes the local Lambda functions with AWS'
77
+ c.action do |args, options|
78
+ result = Eleventh.sync
79
+
80
+ if result[:success]
81
+ say "Done."
82
+ else
83
+ say_error result[:message]
84
+ abort
85
+ end
86
+ end
87
+ end
data/lib/eleventh.rb ADDED
@@ -0,0 +1,151 @@
1
+ require 'aws-sdk'
2
+ require 'json'
3
+ require 'zip'
4
+ require 'fileutils'
5
+ require 'base64'
6
+ require 'open-uri'
7
+
8
+ module Eleventh
9
+ VERSION = '0.0.0'
10
+
11
+ def self.init_project(initPath, region, profile_name)
12
+
13
+ unless File.exists?(initPath)
14
+ FileUtils.mkdir_p initPath
15
+ FileUtils.mkdir_p "#{initPath}/builds"
16
+
17
+ config = {
18
+ 'AWS' => {
19
+ 'Region' => region,
20
+ 'CredentialsProfile' => profile_name
21
+ }
22
+ }
23
+
24
+ File.open("#{initPath}/eleventh.json", "w+") { |file| file.write(JSON.pretty_generate config, :indent => ' ') }
25
+
26
+ lambda = Aws::Lambda::Client.new(
27
+ region: region,
28
+ credentials: Aws::SharedCredentials.new(:profile_name => profile_name)
29
+ )
30
+
31
+ lambda.list_functions.functions.each do |function|
32
+ self.init_function(initPath, lambda, function)
33
+ end
34
+
35
+ {:success => true}
36
+ else
37
+ {:success => false, :message => "Argh! Can't initialize the project there because something already exists." }
38
+ end
39
+ end
40
+
41
+ def self.init_function(initPath, lambda, function)
42
+ function_name = function.function_name
43
+
44
+ FileUtils.mkdir_p "#{initPath}/functions/#{function_name}"
45
+
46
+ config = {
47
+ "FunctionName" => function_name,
48
+ "MemorySize" => function.memory_size,
49
+ "Handler" => function.handler,
50
+ "Role" => function.role,
51
+ "Timeout" => function.timeout,
52
+ "Runtime" => function.runtime,
53
+ "Description" => function.description
54
+ }
55
+
56
+ File.open("#{initPath}/functions/#{function_name}/lambda.json", "w+") { |file| file.write(JSON.pretty_generate config, :indent => ' ') }
57
+
58
+ File.open("#{initPath}/builds/#{function.function_name}.zip", "wb") do |saved_file|
59
+ function_code = lambda.get_function(:function_name => function.function_name).code
60
+
61
+ open(function_code.location, "rb") do |read_file|
62
+ saved_file.write(read_file.read)
63
+ end
64
+ end
65
+
66
+ Zip::File.open("#{initPath}/builds/#{function_name}.zip") do |zip_file|
67
+ zip_file.each do |entry|
68
+ entry.extract("#{initPath}/functions/#{function_name}/#{entry.name}")
69
+ end
70
+ end
71
+ end
72
+
73
+ def self.sync
74
+ if File.exists?('./eleventh.json')
75
+ config = JSON.parse(File.read('./eleventh.json'))
76
+
77
+ lambda = Aws::Lambda::Client.new(
78
+ region: config['AWS']['Region'],
79
+ credentials: Aws::SharedCredentials.new(:profile_name => config['AWS']['CredentialsProfile'])
80
+ )
81
+
82
+ begin
83
+ function_names = lambda.list_functions.functions.map{|f| f.function_name}
84
+
85
+ # Remove old builds
86
+ Dir.foreach('./builds') do |f|
87
+ if ['.', '..'].include? f then next
88
+ elsif File.directory?("./builds/#{f}") then FileUtils.rm_rf("./builds/#{f}")
89
+ else FileUtils.rm("./builds/#{f}")
90
+ end
91
+ end
92
+
93
+ local_functions = []
94
+
95
+ Dir.foreach('./functions') do |f|
96
+ if ['.', '..'].include? f then next
97
+ else local_functions << f
98
+ end
99
+ end
100
+
101
+ local_functions.each do |function_name|
102
+ if File.exists?("./functions/#{function_name}/lambda.json")
103
+ function_config = JSON.parse(File.read("./functions/#{function_name}/lambda.json"))
104
+
105
+ Zip::File.open("./builds/#{function_name}.zip", Zip::File::CREATE) do |zipfile|
106
+ zipfile.add('index.js', "./functions/#{function_name}/index.js")
107
+ end
108
+
109
+ if function_names.include? function_name
110
+ resp = lambda.update_function_configuration({
111
+ function_name: function_name,
112
+ role: function_config['Role'],
113
+ handler: function_config['Handler'],
114
+ description: function_config['Description'],
115
+ timeout: function_config['Timeout'],
116
+ memory_size: function_config['MemorySize']
117
+ })
118
+
119
+ resp = lambda.update_function_code({
120
+ function_name: function_name,
121
+ zip_file: File.read("./builds/#{function_name}.zip")
122
+ })
123
+ else
124
+ resp = lambda.create_function({
125
+ function_name: function_name,
126
+ runtime: function_config['Runtime'],
127
+ role: function_config['Role'],
128
+ handler: function_config['Handler'],
129
+ description: function_config['Description'],
130
+ timeout: function_config['Timeout'],
131
+ memory_size: function_config['MemorySize'],
132
+ code: {
133
+ zip_file: File.read("./builds/#{function_name}.zip")
134
+ },
135
+ })
136
+ end
137
+
138
+ puts "Synced #{function_name} (#{resp.function_arn})"
139
+ end
140
+ end
141
+
142
+ {:success => true}
143
+ rescue Aws::Lambda::Errors::ServiceError => e
144
+ puts e.message
145
+ {:success => false, :message => "Oh no! Something went wrong."}
146
+ end
147
+ else
148
+ {:success => false, :message => "Darn! No eleventh.json config file."}
149
+ end
150
+ end
151
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eleventh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Michael Wood
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubyzip
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aws-sdk
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.1'
69
+ description: This gem will synchronize locally developed Lambda functions to Amazon
70
+ Web Services Lambda.
71
+ email: support@attendease.com
72
+ executables:
73
+ - eleventh
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - bin/eleventh
78
+ - lib/eleventh.rb
79
+ homepage: https://attendease.com
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.2.3
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Synchronize locally developed Lambda functions to AWS Lambda.
103
+ test_files: []