kybus-cli 0.1.0

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