lambda-version-manager 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/lambda-version-manager +83 -0
- data/lib/client.rb +12 -0
- data/lib/deployer.rb +86 -0
- data/lib/project.rb +67 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 65c1fc87ac3d5d62b4cbc7fdcd68100c73110ebd
|
4
|
+
data.tar.gz: d6e4ac2ad9dbb56c3d23f1fd2886aeafd103f8fd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f7da2339574a59efb3c099145130db05fab72691120211f93c210a6f1f39123c8d3172458393347933c2131c8f46888a0a68ac2b614bc2af47ddfa21f2ee920
|
7
|
+
data.tar.gz: b8e3b5d321133d329f9a05b8c4ee65ac9fc70705808e5b455e43621021dfa5ee184bbc1b73c0ee4a3d1c82983ed052aa53a95f0d5c082555fa8d11ec0d015115
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
require 'thor'
|
4
|
+
require 'yaml'
|
5
|
+
require 'pp'
|
6
|
+
require_relative '../lib/project'
|
7
|
+
require_relative '../lib/deployer'
|
8
|
+
class GeneratorCLI < ::Thor
|
9
|
+
|
10
|
+
desc 'deploy', 'Deploy the updated lambda versions'
|
11
|
+
option 'project_path', banner: 'PROJECT_PATH', type: :string, desc: 'Path to the lambda version mappings project'
|
12
|
+
option 'environments', banner: 'ENVIRONMENT', type: :array, desc: 'Deploy lambdas in this environment'
|
13
|
+
option 'artifact', banner: 'ARTIFACT', type: :string, desc: 'Deploy lambdas that use this artifact'
|
14
|
+
option 'lambda', banner: 'LAMBDA', type: :string, desc: 'Deploy lambdas with this name'
|
15
|
+
option 'account', banner: 'ACCOUNT', type: :string, desc: 'Account to deploy to', :required => true
|
16
|
+
option 'version_map_file', banner: 'VERSION_MAP_FILE', type: :string, desc: 'A java properties file mapping artifacts to update to version'
|
17
|
+
|
18
|
+
def deploy
|
19
|
+
opts = parse_options(options)
|
20
|
+
if opts['version_map_file']
|
21
|
+
#for each x=y pair we need to call
|
22
|
+
File.readlines(options['version_map_file']).each do |line|
|
23
|
+
array = line.split("=")
|
24
|
+
deployer = Deployer.new(opts['project_path'], opts['account'], array[0].strip)
|
25
|
+
deployer.deploy(opts['environments'])
|
26
|
+
end
|
27
|
+
else
|
28
|
+
deployer = Deployer.new(opts['project_path'], opts['account'], opts['artifact'], opts['lambda'])
|
29
|
+
deployer.deploy(opts['environments'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'update_project', 'Update the versions'
|
34
|
+
option 'project_path', banner: 'PROJECT_PATH', type: :string, desc: 'Path to the lambda version mappings project'
|
35
|
+
option 'artifact', banner: 'ARTIFACT', type: :string, desc: 'Deploy lambdas that use this artifact'
|
36
|
+
option 'version', banner: 'VERSION', type: :string, desc: 'Version of the new artifact'
|
37
|
+
option 'version_map_file', banner: 'VERSION_MAP_FILE', type: :string, desc: 'A java properties file mapping artifacts to update to version'
|
38
|
+
option 'accounts', banner: 'ACCOUNT', type: :array, desc: 'Account to deploy to', :required => true
|
39
|
+
|
40
|
+
def update_project
|
41
|
+
opts = parse_options(options)
|
42
|
+
project = Project.new(opts['project_path'])
|
43
|
+
lambda_env_map = project.get_lambdas
|
44
|
+
account_env_map = project.account_env_map
|
45
|
+
|
46
|
+
supportd_envs = []
|
47
|
+
opts['accounts'].each do | account|
|
48
|
+
supportd_envs += account_env_map[account]
|
49
|
+
end
|
50
|
+
|
51
|
+
lambda_env_map.each do |env, lamdas|
|
52
|
+
unless supportd_envs.include?(env)
|
53
|
+
lambda_env_map.delete(env)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
if opts['version_map_file']
|
59
|
+
#for each artifact=version pair we need to call
|
60
|
+
File.readlines(opts['version_map_file']).each do |line|
|
61
|
+
array = line.split("=")
|
62
|
+
updated_files = project.update_by_artifact(lambda_env_map, array[0].strip, array[1].strip)
|
63
|
+
lambda_env_map = updated_files
|
64
|
+
end
|
65
|
+
else
|
66
|
+
lambda_env_map = project.update_by_artifact(lambda_env_map, opts['artifact'], opts['version'])
|
67
|
+
end
|
68
|
+
project.write_new_files(lambda_env_map)
|
69
|
+
end
|
70
|
+
|
71
|
+
no_commands do
|
72
|
+
def parse_options(options)
|
73
|
+
unless options['version_map_file'] || (options['version'] && (options['lambda'] || options['artifact']))
|
74
|
+
raise 'Either a file must be specified or a version and lambda or artifact.'
|
75
|
+
end
|
76
|
+
#add input validation, either a file must be specified or a version and lambda or artifact.
|
77
|
+
opts = options.dup
|
78
|
+
opts
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
GeneratorCLI.start(ARGV)
|
data/lib/client.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'aws-sdk-lambda'
|
2
|
+
class Client
|
3
|
+
attr_accessor :client
|
4
|
+
def initialize(aws_region)
|
5
|
+
@client = Aws::Lambda::Client.new(region: aws_region)
|
6
|
+
end
|
7
|
+
|
8
|
+
def update_function_code(function_name, s3_bucket, s3_key)
|
9
|
+
response = client.update_function_code({function_name: function_name, s3_bucket: s3_bucket, s3_key: s3_key})
|
10
|
+
puts "Updated: #{response.function_name}"
|
11
|
+
end
|
12
|
+
end
|
data/lib/deployer.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative 'client'
|
2
|
+
require_relative 'project'
|
3
|
+
class Deployer
|
4
|
+
attr_accessor :project_path
|
5
|
+
attr_accessor :account
|
6
|
+
attr_accessor :config
|
7
|
+
attr_accessor :project
|
8
|
+
attr_accessor :lambda
|
9
|
+
attr_accessor :artifact
|
10
|
+
|
11
|
+
def initialize(project_path, account, artifact, lambda)
|
12
|
+
@project_path = project_path
|
13
|
+
@account = account
|
14
|
+
@project = Project.new("#{project_path}")
|
15
|
+
@config = set_config
|
16
|
+
@artifact = artifact
|
17
|
+
@lambda = lambda
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_config
|
21
|
+
@project.config
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_deployable_lambdas(lambda_env_map)
|
25
|
+
|
26
|
+
if artifact
|
27
|
+
lambda_env_map.each do |env, lambdas|
|
28
|
+
lambdas.each do |lambda_name, properties|
|
29
|
+
lambdas.delete(lambda_name) unless properties['artifact_name'] == artifact
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if lambda
|
35
|
+
lambda_env_map.each do |env, lambdas|
|
36
|
+
lambdas.each do |lambda_name, properties|
|
37
|
+
lambdas.delete(lambda_name) unless lambda_name == lambda
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
lambda_env_map
|
42
|
+
end
|
43
|
+
|
44
|
+
def deploy(environments)
|
45
|
+
account_env_map = project.account_env_map[account]
|
46
|
+
env_region_map = project.env_region_map
|
47
|
+
#Filter by account as the primary owner of envs
|
48
|
+
lambda_env_map = project.get_lambdas
|
49
|
+
lambda_env_map = get_deployable_lambdas(lambda_env_map)
|
50
|
+
account_env_map.each do |env|
|
51
|
+
#IF users has specified environments, skip if the environment is not a user specified one
|
52
|
+
next if !environments.nil? && environments.include?(env)
|
53
|
+
lambda_env_map[env].each do |lambda_name, properties|
|
54
|
+
client = Client.new(env_region_map[env])
|
55
|
+
|
56
|
+
s3_bucket = get_s3_bucket(properties, env)
|
57
|
+
s3_key = construct_s3_key(properties, env)
|
58
|
+
|
59
|
+
puts "ENV: #{env}"
|
60
|
+
puts "Lambda Name: #{lambda_name}"
|
61
|
+
puts "S3 Bucket: #{s3_bucket}"
|
62
|
+
puts "S3 Key: #{s3_key}"
|
63
|
+
#client.update_function_code(lambda_name,s3_bucket,s3_key)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def get_s3_bucket(properties, env)
|
70
|
+
if properties['s3_bucket']
|
71
|
+
return properties['s3_bucket']
|
72
|
+
else
|
73
|
+
return config['environments'][env]['s3_bucket']
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
def construct_s3_key(properties, env)
|
79
|
+
if properties['s3_key']
|
80
|
+
return properties['s3_key']
|
81
|
+
else
|
82
|
+
return "#{config['environments'][env]['base_path']}/#{properties['artifact_name']}#{properties['artifact_name']}-#{properties['version']}.#{properties['extension']}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
data/lib/project.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class Project
|
2
|
+
attr_accessor :config
|
3
|
+
attr_accessor :project_path
|
4
|
+
|
5
|
+
def initialize(project_path)
|
6
|
+
@config = YAML.load_file("#{project_path}/config/config.yaml")
|
7
|
+
@project_path = project_path
|
8
|
+
end
|
9
|
+
|
10
|
+
def environments
|
11
|
+
config['environments']
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_lambdas
|
15
|
+
lambdas = {}
|
16
|
+
environments.keys.each do |env|
|
17
|
+
lambdas[env] = YAML.load_file("#{project_path}/environments/#{env}.yaml")
|
18
|
+
end
|
19
|
+
lambdas
|
20
|
+
end
|
21
|
+
|
22
|
+
def account_env_map
|
23
|
+
hash = {}
|
24
|
+
config['environments'].each do |env, properties|
|
25
|
+
if hash[properties['account']].nil?
|
26
|
+
hash[properties['account']] = []
|
27
|
+
hash[properties['account']] << env
|
28
|
+
else
|
29
|
+
hash[properties['account']] << env
|
30
|
+
end
|
31
|
+
end
|
32
|
+
hash
|
33
|
+
end
|
34
|
+
|
35
|
+
def env_region_map
|
36
|
+
hash = {}
|
37
|
+
config['environments'].each do |env, properties|
|
38
|
+
if hash[env].nil?
|
39
|
+
hash[env] = properties['region']
|
40
|
+
else
|
41
|
+
raise("An environment cannot map to more than one region ENV: #{env} Region: #{properties['region']}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
hash
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def write_new_files(lambda_env_map)
|
49
|
+
lambda_env_map.each do |env, contents|
|
50
|
+
File.write("#{project_path}/environments/#{env}.yaml", contents.to_yaml)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_by_artifact(lambda_env_map, artifact, version)
|
55
|
+
#iterate through all lambdas and update the ones with version changes
|
56
|
+
lambda_env_map.each do |env, lambda|
|
57
|
+
pp env
|
58
|
+
pp lambda
|
59
|
+
lambda.each do |lambda_name, properties|
|
60
|
+
if properties['artifact_name'] == artifact
|
61
|
+
properties['version'] = version
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
lambda_env_map
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lambda-version-manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bryan Call
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-02-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.0.rc2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.0.rc2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor-scmversion
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Updates aws lambda versions to match a yaml property file
|
56
|
+
email: bcall@rapid7.com
|
57
|
+
executables:
|
58
|
+
- lambda-version-manager
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/lambda-version-manager
|
63
|
+
- lib/client.rb
|
64
|
+
- lib/deployer.rb
|
65
|
+
- lib/project.rb
|
66
|
+
homepage: http://rubygems.org/gems/lambda-version-manager
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 2.6.12
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Lambda version manager
|
90
|
+
test_files: []
|