kybus-cli 0.1.0 → 0.2.2

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.
@@ -2,73 +2,13 @@
2
2
 
3
3
  module Kybus
4
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
-
5
+ class AWSBotDeployer < BotDeployerBase # rubocop: disable Metrics/ClassLength
61
6
  def initialize(configs)
62
7
  configs['account_id'] = account_id
63
8
  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)
9
+ @region = @config['region'] || 'us-east-1'
10
+ initialize_aws_resources(configs)
11
+ assign_policies_to_role
72
12
  end
73
13
 
74
14
  def destroy!
@@ -87,9 +27,115 @@ module Kybus
87
27
  @log_group.create_or_update!
88
28
  @dynamo_policy.create_or_update!
89
29
  @cloudwatch_policy.create_or_update!
30
+ @queue.create_or_update!
90
31
  @role.create_or_update!
91
32
  @lambda.create_or_update!
92
33
  end
34
+
35
+ private
36
+
37
+ def role_name
38
+ function_name
39
+ end
40
+
41
+ def initialize_aws_resources(configs)
42
+ @role = ::Kybus::AWS::Role.new(configs, role_name, :lambda)
43
+ @dynamo_policy = ::Kybus::AWS::Policy.new(configs, "#{function_name}-dynamo", make_dynamo_policy_document)
44
+ @cloudwatch_policy = ::Kybus::AWS::Policy.new(configs, "#{function_name}-cloudwatch",
45
+ make_log_group_policy_document)
46
+ @log_group = ::Kybus::AWS::LogGroup.new(configs, function_name)
47
+ @queue = Kybus::AWS::Queue.new(configs, function_name) if configs.dig('forker', 'queue')
48
+ init_lambda(configs)
49
+ end
50
+
51
+ def lambda_config
52
+ {
53
+ 'triggers' => [{ 'type' => 'url', 'public' => true }],
54
+ 'layers' => [
55
+ {
56
+ 'type' => 'codezip', 'zipfile' => '.deps.zip',
57
+ 'checksumfile' => 'Gemfile.lock', 'name' => "#{function_name}-deps"
58
+ }
59
+ ]
60
+ }
61
+ end
62
+
63
+ def init_lambda(configs)
64
+ @lambda = ::Kybus::AWS::Lambda.new(configs.merge(lambda_config), function_name)
65
+ end
66
+
67
+ def assign_sqs_policy
68
+ @role.add_policy(@queue.make_write_policy) if @queue
69
+ end
70
+
71
+ def assign_policies_to_role
72
+ @role.add_policy(@dynamo_policy)
73
+ @role.add_policy(@cloudwatch_policy)
74
+ assign_sqs_policy
75
+ end
76
+
77
+ def make_dynamo_policy_document
78
+ {
79
+ Version: '2012-10-17',
80
+ Statement: [
81
+ dynamo_policy_allow_all,
82
+ dynamo_policy_allow_describe
83
+ ]
84
+ }
85
+ end
86
+
87
+ def dynamo_policy_allow_all
88
+ {
89
+ Effect: 'Allow',
90
+ Action: ['dynamodb:BatchGetItem', 'dynamodb:BatchWriteItem', 'dynamodb:Describe*', 'dynamodb:Get*',
91
+ 'dynamodb:List*', 'dynamodb:PutItem', 'dynamodb:Query', 'dynamodb:Scan', 'dynamodb:UpdateItem',
92
+ 'dynamodb:DeleteItem'],
93
+ Resource: "arn:aws:dynamodb:#{@region}:#{account_id}:table/#{function_name}*"
94
+ }
95
+ end
96
+
97
+ def dynamo_policy_allow_describe
98
+ {
99
+ Effect: 'Allow',
100
+ Action: [
101
+ 'dynamodb:Describe*',
102
+ 'dynamodb:Get*',
103
+ 'dynamodb:List*'
104
+ ],
105
+ Resource: '*'
106
+ }
107
+ end
108
+
109
+ def make_log_group_policy_document
110
+ {
111
+ Version: '2012-10-17',
112
+ Statement: [
113
+ log_group_policy_create_group,
114
+ log_group_policy_create_stream_and_put_events
115
+ ]
116
+ }
117
+ end
118
+
119
+ def log_group_policy_create_group
120
+ {
121
+ Effect: 'Allow',
122
+ Action: 'logs:CreateLogGroup',
123
+ Resource: "arn:aws:logs:#{@region}:#{account_id}:*"
124
+ }
125
+ end
126
+
127
+ def log_group_policy_create_stream_and_put_events
128
+ {
129
+ Effect: 'Allow',
130
+ Action: [
131
+ 'logs:CreateLogStream',
132
+ 'logs:PutLogEvents'
133
+ ],
134
+ Resource: [
135
+ "arn:aws:logs:#{@region}:#{account_id}:log-group:/aws/lambda/#{function_name}*:*"
136
+ ]
137
+ }
138
+ end
93
139
  end
94
140
  end
95
141
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kybus
4
+ class CLI < Thor
5
+ class AWSBotJobRunnerDeployer < AWSBotDeployer
6
+ def lambda_config
7
+ {
8
+ 'triggers' => [{ 'type' => 'sqs', 'queue_arn' => @queue.arn }],
9
+ 'layers' => [
10
+ { 'type' => 'existing',
11
+ 'name' => "#{function_name}-deps" }
12
+ ],
13
+ 'handler' => 'handler.sqs_job_handler'
14
+ }
15
+ end
16
+
17
+ def role_name
18
+ "#{function_name}_job_processor"
19
+ end
20
+
21
+ def init_lambda(configs)
22
+ @lambda = ::Kybus::AWS::Lambda.new(configs.merge(lambda_config), role_name)
23
+ end
24
+
25
+ def assign_sqs_policy
26
+ @role.add_policy(@queue.make_processor_policy) if @queue
27
+ end
28
+ end
29
+ end
30
+ end
@@ -6,18 +6,23 @@ module Kybus
6
6
  class CLI < Thor
7
7
  class BotDeployerTelegramConfigurator < BotDeployerBase
8
8
  attr_reader :url
9
- attr_writer :url
10
9
 
11
10
  def initialize(url, config)
12
11
  @url = url
13
12
  super(config)
14
13
  end
15
14
 
15
+ def url=(url)
16
+ fail "Empty Webhook URL" if url.nil?
17
+ @url = url
18
+ end
19
+
16
20
  def create_or_update!
17
21
  raise 'Missing Token' if @config['secret_token'].nil?
18
22
 
19
23
  uri = URI("https://api.telegram.org/bot#{@config['bot_token']}/setWebhook")
20
24
  params = { url: @url, secret_token: @config['secret_token'] }
25
+ puts({msg: 'Making request to', url: uri, params: }.to_yaml)
21
26
  res = Net::HTTP.post_form(uri, params)
22
27
  puts res.body
23
28
  end
@@ -6,6 +6,27 @@ module Kybus
6
6
  class ComposefileGenerator < FileProvider
7
7
  autoregister!
8
8
 
9
+ DB_SERVICES = {
10
+ 'dynamoid' => <<-LOCALSTACK.chomp,
11
+ localstack:
12
+ image: localstack/localstack
13
+ ports:
14
+ - "4566:4566"
15
+ environment:
16
+ - SERVICES=dynamodb
17
+ LOCALSTACK
18
+ 'sequel' => <<-DATABASE.chomp
19
+ db:
20
+ image: postgres
21
+ ports:
22
+ - "5432:5432"
23
+ environment:
24
+ POSTGRES_DB: app_development
25
+ POSTGRES_USER: user
26
+ POSTGRES_PASSWORD: password
27
+ DATABASE
28
+ }.freeze
29
+
9
30
  def skip_file?
10
31
  !@config[:with_docker_compose]
11
32
  end
@@ -15,7 +36,7 @@ module Kybus
15
36
  end
16
37
 
17
38
  def make_contents
18
- content = <<~DOCKERCOMPOSE
39
+ <<~DOCKERCOMPOSE + db_service_config
19
40
  version: '3'
20
41
  services:
21
42
  app:
@@ -23,30 +44,12 @@ module Kybus
23
44
  volumes:
24
45
  - .:/app
25
46
  DOCKERCOMPOSE
47
+ end
26
48
 
27
- if @config[:db_adapter] == 'dynamoid'
28
- content << <<-LOCALSTACK
29
- localstack:
30
- image: localstack/localstack
31
- ports:
32
- - "4566:4566"
33
- environment:
34
- - SERVICES=dynamodb
35
- LOCALSTACK
36
- elsif @config[:db_adapter] == 'sequel'
37
- content << <<-DATABASE
38
- db:
39
- image: postgres
40
- ports:
41
- - "5432:5432"
42
- environment:
43
- POSTGRES_DB: app_development
44
- POSTGRES_USER: user
45
- POSTGRES_PASSWORD: password
46
- DATABASE
47
- end
49
+ private
48
50
 
49
- content
51
+ def db_service_config
52
+ DB_SERVICES[@config[:db_adapter]] || ''
50
53
  end
51
54
  end
52
55
  end
@@ -6,6 +6,19 @@ module Kybus
6
6
  module Config
7
7
  class ConfigDefaultGenerator < FileProvider
8
8
  autoregister!
9
+
10
+ DB_CONFIGS = {
11
+ 'sequel' => <<~SEQUEL.chomp,
12
+ name: sequel
13
+ endpoint: 'sqlite://${bot_name_snake_case}_botmeta.db'
14
+ database: 'sqlite://${bot_name_snake_case}.db'
15
+ SEQUEL
16
+ 'dynamoid' => <<~DYNAMOID.chomp
17
+ name: json
18
+ storage: ./storage
19
+ DYNAMOID
20
+ }.freeze
21
+
9
22
  def saving_path
10
23
  'config/config.default.yaml'
11
24
  end
@@ -15,7 +28,7 @@ module Kybus
15
28
  end
16
29
 
17
30
  def make_contents
18
- content = <<~YAML
31
+ <<~YAML + db_config.gsub('${bot_name_snake_case}', bot_name_snake_case)
19
32
  logger:
20
33
  stdout: yes
21
34
  severity: debug
@@ -23,25 +36,18 @@ module Kybus
23
36
  main:
24
37
  pool_size: 1
25
38
  inline_args: true
26
- provider:#{' '}
39
+ provider:
27
40
  name: REPLACE_ME
28
41
  token: REPLACE_ME
29
42
  debug: true
30
43
  state_repository:
31
44
  YAML
45
+ end
46
+
47
+ private
32
48
 
33
- if @config[:db_adapter] == 'sequel'
34
- content << <<~SEQUEL
35
- name: sequel
36
- endpoint: 'sqlite://#{bot_name_snake_case}_botmeta.db'
37
- database: 'sqlite://#{bot_name_snake_case}.db'
38
- SEQUEL
39
- elsif @config[:db_adapter] == 'dynamoid'
40
- content << <<-DYNAMOID
41
- name: json
42
- storage: ./storage
43
- DYNAMOID
44
- end
49
+ def db_config
50
+ DB_CONFIGS[@config[:db_adapter]] || ''
45
51
  end
46
52
  end
47
53
  end
@@ -6,12 +6,28 @@ module Kybus
6
6
  module Config
7
7
  class ConfigGenerator < FileProvider
8
8
  autoregister!
9
+
10
+ DB_CONFIGS = {
11
+ 'sequel' => <<-SEQUEL.chomp,
12
+ name: sequel
13
+ endpoint: 'sqlite://${bot_name_snake_case}_botmeta.db'
14
+ SEQUEL
15
+ 'dynamoid' => <<-DYNAMOID.chomp
16
+ name: dynamoid
17
+ dynamoid_config: true
18
+ region: 'us-east-1'
19
+ namespace: '${bot_name_snake_case}'
20
+ read_capacity: 3
21
+ write_capacity: 3
22
+ DYNAMOID
23
+ }.freeze
24
+
9
25
  def saving_path
10
26
  'config/config.yaml'
11
27
  end
12
28
 
13
29
  def make_contents
14
- content = <<~YAML
30
+ <<~YAML + db_config.gsub('${bot_name_snake_case}', bot_name_snake_case)
15
31
  bots:
16
32
  main:
17
33
  provider:
@@ -21,22 +37,12 @@ module Kybus
21
37
  debug: true
22
38
  state_repository:
23
39
  YAML
40
+ end
41
+
42
+ private
24
43
 
25
- if @config[:db_adapter] == 'sequel'
26
- content << <<-SEQUEL
27
- name: sequel
28
- endpoint: 'sqlite://#{bot_name_snake_case}_botmeta.db'
29
- SEQUEL
30
- elsif @config[:db_adapter] == 'dynamoid'
31
- content << <<-DYNAMOID
32
- name: dynamoid
33
- dynamoid_config: true
34
- region: 'us-east-1'
35
- namespace: '#{bot_name_snake_case}'
36
- read_capacity: 3
37
- write_capacity: 3
38
- DYNAMOID
39
- end
44
+ def db_config
45
+ DB_CONFIGS[@config[:db_adapter]] || ''
40
46
  end
41
47
  end
42
48
  end
@@ -7,44 +7,43 @@ module Kybus
7
7
  class DBGenerator < FileProvider
8
8
  autoregister!
9
9
 
10
+ DB_CONTENTS = {
11
+ 'sequel' => <<~RUBY,
12
+ # frozen_string_literal: true
13
+
14
+ require 'sequel'
15
+
16
+ DB = Sequel.connect(APP_CONF['database'])
17
+
18
+ def run_migrations!
19
+ require 'kybus/bot/migrator'
20
+ require 'sequel/core'
21
+ Kybus::Bot::Migrator.run_migrations!(APP_CONF['bots']['main']['state_repository'])
22
+ Sequel.extension :migration
23
+ Sequel::Migrator.run(DB, 'models/migrations')
24
+ end
25
+ RUBY
26
+ 'activerecord' => <<~RUBY,
27
+ # frozen_string_literal: true
28
+
29
+ require 'active_record'
30
+
31
+ ActiveRecord::Base.establish_connection(APP_CONF['database'])
32
+ RUBY
33
+ 'dynamoid' => <<~RUBY
34
+ def run_migrations!
35
+ require 'kybus/bot/migrator'
36
+ Kybus::Bot::Migrator.run_migrations!(APP_CONF['bots']['main']['state_repository'])
37
+ end
38
+ RUBY
39
+ }.freeze
40
+
10
41
  def saving_path
11
42
  'config_loaders/db.rb'
12
43
  end
13
44
 
14
45
  def make_contents
15
- case @config[:db_adapter]
16
- when 'sequel'
17
- <<~RUBY
18
- # frozen_string_literal: true
19
-
20
- require 'sequel'
21
-
22
- DB = Sequel.connect(APP_CONF['database'])
23
-
24
- def run_migrations!
25
- require 'kybus/bot/migrator'
26
- require 'sequel/core'
27
- Kybus::Bot::Migrator.run_migrations!(APP_CONF['bots']['main']['state_repository'])
28
- Sequel.extension :migration
29
- Sequel::Migrator.run(DB, 'models/migrations')
30
- end
31
- RUBY
32
- when 'activerecord'
33
- <<~RUBY
34
- # frozen_string_literal: true
35
-
36
- require 'active_record'
37
-
38
- ActiveRecord::Base.establish_connection(APP_CONF['database'])
39
- RUBY
40
- when 'dynamoid'
41
- <<~RUBY
42
- def run_migrations!
43
- require 'kybus/bot/migrator'
44
- Kybus::Bot::Migrator.run_migrations!(APP_CONF['bots']['main']['state_repository'])
45
- end
46
- RUBY
47
- end
46
+ DB_CONTENTS[@config[:db_adapter]]
48
47
  end
49
48
  end
50
49
  end
@@ -26,6 +26,16 @@ module Kybus
26
26
  @file_writer = FileWriter.new(@name)
27
27
  end
28
28
 
29
+ def run_commands
30
+ commands = "cd #{@name} && " \
31
+ 'git init . && ' \
32
+ 'bundle install --path vendor/bundle && ' \
33
+ 'git add . && ' \
34
+ 'git commit -m "Initial Commit"'
35
+
36
+ puts `#{commands}`
37
+ end
38
+
29
39
  def generate
30
40
  if File.directory?(@name)
31
41
  puts "Directory exists #{@name}"
@@ -34,7 +44,7 @@ module Kybus
34
44
 
35
45
  create_directories
36
46
  write_files
37
- puts `cd #{@name} && git init . && bundle install --path vendor/bundle && git add . && git commit -m "Initial Commit"`
47
+ run_commands
38
48
  puts "Project #{@name} initialized with #{@configs[:db_adapter]} adapter."
39
49
  end
40
50
 
@@ -0,0 +1,65 @@
1
+ require 'thor'
2
+
3
+ require 'kybus/ssl'
4
+ require 'kybus/ssl/cli'
5
+
6
+
7
+ module Kybus
8
+ class CLI < Thor
9
+ class SSL < Thor
10
+ desc 'init', 'initialize new PKI file'
11
+ class_option :path, alias: :P ,type: :string, desc: 'Set storage path', required: true
12
+ method_option :force, type: :boolean, desc: 'Overwrites previous file', required: false, default: false
13
+ method_option :key_size, alias: :s, desc: 'RSA Key Size', required: true, type: :numeric
14
+ method_option :team, alias: :T, desc: 'Organization Unit', required: true
15
+ method_option :country, alias: :C, desc: 'Country', required: true
16
+ method_option :city , alias: :c, desc: 'City', required: true
17
+ method_option :state , alias: :S, desc: 'State', required: true
18
+
19
+
20
+ def init
21
+ Kybus::SSL::CLI::Init.new(options.merge(pki_file: "#{options[:path]}/pki.yaml")).run
22
+ end
23
+
24
+ desc 'add-ca', 'Add a new CA to inventory'
25
+ method_option :ca_name, type: :string, desc: 'CA Name', required: true
26
+ method_option :key_size, alias: :s, desc: 'RSA Key Size', required: true, type: :numeric
27
+ method_option :expiration, alias: :X, desc: 'Expiration in Years', required: false, type: :numeric
28
+ method_option :ca, type: :string, desc: 'CA Parent Name, default: root', required: false, default: 'root'
29
+ method_option :team, alias: :T, desc: 'Organization Unit', required: false
30
+ method_option :country, alias: :C, desc: 'Country', required: false
31
+ method_option :city , alias: :c, desc: 'City', required: false
32
+ method_option :state , alias: :S, desc: 'State', required: false
33
+
34
+
35
+ def add_ca
36
+ Kybus::SSL::CLI::AddCA.new(options.merge(pki_file: "#{options[:path]}/pki.yaml")).run
37
+ end
38
+
39
+ desc 'add-certificate', 'Add new certificate to inventory'
40
+ method_option :expiration, alias: :X, desc: 'Expiration in Years', required: false, type: :numeric
41
+ method_option :ca
42
+ method_option :key_size, alias: :s, desc: 'RSA Key Size', required: false, type: :numeric
43
+ method_option :name, required: true
44
+ method_option :email, alias: :E, desc: 'E-Mail', required: false
45
+ method_option :team, alias: :T, desc: 'Organization Unit', required: false
46
+ method_option :country, alias: :C, desc: 'Country', required: false
47
+ method_option :city , alias: :c, desc: 'City', required: false
48
+ method_option :state , alias: :S, desc: 'State', required: false
49
+
50
+ def add_certificate
51
+ Kybus::SSL::CLI::AddCertificate.new(options.merge(pki_file: "#{options[:path]}/pki.yaml")).run
52
+ end
53
+
54
+ def update_crl
55
+ Kybus::SSL::CLI::UpdateCRL.new(options.merge(pki_file: "#{options[:path]}/pki.yaml")).run
56
+ end
57
+
58
+ desc 'build', 'Builds the certificates listed in the PKI file'
59
+
60
+ def build
61
+ Kybus::SSL::CLI::Build.new(options.merge(pki_file: "#{options[:path]}/pki.yaml")).run
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ KYBUS_CLI_VERSION = '0.2.2'
data/lib/kybus/cli.rb CHANGED
@@ -2,12 +2,25 @@
2
2
 
3
3
  require 'thor'
4
4
  require_relative 'cli/bot'
5
+ require_relative 'cli/ssl'
6
+ require_relative 'cli/version'
5
7
 
6
8
  module Kybus
7
9
  class CLI < Thor
10
+ VERSION = KYBUS_CLI_VERSION
11
+ map %w[--version -v] => :__print_version
12
+
13
+ desc '--version, -v', 'print the version'
14
+ def __print_version
15
+ puts Kybus::CLI::VERSION
16
+ end
17
+
8
18
  desc 'bot SUBCOMMAND ...ARGS', 'Commands for managing bots'
9
19
  subcommand 'bot', Kybus::CLI::Bot
10
20
 
21
+ desc 'pki SUBCOMMAND ...ARGS', 'Commands for managing PKI'
22
+ subcommand 'pki', Kybus::CLI::SSL
23
+
11
24
  def self.exit_on_failure?
12
25
  true
13
26
  end