kybus-cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/bin/kybus +6 -0
  3. data/lib/kybus/aws/code_packager.rb +47 -0
  4. data/lib/kybus/aws/lambda.rb +166 -0
  5. data/lib/kybus/aws/log_group.rb +34 -0
  6. data/lib/kybus/aws/policy.rb +34 -0
  7. data/lib/kybus/aws/resource.rb +33 -0
  8. data/lib/kybus/aws/role.rb +76 -0
  9. data/lib/kybus/aws.rb +8 -0
  10. data/lib/kybus/cli/bot/controller_generator.rb +38 -0
  11. data/lib/kybus/cli/bot/deploy_init_generator.rb +33 -0
  12. data/lib/kybus/cli/bot/deployer.rb +70 -0
  13. data/lib/kybus/cli/bot/deployers/aws_bot_deployer.rb +95 -0
  14. data/lib/kybus/cli/bot/deployers/deployer_base.rb +23 -0
  15. data/lib/kybus/cli/bot/deployers/telegram_configurator.rb +33 -0
  16. data/lib/kybus/cli/bot/file_provider.rb +50 -0
  17. data/lib/kybus/cli/bot/file_providers/autoconfig_generator.rb +28 -0
  18. data/lib/kybus/cli/bot/file_providers/autoconfig_loader_generator.rb +37 -0
  19. data/lib/kybus/cli/bot/file_providers/bot_builder_generator.rb +25 -0
  20. data/lib/kybus/cli/bot/file_providers/bot_generator.rb +29 -0
  21. data/lib/kybus/cli/bot/file_providers/composefile_generator.rb +54 -0
  22. data/lib/kybus/cli/bot/file_providers/config_default_generator.rb +50 -0
  23. data/lib/kybus/cli/bot/file_providers/config_generator.rb +45 -0
  24. data/lib/kybus/cli/bot/file_providers/db_generator.rb +53 -0
  25. data/lib/kybus/cli/bot/file_providers/deployment_file_provider.rb +39 -0
  26. data/lib/kybus/cli/bot/file_providers/dockerfile_generator.rb +33 -0
  27. data/lib/kybus/cli/bot/file_providers/gemfile_generator.rb +41 -0
  28. data/lib/kybus/cli/bot/file_providers/lambda_handler_generator.rb +38 -0
  29. data/lib/kybus/cli/bot/file_providers/rakefile_generator.rb +40 -0
  30. data/lib/kybus/cli/bot/file_providers/test_helper_generator.rb +32 -0
  31. data/lib/kybus/cli/bot/project_generator.rb +76 -0
  32. data/lib/kybus/cli/bot.rb +60 -0
  33. data/lib/kybus/cli/file_writer.rb +17 -0
  34. data/lib/kybus/cli.rb +15 -0
  35. metadata +193 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2787f36a297b9c14e6c9fb0d4b28284721e4065c0c2a7c4f64db8246da1767fc
4
+ data.tar.gz: 619dcf54613ed6d18aecec46e84ae1b1fecad32c05882ec5e2b6d1d4ca4bc8aa
5
+ SHA512:
6
+ metadata.gz: 4e2cd597770a3f06ef11a3077752d35608f90883def9e89be0b78cc10c4256d1039fa5877dd38d217c1702fbe9b7b82d1026c3cf9a0d79ac90e41429b2b06ed9
7
+ data.tar.gz: f2fc53893eb88358018a1a3251c0b78d24120735d8ec9e09ce81ef26ab985768800bb9e83de51810b7b66f18931041a6d6eaf67a5cb4a0797ae31cdfdcfb6008
data/bin/kybus ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'kybus/cli'
5
+
6
+ Kybus::CLI.start(ARGV)
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ module AWS
5
+ class CodePackager < Resource
6
+ def create_or_update!
7
+ ruby_version = RUBY_VERSION.split('.')[0..1].join('.') + '.0'
8
+ create_zip('.deps.zip', "vendor/bundle/ruby/#{ruby_version}", zip_root: "ruby/gems/#{ruby_version}")
9
+ create_zip('.kybuscode.zip', @config['repo_path'], exclude_files: [
10
+ 'test', 'Gemfile*', 'Rakefile', '.gitignore', '.bundle', '.git', '.deps.zip', '.kybuscode.zip', 'kybusbot.yaml', 'vendor', '.ruby-version'
11
+ ], extra_files: { '.bundle/config' => 'BUNDLE_PATH: "/opt/vendor/bundle"' }, zip_root: '.')
12
+ end
13
+
14
+ def create_zip(zip_name, directory, exclude_files: [], extra_files: {}, zip_root: '')
15
+ require 'zip'
16
+ FileUtils.rm(zip_name, force: true)
17
+ entries = Dir.entries(directory) - %w[. ..]
18
+
19
+ Zip::File.open(zip_name, Zip::File::CREATE) do |zipfile|
20
+ extra_files.each do |entry, contents|
21
+ zipfile.get_output_stream(entry) { |f| f.puts(contents) }
22
+ end
23
+
24
+ entries.each do |entry|
25
+ entry_path = File.join(directory, entry)
26
+ next if exclude_files.any? { |pattern| File.fnmatch(pattern, entry) || File.fnmatch(pattern, entry_path) }
27
+
28
+ puts "Adding #{entry} to #{zip_name}"
29
+
30
+ if File.directory?(entry_path)
31
+ zipfile.mkdir("#{zip_root}#{entry_path.sub(directory, '')}")
32
+ Dir[File.join(entry_path, '**', '**')].each do |file|
33
+ next if exclude_files.any? { |pattern| File.fnmatch(pattern, file) }
34
+
35
+ zipfile.add("#{zip_root}#{file.sub(directory, '')}", file)
36
+ end
37
+ else
38
+ zipfile.add("#{zip_root}#{entry_path.sub(directory, '')}", entry_path)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def destroy!; end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+
5
+ def calculate_md5(file_path)
6
+ md5 = Digest::MD5.new
7
+ File.open(file_path, 'rb') do |file|
8
+ buffer = String.new
9
+ md5.update(buffer) while file.read(4096, buffer)
10
+ end
11
+ md5.hexdigest
12
+ end
13
+
14
+ module Kybus
15
+ module AWS
16
+ class Lambda < Resource
17
+ attr_reader :url, :name
18
+
19
+ def initialize(configs, name)
20
+ super(configs)
21
+ @name = name
22
+ end
23
+
24
+ def lambda_client
25
+ @lambda_client ||= Aws::Lambda::Client.new(region: @region)
26
+ end
27
+
28
+ def function_name
29
+ @name
30
+ end
31
+
32
+ def deploy_lambda!
33
+ layer_arn_deps = create_or_update_layer('.deps.zip', "#{function_name}-deps")
34
+
35
+ function_exists = begin
36
+ lambda_client.get_function(function_name:)
37
+ rescue StandardError
38
+ false
39
+ end
40
+
41
+ if function_exists
42
+ update_lambda!(layer_arn_deps)
43
+ else
44
+ create_lambda!(layer_arn_deps)
45
+ end
46
+ end
47
+
48
+ def create_layer(zip_file, layer_name, zipfile_hash)
49
+ response = lambda_client.publish_layer_version({
50
+ layer_name:,
51
+ content: {
52
+ zip_file: File.read(zip_file)
53
+ },
54
+ description: zipfile_hash,
55
+ compatible_runtimes: ["ruby3.3"]
56
+ })
57
+ puts "Layer '#{layer_name}' created: #{response.layer_version_arn}"
58
+ response.layer_version_arn
59
+ end
60
+
61
+ def create_or_update_layer(zip_file, layer_name)
62
+ layer_exists = begin
63
+ response = lambda_client.list_layer_versions({
64
+ layer_name: layer_name,
65
+ max_items: 1
66
+ })
67
+
68
+ response.layer_versions.first
69
+ end
70
+
71
+ zipfile_hash = calculate_md5('Gemfile.lock')
72
+
73
+ if !layer_exists || layer_exists.description != zipfile_hash
74
+ create_layer(zip_file, layer_name, zipfile_hash)
75
+ else
76
+ puts "Layer unmodified: #{layer_name}"
77
+ layer_exists.layer_version_arn
78
+ end
79
+ end
80
+
81
+ def update_lambda!(layer_arn_deps)
82
+ with_retries(Aws::Lambda::Errors::ResourceConflictException) do
83
+ lambda_client.update_function_configuration({
84
+ function_name:,
85
+ layers: [layer_arn_deps],
86
+ timeout: @config['timeout'] || 3,
87
+ environment: {
88
+ variables: {
89
+ 'SECRET_TOKEN' => @config['secret_token']
90
+ }
91
+ }
92
+ })
93
+ end
94
+
95
+ with_retries(Aws::Lambda::Errors::ResourceConflictException) do
96
+ lambda_client.update_function_code(function_name:, zip_file: File.read('.kybuscode.zip'))
97
+ end
98
+ puts "Lambda function '#{function_name}' updated."
99
+ end
100
+
101
+ def create_lambda!(layer_arn_deps)
102
+ with_retries(Aws::Lambda::Errors::ResourceConflictException) do
103
+ lambda_client.create_function({
104
+ function_name:,
105
+ runtime: 'ruby3.3',
106
+ role: "arn:aws:iam::#{account_id}:role/#{function_name}",
107
+ handler: 'handler.lambda_handler',
108
+ layers: [layer_arn_deps],
109
+ code: {
110
+ zip_file: File.read('.kybuscode.zip')
111
+ },
112
+ timeout: @config['timeout'] || 3,
113
+ environment: {
114
+ variables: {
115
+ 'SECRET_TOKEN' => @config['secret_token']
116
+ }
117
+ }
118
+ })
119
+ puts "Lambda function '#{function_name}' created."
120
+ end
121
+ end
122
+
123
+ def make_public!
124
+ with_retries(Aws::Lambda::Errors::ResourceConflictException) do
125
+ response = lambda_client.create_function_url_config({
126
+ function_name:,
127
+ auth_type: 'NONE'
128
+ })
129
+ puts "Function URL created: #{response.function_url}"
130
+ @url = response.function_url
131
+ rescue Aws::Lambda::Errors::ResourceConflictException
132
+ response = lambda_client.get_function_url_config({
133
+ function_name:
134
+ })
135
+ puts "Function URL exists: #{response.function_url}"
136
+ @url = response.function_url
137
+ end
138
+
139
+ begin
140
+ response = lambda_client.add_permission({
141
+ function_name:,
142
+ statement_id: 'AllowPublicInvoke',
143
+ action: 'lambda:InvokeFunctionUrl',
144
+ principal: '*',
145
+ function_url_auth_type: 'NONE'
146
+ })
147
+ puts "Permission added successfully: #{response}"
148
+ rescue Aws::Lambda::Errors::ServiceError => e
149
+ puts "Error adding permission: #{e.message}"
150
+ end
151
+ end
152
+
153
+ def create_or_update!
154
+ deploy_lambda!
155
+ make_public!
156
+ end
157
+
158
+ def destroy!
159
+ lambda_client.delete_function(function_name:)
160
+ puts "Lambda function '#{function_name}' deleted."
161
+ rescue Aws::Lambda::Errors::ResourceNotFoundException
162
+ puts "Lambda function '#{function_name}' not found."
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ module AWS
5
+ class LogGroup < Resource
6
+ def initialize(config, name)
7
+ super(config)
8
+ @name = name
9
+ end
10
+
11
+ def logs_client
12
+ @logs_client ||= Aws::CloudWatchLogs::Client.new(region: @region)
13
+ end
14
+
15
+ def log_group_name
16
+ "/aws/lambda/#{@name}"
17
+ end
18
+
19
+ def create_or_update!
20
+ logs_client.create_log_group(log_group_name:)
21
+ puts "Log group '#{log_group_name}' created."
22
+ rescue Aws::CloudWatchLogs::Errors::ResourceAlreadyExistsException
23
+ puts "Log group '#{log_group_name}' already exists."
24
+ end
25
+
26
+ def destroy!
27
+ logs_client.delete_log_group(log_group_name:)
28
+ puts "Log group '#{log_group_name}' deleted."
29
+ rescue Aws::CloudWatchLogs::Errors::ResourceNotFoundException
30
+ puts "Log group '#{log_group_name}' not found."
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ module AWS
5
+ class Policy < Resource
6
+ attr_reader :name
7
+
8
+ def initialize(config, name, body)
9
+ super(config)
10
+ @name = name
11
+ @body = body
12
+ @iam_client = Aws::IAM::Client.new
13
+ end
14
+
15
+ def arn
16
+ "arn:aws:iam::#{account_id}:policy/#{name}"
17
+ end
18
+
19
+ def create_or_update!
20
+ @iam_client.create_policy(policy_name: @name, policy_document: @body.to_json)
21
+ puts "Policy '#{@name}' created."
22
+ rescue Aws::IAM::Errors::EntityAlreadyExists
23
+ puts "Policy '#{@name}' already exists."
24
+ end
25
+
26
+ def destroy!
27
+ @iam_client.delete_policy(policy_arn: arn)
28
+ puts "Policy '#{@name}' deleted."
29
+ rescue Aws::IAM::Errors::NoSuchEntity
30
+ puts "Policy '#{@name}' not found."
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ module AWS
5
+ class Resource
6
+ def initialize(config)
7
+ @config = config
8
+ @region = @config['region'] || 'us-east-1'
9
+ end
10
+
11
+ def account_id
12
+ @config['account_id']
13
+ end
14
+
15
+ def with_retries(exception, max_retries = 5)
16
+ retry_count = 0
17
+ begin
18
+ yield
19
+ rescue exception
20
+ retry_count += 1
21
+ unless retry_count <= max_retries
22
+ raise "Failed to apply #{self.class} after #{max_retries} attempts due to ongoing updates."
23
+ end
24
+
25
+ sleep_time = 2**retry_count
26
+ puts "Update in progress, retrying in #{sleep_time} seconds..."
27
+ sleep(sleep_time)
28
+ retry
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ module AWS
5
+ class Role < Resource
6
+ LAMBDA_ASSUME_ROLE_POLICY = {
7
+ Version: '2012-10-17',
8
+ Statement: [
9
+ {
10
+ Effect: 'Allow',
11
+ Principal: {
12
+ Service: 'lambda.amazonaws.com'
13
+ },
14
+ Action: 'sts:AssumeRole'
15
+ }
16
+ ]
17
+ }.to_json.freeze
18
+
19
+ def initialize(config, name, type)
20
+ super(config)
21
+ @type = type
22
+ @name = name
23
+ @iam_client = Aws::IAM::Client.new
24
+ @policies = []
25
+ end
26
+
27
+ def add_policy(policy)
28
+ @policies << policy
29
+ end
30
+
31
+ def assume_role_policy
32
+ case @type
33
+ when :lambda
34
+ LAMBDA_ASSUME_ROLE_POLICY
35
+ else
36
+ raise 'Invalid Role Type'
37
+ end
38
+ end
39
+
40
+ def create_or_update!
41
+ begin
42
+ @iam_client.create_role({
43
+ role_name: @name,
44
+ assume_role_policy_document: assume_role_policy
45
+ })
46
+ puts "Role '#{@name}' created."
47
+ rescue Aws::IAM::Errors::EntityAlreadyExists
48
+ puts "Role '#{@name}' already exists."
49
+ end
50
+
51
+ @policies.each do |policy|
52
+ @iam_client.attach_role_policy(role_name: @name, policy_arn: policy.arn)
53
+ puts "Policy '#{policy.name}' attached to role '#{@name}'."
54
+ rescue Aws::IAM::Errors::EntityAlreadyExists
55
+ puts "Policy '#{policy.name}' already attached to role '#{@name}'."
56
+ end
57
+ end
58
+
59
+ def destroy!
60
+ @policies.each do |policy|
61
+ @iam_client.detach_role_policy({ role_name: @name, policy_arn: policy.arn })
62
+ puts "Policy '#{policy.name}' deleted."
63
+ rescue Aws::IAM::Errors::NoSuchEntity
64
+ puts "Policy '#{policy.name}' not found."
65
+ end
66
+
67
+ begin
68
+ @iam_client.delete_role(role_name: @name)
69
+ puts "Role '#{@name}' deleted."
70
+ rescue Aws::IAM::Errors::NoSuchEntity
71
+ puts "Role '#{@name}' not found."
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
data/lib/kybus/aws.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'aws/resource'
4
+ require_relative 'aws/code_packager'
5
+ require_relative 'aws/lambda'
6
+ require_relative 'aws/log_group'
7
+ require_relative 'aws/policy'
8
+ require_relative 'aws/role'
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ class CLI < Thor
5
+ class Bot < Thor
6
+ class ControllerGenerator
7
+ def initialize(name)
8
+ @name = name
9
+ @file_writer = Kybus::CLI::FileWriter.new('routes')
10
+ end
11
+
12
+ def generate
13
+ @file_writer.write("#{@name}_controller.rb", controller_content)
14
+ end
15
+
16
+ private
17
+
18
+ def controller_content
19
+ <<~RUBY
20
+ # frozen_string_literal: true
21
+
22
+ module #{@name.capitalize}Controller
23
+ def self.included(base)
24
+ base.instance_eval do
25
+ include Routes
26
+
27
+ def #{@name}_routes
28
+ # Define your routes here
29
+ end
30
+ end
31
+ end
32
+ end
33
+ RUBY
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ module CLI
5
+ module Bot
6
+ class DeployInitGenerator
7
+ def initialize(name, options)
8
+ @file_writer = Kybus::CLI::FileWriter.new(name)
9
+ @options = options
10
+ end
11
+
12
+ def generate
13
+ @file_writer.write('.kybusbot.yaml', config_yaml_content)
14
+ end
15
+
16
+ private
17
+
18
+ def config_yaml_content
19
+ <<~YAML
20
+ bot_name: #{bot_name_snake_case}
21
+ cloud_provider: #{@options[:cloud_provider] || 'aws'}
22
+ dynamo:
23
+ capacity: #{@options[:dynamo_capacity] || 'on_demand'}
24
+ table_name: #{@options[:dynamo_table] || 'bot_sessions'}
25
+ chat_provider: #{@options[:chat_provider] || 'telegram'}
26
+ telegram:
27
+ token: 'REPLACE_ME'
28
+ YAML
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'rake'
7
+ require 'securerandom'
8
+ require 'fileutils'
9
+ require 'yaml'
10
+ require 'aws-sdk-iam'
11
+ require 'aws-sdk-lambda'
12
+ require 'aws-sdk-cloudwatchlogs'
13
+ require 'zip'
14
+
15
+ require 'kybus/aws'
16
+ require_relative 'deployers/telegram_configurator'
17
+ require_relative 'deployers/aws_bot_deployer'
18
+
19
+ module Kybus
20
+ class CLI < Thor
21
+ class Deployer
22
+ DEFAULT_CONFIGS = {
23
+ 'repo_path' => '.',
24
+ 'output_path' => './.kybusbotcode.zip'
25
+ }.freeze
26
+
27
+ def initialize(options)
28
+ @params = options
29
+ load_kybusdeploy_file!
30
+ @telegram = ::Kybus::CLI::BotDeployerTelegramConfigurator.new(@url, config_with_options)
31
+ @lambda = ::Kybus::CLI::AWSBotDeployer.new(config_with_options)
32
+ end
33
+
34
+ def run_migrations!
35
+ Rake::Task.clear
36
+ load 'Rakefile'
37
+ Rake::Task['db:migrate'].invoke
38
+ end
39
+
40
+ def load_kybusdeploy_file!
41
+ @config = YAML.load_file('./kybusbot.yaml')
42
+ end
43
+
44
+ def config_with_options
45
+ @config_with_options ||= DEFAULT_CONFIGS.merge(@config.merge(@params))
46
+ end
47
+
48
+ def compress_repo!
49
+ code = ::Kybus::AWS::CodePackager.new(config_with_options)
50
+ code.create_or_update!
51
+ end
52
+
53
+ def deploy_lambda!
54
+ @lambda.create_or_update!
55
+ @telegram.url = @lambda.url
56
+ end
57
+
58
+ def run
59
+ compress_repo!
60
+ deploy_lambda!
61
+ @telegram.create_or_update!
62
+ end
63
+
64
+ def destroy
65
+ @lambda.destroy!
66
+ @telegram.destroy!
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ class CLI < Thor
5
+ class AWSBotDeployer < BotDeployerBase
6
+ def make_dynamo_policy_document
7
+ {
8
+ Version: '2012-10-17',
9
+ Statement: [
10
+ {
11
+ Effect: 'Allow',
12
+ Action: [
13
+ 'dynamodb:BatchGetItem',
14
+ 'dynamodb:BatchWriteItem',
15
+ 'dynamodb:Describe*',
16
+ 'dynamodb:Get*',
17
+ 'dynamodb:List*',
18
+ 'dynamodb:PutItem',
19
+ 'dynamodb:Query',
20
+ 'dynamodb:Scan',
21
+ 'dynamodb:UpdateItem',
22
+ 'dynamodb:DeleteItem'
23
+ ],
24
+ Resource: "arn:aws:dynamodb:#{@region}:#{account_id}:table/#{function_name}*"
25
+ }, {
26
+ Effect: :Allow,
27
+ Action: [
28
+ 'dynamodb:Describe*',
29
+ 'dynamodb:Get*',
30
+ 'dynamodb:List*'
31
+ ],
32
+ Resource: '*'
33
+ }
34
+ ]
35
+ }
36
+ end
37
+
38
+ def make_log_groupo_policy_document
39
+ {
40
+ Version: '2012-10-17',
41
+ Statement: [
42
+ {
43
+ Effect: 'Allow',
44
+ Action: 'logs:CreateLogGroup',
45
+ Resource: "arn:aws:logs:#{@region}:#{account_id}:*"
46
+ },
47
+ {
48
+ Effect: 'Allow',
49
+ Action: [
50
+ 'logs:CreateLogStream',
51
+ 'logs:PutLogEvents'
52
+ ],
53
+ Resource: [
54
+ "arn:aws:logs:#{@region}:#{account_id}:log-group:/aws/lambda/#{function_name}:*"
55
+ ]
56
+ }
57
+ ]
58
+ }
59
+ end
60
+
61
+ def initialize(configs)
62
+ configs['account_id'] = account_id
63
+ super
64
+ @role = ::Kybus::AWS::Role.new(configs, function_name, :lambda)
65
+ @dynamo_policy = ::Kybus::AWS::Policy.new(configs, "#{function_name}-dynamo", make_dynamo_policy_document)
66
+ @cloudwatch_policy = ::Kybus::AWS::Policy.new(configs, "#{function_name}-cloudwatch",
67
+ make_log_groupo_policy_document)
68
+ @role.add_policy(@dynamo_policy)
69
+ @role.add_policy(@cloudwatch_policy)
70
+ @log_group = ::Kybus::AWS::LogGroup.new(configs, function_name)
71
+ @lambda = ::Kybus::AWS::Lambda.new(configs, function_name)
72
+ end
73
+
74
+ def destroy!
75
+ @lambda.destroy!
76
+ @role.destroy!
77
+ @dynamo_policy.destroy!
78
+ @cloudwatch_policy.destroy!
79
+ @log_group.destroy!
80
+ end
81
+
82
+ def url
83
+ @lambda.url
84
+ end
85
+
86
+ def create_or_update!
87
+ @log_group.create_or_update!
88
+ @dynamo_policy.create_or_update!
89
+ @cloudwatch_policy.create_or_update!
90
+ @role.create_or_update!
91
+ @lambda.create_or_update!
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ class CLI < Thor
5
+ class BotDeployerBase
6
+ def initialize(configs)
7
+ @config = configs
8
+ end
9
+
10
+ def function_name
11
+ "#{@config[:env] || 'production'}-#{@config['name']}"
12
+ end
13
+
14
+ def account_id
15
+ @account_id ||= begin
16
+ sts_client = Aws::STS::Client.new
17
+ response = sts_client.get_caller_identity
18
+ response.account
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end