lambda-version-manager 0.0.3
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.
- 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: []
|