bauble_core 0.1.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6928636a53aa5a88ae8f1da06e9ab3b50fb9fefba2c4ff2684c69adcdb68031e
4
- data.tar.gz: 6af981f1f1f607547c09121b3105d14f4ae552af178b6592c9d8d7982b07a294
3
+ metadata.gz: 90cf0a735fda2a560d5a8966ab5b87ab071d5f685af0dc8cff85b113449d580b
4
+ data.tar.gz: 34beb847ffbae3fa044aa8f181efe36974ae6cb2af57be1f587e5a5558f8e866
5
5
  SHA512:
6
- metadata.gz: a4ac5e9706f526df8752dbebf54a0c2f4fd99661b4302d60177d2e7dd4d4e54c7996329888ddc2d57c088f4d858b21db0f30dab3ec3992f23135e0c3ffd9e0e7
7
- data.tar.gz: 7c99a753835fc040bc28bf146beb40c9e1f20c8938eefca59b03b2646f554ff7aa73801752fd7e02f21cc4808975d5d83f273b1f884d42ef16c307317049d0b2
6
+ metadata.gz: f80357144acefd390c9e099e74328b0ac029dd494d4d18b5513bb4d86b3019021370f1e910b7b240b857f327853f729d2a4a08778c43189d78811bc2eb3ebb04
7
+ data.tar.gz: 50151eef8e96197be8e8a9eddccce7e97a9b3ea0478cda255391e5887c07a86f4bcc2a8fbbe9b2443ef7aec0fd56feb4925a09f257152a8426c1351686ae6358
data/exe/bauble CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ # frozen_string_literal: true
4
+
3
5
  require_relative '../lib/bauble/cli/cli'
4
6
 
5
7
  Bauble::Cli::BaubleCli.start(ARGV)
@@ -19,55 +19,81 @@ module Bauble
19
19
  :code_dir,
20
20
  :bundle_hash,
21
21
  :shared_code_dir,
22
+ :shared_code_hash,
23
+ :gem_layer_hash,
22
24
  :skip_gem_layer
23
25
  )
24
26
 
25
- def initialize(name:, stacks: [], code_dir: nil, skip_gem_layer: false)
26
- @resources = []
27
- @stacks = []
27
+ def initialize(name:, code_dir:, stacks: [], skip_gem_layer: false)
28
+ # passed arguments
28
29
  @name = name
29
30
  @shared_code_dir = code_dir
31
+ @stacks = []
30
32
  @skip_gem_layer = skip_gem_layer
33
+
34
+ # init others
35
+ @resources = []
36
+
37
+ # add gem layer by defalt
31
38
  add_gem_layer unless skip_gem_layer
39
+
40
+ # create a default stack if none passed
32
41
  stacks = ['dev'] if stacks.empty?
33
42
  stacks.each do |stack|
34
43
  Stack.new(self, stack)
35
44
  end
36
- end
37
-
38
- def add_resource(resource)
39
- @resources << resource
40
- end
41
-
42
- def add_stack(stack)
43
- @stacks << stack
45
+ @current_stack = @stacks[0]
44
46
  end
45
47
 
46
48
  def template
47
49
  @template ||= synthesize_template
48
50
  end
49
51
 
50
- def add_gem_layer
51
- Bauble::Resources::GemLayer.new(self)
52
- end
53
-
54
52
  def change_current_stack(stack_name)
55
- @current_stack = @stacks.find { |stack| stack.name == stack_name }
53
+ stack = @stacks.find { |st| st.name == stack_name }
54
+ unless stack
55
+ Bauble::Cli::Logger.error "Unknown stack #{stack_name}"
56
+ exit(1)
57
+ end
58
+
59
+ @current_stack = stack
56
60
  end
57
61
 
58
62
  def bundle
59
- # TODO: this potentially need to be a hash of more resources I'm not sure yet'
60
- @bundle_hash = generate_unique_string("#{Dir.pwd}/app")
63
+ create_bundle_hashes
61
64
  create_shared_code
62
65
  @resources.each(&:bundle)
63
66
  end
64
67
 
68
+ def add_resource(resource)
69
+ @resources << resource
70
+ end
71
+
72
+ def add_stack(stack)
73
+ @stacks << stack
74
+ end
75
+
65
76
  private
66
77
 
78
+ def create_bundle_hashes
79
+ @bundle_hash = hash_of_dir("#{Dir.pwd}/#{code_dir}")
80
+ @shared_code_hash = hash_of_dir("#{@config.root_dir}/#{@shared_code_dir}") if @shared_code_dir
81
+ @gem_layer_hash = hash_of_file("#{@config.root_dir}/Gemfile") unless @skip_gem_layer
82
+ end
83
+
84
+ def add_gem_layer
85
+ Bauble::Resources::GemLayer.new(self)
86
+ end
87
+
67
88
  def create_shared_code
68
89
  return unless @shared_code_dir
69
90
 
70
- destination_dir = File.join(config.asset_dir, @bundle_hash, 'shared_app_code', File.basename(@shared_code_dir))
91
+ destination_dir = File.join(
92
+ config.asset_dir,
93
+ 'shared_app_code',
94
+ @shared_code_hash,
95
+ @shared_code_dir
96
+ )
71
97
  FileUtils.mkdir_p(destination_dir)
72
98
  FileUtils.cp_r(Dir.glob(File.join(@shared_code_dir, '*')), destination_dir)
73
99
  end
@@ -87,10 +113,14 @@ module Bauble
87
113
  }
88
114
  end
89
115
 
90
- def generate_unique_string(directory)
116
+ def hash_of_dir(directory)
91
117
  files = Dir.glob("#{directory}/**/*").select { |file| File.file?(file) }
92
118
  content_hash = files.map { |file| Digest::SHA256.file(file).hexdigest }.join
93
119
  Digest::SHA256.hexdigest(content_hash)
94
120
  end
121
+
122
+ def hash_of_file(filename)
123
+ Digest::SHA256.file(filename).hexdigest
124
+ end
95
125
  end
96
126
  end
@@ -13,8 +13,8 @@ module Bauble
13
13
  self
14
14
  end
15
15
 
16
- def with_bundle_path(bundle_hash)
17
- @commands << "bundle config set path \".bauble/assets/#{bundle_hash}/gem-layer\""
16
+ def with_bundle_path(path)
17
+ @commands << "bundle config set path #{path}"
18
18
  self
19
19
  end
20
20
 
@@ -49,7 +49,7 @@ module Bauble
49
49
  def write_stack_template(stack)
50
50
  create_directory
51
51
  # TODO: this can probably be put into something smarter, maube a file writing class?
52
- File.open("#{config.pulumi_home}/Pulumi.#{stack.name}.yaml", 'w') { |file| file.write(stack.template) }
52
+ File.write("#{config.pulumi_home}/Pulumi.#{stack.name}.yaml", stack.template)
53
53
  end
54
54
 
55
55
  def create_directory
@@ -61,8 +61,7 @@ module Bauble
61
61
  end
62
62
 
63
63
  def require_entrypoint
64
- # TODO: We should probably use a config value here instead of Dir.pwd
65
- require "#{Dir.pwd}/#{bauble_json['entrypoint']}"
64
+ Kernel.require "#{Dir.pwd}/#{bauble_json['entrypoint']}"
66
65
  end
67
66
  end
68
67
  end
@@ -10,14 +10,14 @@ module Bauble
10
10
  # bundle code
11
11
  class CodeBundler
12
12
  class << self
13
- def docker_bundle_gems(bundle_hash:)
14
- IO.popen("#{docker_build_gems_command(bundle_hash)} 2>&1") do |io|
13
+ def docker_bundle_gems(gem_path:)
14
+ IO.popen("#{docker_build_gems_command(gem_path)} 2>&1") do |io|
15
15
  io.each do |line|
16
16
  Logger.docker(line)
17
17
  end
18
18
  end
19
19
 
20
- return if $CHILD_STATUS.success?
20
+ return if last_process_success?
21
21
 
22
22
  `rm -rf .bundle`
23
23
  Logger.error('Bundle step failed')
@@ -26,8 +26,12 @@ module Bauble
26
26
 
27
27
  private
28
28
 
29
+ def last_process_success?
30
+ $CHILD_STATUS.success?
31
+ end
32
+
29
33
  # TODO: Remove the need for this to install things from the sub dir
30
- def docker_build_gems_command(bundle_hash)
34
+ def docker_build_gems_command(gem_path)
31
35
  command = DockerCommandBuilder
32
36
  .new
33
37
  .with_rm
@@ -41,15 +45,15 @@ module Bauble
41
45
  end
42
46
 
43
47
  command.with_image('public.ecr.aws/sam/build-ruby3.2')
44
- .with_command(bundle_command(bundle_hash))
48
+ .with_command(bundle_command(gem_path))
45
49
  .build
46
50
  end
47
51
 
48
- def bundle_command(bundle_hash)
52
+ def bundle_command(gem_path)
49
53
  command = BundleCommandBuilder
50
54
  .new
51
55
  .with_bundle_without(%w[test development])
52
- .with_bundle_path(bundle_hash)
56
+ .with_bundle_path(gem_path)
53
57
 
54
58
  command.with_bauble_gem_override if ENV['BAUBLE_DEV_GEM_PATH']
55
59
 
@@ -24,7 +24,7 @@ module Bauble
24
24
 
25
25
  # check for multiple stacks
26
26
  if @app.stacks.length > 1 && options[:stack].nil?
27
- Log.error 'Must provide a stack when multiple are defined'
27
+ Logger.error 'Must provide a stack when multiple are defined'
28
28
  exit(1)
29
29
  end
30
30
 
@@ -23,7 +23,7 @@ module Bauble
23
23
 
24
24
  # check for multiple stacks
25
25
  if @app.stacks.length > 1 && options[:stack].nil?
26
- Log.error 'Must provide a stack when multiple are defined'
26
+ Logger.error 'Must provide a stack when multiple are defined'
27
27
  exit(1)
28
28
  end
29
29
 
@@ -23,7 +23,7 @@ module Bauble
23
23
 
24
24
  # check for multiple stacks
25
25
  if @app.stacks.length > 1 && options[:stack].nil?
26
- Log.error 'Must provide a stack when multiple are defined'
26
+ Logger.error 'Must provide a stack when multiple are defined'
27
27
  exit(1)
28
28
  end
29
29
 
@@ -12,7 +12,9 @@ module Bauble
12
12
  :debug,
13
13
  :asset_dir,
14
14
  :root_dir,
15
- :skip_gem_layer
15
+ :skip_gem_layer,
16
+ :gem_layer_asset_dir,
17
+ :shared_code_asset_dir
16
18
  )
17
19
 
18
20
  def initialize
@@ -20,6 +22,8 @@ module Bauble
20
22
  @bauble_home = "#{@root_dir}/.bauble"
21
23
  @asset_dir = "#{@bauble_home}/assets"
22
24
  @pulumi_home = "#{@bauble_home}/.pulumi"
25
+ @gem_layer_asset_dir = "#{@asset_dir}/gem_layer"
26
+ @shared_code_asset_dir = "#{@asset_dir}/shared_app_code"
23
27
  @app_stack_name = 'bauble'
24
28
  @debug = ENV['BAUBLE_DEBUG'] || false
25
29
  @skip_gem_layer = false
@@ -39,7 +39,7 @@ module Bauble
39
39
  end
40
40
 
41
41
  def with_command(cmd)
42
- @command += "-c \"#{cmd}\""
42
+ @command += %(-c "#{cmd.gsub('"', '\"')}" )
43
43
  self
44
44
  end
45
45
 
@@ -49,7 +49,7 @@ module Bauble
49
49
  end
50
50
 
51
51
  def build
52
- @command
52
+ @command.strip
53
53
  end
54
54
  end
55
55
  end
@@ -30,7 +30,7 @@ module Bauble
30
30
  end
31
31
 
32
32
  def debug(message)
33
- puts "[ Bauble DEBUG ] #{message}".orange if ENV['BAUBLE_DEBUG']
33
+ puts "[ Bauble DEBUG ] #{message}".yellow if ENV['BAUBLE_DEBUG']
34
34
  end
35
35
 
36
36
  def error(message)
@@ -16,7 +16,7 @@ module Bauble
16
16
 
17
17
  def create_pulumi_yml(template)
18
18
  Logger.debug 'Creating Pulumi.yaml...'
19
- FileUtils.mkdir_p(@config.pulumi_home) unless Dir.exist?(@config.pulumi_home)
19
+ FileUtils.mkdir_p(@config.pulumi_home)
20
20
  File.write("#{@config.pulumi_home}/Pulumi.yaml", template, mode: 'w')
21
21
  end
22
22
 
@@ -102,8 +102,9 @@ module Bauble
102
102
 
103
103
  def pulumi_logged_in?
104
104
  run_command('whoami')
105
- Logger.debug "Checking pulumi login status... #{$CHILD_STATUS.success?}"
106
- $CHILD_STATUS.success?
105
+ success = pulumi_command_success?
106
+ Logger.debug "Checking pulumi login status... #{success}"
107
+ success
107
108
  end
108
109
 
109
110
  def init_stack(stack_name)
@@ -118,6 +119,10 @@ module Bauble
118
119
  Logger.debug "Checking if stack #{stack_name} is initialized..."
119
120
  run_command('stack ls').include?(stack_name)
120
121
  end
122
+
123
+ def pulumi_command_success?
124
+ $CHILD_STATUS.success?
125
+ end
121
126
  end
122
127
  end
123
128
  end
@@ -35,7 +35,7 @@ module Bauble
35
35
  private
36
36
 
37
37
  def routes_hash
38
- routes.each_with_index.each_with_object({}) do |(route, index), route_hash|
38
+ routes.each_with_index.with_object({}) do |(route, index), route_hash|
39
39
  route_name = "#{name}-route-#{index}"
40
40
  route_hash[route_name] = {
41
41
  'type' => 'aws:apigatewayv2:Route',
@@ -45,11 +45,11 @@ module Bauble
45
45
  'target' => "integrations/${#{route_name}-integration.id}"
46
46
  }
47
47
  }
48
- route_hash.merge!(synthesize_integration(route, route_name))
48
+ route_hash.merge!(integration_hash(route, route_name))
49
49
  end
50
50
  end
51
51
 
52
- def synthesize_integration(route, route_name)
52
+ def integration_hash(route, route_name)
53
53
  {
54
54
  "#{route_name}-integration" => {
55
55
  'type' => 'aws:apigatewayv2:Integration',
@@ -102,7 +102,7 @@ module Bauble
102
102
  name => {
103
103
  'type' => 'aws:apigatewayv2:Api',
104
104
  'properties' => {
105
- 'name' => name,
105
+ 'name' => resource_name(name),
106
106
  'protocolType' => 'HTTP'
107
107
  }
108
108
  },
@@ -6,9 +6,9 @@ module Bauble
6
6
  module Resources
7
7
  # EventBridgeRule class
8
8
  class EventBridgeRule < Resource
9
- def initialize(app, rule_name:, **kwargs)
9
+ def initialize(app, name:, **kwargs)
10
10
  super(app)
11
- @rule_name = rule_name
11
+ @name = name
12
12
  @description = kwargs.fetch(:description, 'Bauble EventBridge Rule')
13
13
  @event_pattern = kwargs.fetch(:event_pattern, nil)
14
14
  @schedule_expression = kwargs.fetch(:schedule_expression, nil)
@@ -21,10 +21,10 @@ module Bauble
21
21
 
22
22
  def synthesize
23
23
  event_rule_hash = {
24
- @rule_name => {
24
+ @name => {
25
25
  'type' => 'aws:cloudwatch:EventRule',
26
26
  'properties' => {
27
- 'name' => @rule_name,
27
+ 'name' => resource_name(@name),
28
28
  'description' => @description,
29
29
  'eventBusName' => @event_bus_name,
30
30
  'state' => @state
@@ -32,8 +32,8 @@ module Bauble
32
32
  }
33
33
  }
34
34
 
35
- event_rule_hash[@rule_name]['properties']['eventPattern'] = @event_pattern.to_json if @event_pattern
36
- event_rule_hash[@rule_name]['properties']['scheduleExpression'] = @schedule_expression if @schedule_expression
35
+ event_rule_hash[@name]['properties']['eventPattern'] = @event_pattern.to_json if @event_pattern
36
+ event_rule_hash[@name]['properties']['scheduleExpression'] = @schedule_expression if @schedule_expression
37
37
 
38
38
  @targets.each do |target|
39
39
  event_rule_hash.merge!(target)
@@ -48,10 +48,10 @@ module Bauble
48
48
 
49
49
  def add_target(function)
50
50
  @targets << {
51
- "#{@rule_name}-#{function.name}-target" => {
51
+ "#{@name}-#{function.name}-target" => {
52
52
  'type' => 'aws:cloudwatch:EventTarget',
53
53
  'properties' => {
54
- 'rule' => "${#{@rule_name}.name}",
54
+ 'rule' => "${#{@name}.name}",
55
55
  'arn' => "${#{function.name}.arn}"
56
56
  }
57
57
  },
@@ -61,7 +61,7 @@ module Bauble
61
61
  'action' => 'lambda:InvokeFunction',
62
62
  'function' => "${#{function.name}.name}",
63
63
  'principal' => 'events.amazonaws.com',
64
- 'sourceArn' => "${#{@rule_name}.arn}"
64
+ 'sourceArn' => "${#{@name}.arn}"
65
65
  }
66
66
  }
67
67
  }
@@ -76,21 +76,21 @@ module Bauble
76
76
  end
77
77
 
78
78
  def pattern_or_schedule?
79
- return if @event_pattern || @schedule_expression
79
+ return false if @event_pattern || @schedule_expression
80
80
 
81
81
  raise 'EventBridgeRule must have an event_pattern or a schedule_expression'
82
82
  end
83
83
 
84
84
  def pattern_and_schedule?
85
- return unless @event_pattern && @schedule_expression
85
+ return false unless @event_pattern && @schedule_expression
86
86
 
87
87
  raise 'EventBridgeRule cannot have both an event_pattern and a schedule_expression'
88
88
  end
89
89
 
90
90
  def name_present?
91
- return if @rule_name
91
+ return false if @name
92
92
 
93
- raise 'EventBridgeRule must have a rule_name'
93
+ raise 'EventBridgeRule must have a name'
94
94
  end
95
95
  end
96
96
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'zip'
4
3
  require_relative 'resource'
5
4
  require_relative '../cli/code_bundler'
6
5
 
@@ -10,19 +9,23 @@ module Bauble
10
9
  # a ruby lambda function
11
10
  class GemLayer < Resource
12
11
  def bundle
13
- Bauble::Cli::CodeBundler.docker_bundle_gems(bundle_hash: @app.bundle_hash)
12
+ FileUtils.mkdir_p("#{@app.config.gem_layer_asset_dir}/#{@app.gem_layer_hash}")
13
+
14
+ Bauble::Cli::CodeBundler.docker_bundle_gems(
15
+ gem_path: ".bauble/assets/gem_layer/#{@app.gem_layer_hash}"
16
+ )
14
17
  end
15
18
 
16
19
  def synthesize
17
20
  {
18
21
  'gemLayer' => {
19
22
  'type' => 'aws:lambda:LayerVersion',
20
- 'name' => 'gem_layer',
23
+ 'name' => resource_name('gem_layer'),
21
24
  'properties' => {
22
25
  'code' => {
23
- 'fn::fileArchive' => "#{@app.config.asset_dir}/#{@app.bundle_hash}/gem-layer"
26
+ 'fn::fileArchive' => "#{@app.config.gem_layer_asset_dir}/#{@app.gem_layer_hash}"
24
27
  },
25
- 'layerName' => "#{@app.config.app_name}-gem-layer",
28
+ 'layerName' => resource_name('gem_layer'),
26
29
  'compatibleRuntimes' => %w[ruby3.2]
27
30
  }
28
31
  }
@@ -7,22 +7,28 @@ module Bauble
7
7
  module Resources
8
8
  # aws lambda role
9
9
  class LambdaRole < Resource
10
- attr_accessor :role_name, :policy_statements
10
+ attr_accessor :name, :policy_statements, :managed_policy_arns, :description
11
11
 
12
- def initialize(app, role_name:, policy_statements: [])
12
+ def initialize(app, name:, policy_statements: [], **kwargs)
13
13
  super(app)
14
- @role_name = role_name
14
+ @name = name
15
15
  @policy_statements = policy_statements
16
+ @managed_policy_arns = []
17
+ @description = kwargs.fetch(:description, 'Bauble lambda role')
16
18
  end
17
19
 
18
20
  def synthesize
19
21
  role_hash = {
20
- role_name => {
22
+ name => {
21
23
  'type' => 'aws:iam:Role',
22
24
  'properties' => {
25
+ 'name' => resource_name(name),
23
26
  'assumeRolePolicy' => assume_role_policy,
24
- 'managedPolicyArns' => ['arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole']
25
- }
27
+ 'managedPolicyArns' => managed_policy_arns.push(
28
+ 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
29
+ ),
30
+ 'description' => @description
31
+ }.compact
26
32
  }
27
33
  }
28
34
 
@@ -43,11 +49,11 @@ module Bauble
43
49
 
44
50
  def role_policy
45
51
  {
46
- "#{role_name}-policy" => {
52
+ "#{name}-policy" => {
47
53
  'type' => 'aws:iam:RolePolicy',
48
54
  'properties' => {
49
- 'name' => "#{role_name}-policy",
50
- 'role' => "${#{role_name}}",
55
+ 'name' => "#{name}-policy",
56
+ 'role' => "${#{name}}",
51
57
  'policy' => synth_policies
52
58
  }
53
59
  }
@@ -3,7 +3,6 @@
3
3
  module Bauble
4
4
  module Resources
5
5
  # Base resource
6
- # TODO: this should just be Resource not base resource
7
6
  class Resource
8
7
  attr_accessor :app
9
8
 
@@ -19,6 +18,10 @@ module Bauble
19
18
  def bundle
20
19
  raise 'Not implemented'
21
20
  end
21
+
22
+ def resource_name(base_name)
23
+ "#{app.name}-#{base_name}-#{app.current_stack.name}"
24
+ end
22
25
  end
23
26
  end
24
27
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'zip'
4
3
  require_relative 'resource'
5
4
 
6
5
  # Ruby function
@@ -8,81 +7,88 @@ module Bauble
8
7
  module Resources
9
8
  # a ruby lambda function
10
9
  class RubyFunction < Resource
11
- attr_accessor :handler, :name, :role, :code_dir, :function_url, :env_vars
10
+ attr_accessor :handler, :name, :role, :function_url, :env_vars, :layers, :timeout, :memory_size,
11
+ :reserved_concurrent_executions, :vpc_config, :image_uri
12
12
 
13
13
  def initialize(app, **kwargs)
14
14
  super(app)
15
15
  @name = kwargs[:name]
16
16
  @handler = kwargs[:handler]
17
- @code_dir = kwargs[:code_dir]
18
17
  @role = kwargs[:role]
18
+ @layers = kwargs.fetch(:layers, [])
19
+ @image_uri = kwargs.fetch(:image_uri, nil)
19
20
  @function_url = kwargs.fetch(:function_url, false)
20
21
  @env_vars = kwargs.fetch(:env_vars, {})
22
+ @timeout = kwargs.fetch(:timeout, 30) # default to 30 seconds
23
+ @memory_size = kwargs.fetch(:memory_size, 128) # default to 128 MB
24
+ @reserved_concurrent_executions = kwargs.fetch(:reserved_concurrent_executions, nil) # no limit by default
25
+ @vpc_config = kwargs.fetch(:vpc_config, nil) # VPC config is optional
21
26
  end
22
27
 
23
28
  def bundle
24
- return true unless @code_dir
25
-
26
- # generate the asset directory path
27
- assets_dir = File.join(@app.config.asset_dir, @app.bundle_hash)
28
- FileUtils.mkdir_p(assets_dir)
29
-
30
- # create the zipfile path
31
- zipfile_name = File.join(assets_dir, "#{name}.zip")
32
- FileUtils.rm_f(zipfile_name)
33
-
34
- # create the zipfile
35
- Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
36
- # add the code directory to the zipfile
37
- Dir.glob(File.join(@code_dir, '**', '*')).each do |file|
38
- zipfile_path = File.join(File.basename(@code_dir), file.sub("#{code_dir}/", ''))
39
- zipfile.add(zipfile_path, file)
40
- end
41
-
42
- %w[Gemfile Gemfile.lock].each do |gemfile|
43
- gemfile_path = File.join(@app.config.root_dir, gemfile)
44
- zipfile.add(gemfile, gemfile_path) if File.exist?(gemfile_path)
45
- end
46
- end
29
+ true
47
30
  end
48
31
 
49
32
  def synthesize
50
- template = base_template
33
+ template = function_hash
34
+ template[@name]['properties'].merge!(code_hash)
51
35
  template.merge!(function_url_template_addon) if @function_url
52
36
  template
53
37
  end
54
38
 
55
39
  private
56
40
 
57
- def base_template
41
+ def function_hash
58
42
  {
59
43
  @name => {
60
44
  'type' => 'aws:lambda:Function',
61
- 'name' => @name,
45
+ 'name' => resource_name(@name),
62
46
  'properties' => {
63
- 'handler' => @handler,
64
- 'runtime' => 'ruby3.2',
65
- 'code' => {
66
- 'fn::fileArchive' => code_archive
67
- },
68
- 'role' => "${#{@role.role_name}.arn}",
69
- 'layers' => ['${gemLayer.arn}'],
47
+ 'name' => resource_name(@name),
48
+ 'role' => "${#{@role.name}.arn}",
70
49
  'environment' => {
71
50
  'variables' => @env_vars.merge(
72
51
  {
73
52
  'GEM_PATH' => '/opt/ruby/3.2.0'
74
53
  }
75
54
  )
76
- }
77
- }
55
+ },
56
+ 'timeout' => @timeout,
57
+ 'memorySize' => @memory_size,
58
+ 'reservedConcurrentExecutions' => @reserved_concurrent_executions,
59
+ 'vpcConfig' => if @vpc_config
60
+ {
61
+ 'subnetIds' => @vpc_config[:subnet_ids],
62
+ 'securityGroupIds' => @vpc_config[:security_group_ids]
63
+ }
64
+ end
65
+ }.compact
78
66
  }
79
67
  }
80
68
  end
81
69
 
82
- def code_archive
83
- return "#{@app.config.asset_dir}/#{@app.bundle_hash}/#{@name}.zip" if @code_dir
70
+ def gem_layers
71
+ all_layers = layers.dup
72
+ all_layers << '${gemLayer.arn}' unless @app.config.skip_gem_layer
73
+ all_layers
74
+ end
84
75
 
85
- "#{@app.config.asset_dir}/#{@app.bundle_hash}/shared_app_code"
76
+ def code_hash
77
+ if @image_uri
78
+ return {
79
+ 'packageType' => 'Image',
80
+ 'imageUri' => @image_uri
81
+ }
82
+ end
83
+
84
+ {
85
+ 'code' => {
86
+ 'fn::fileArchive' => "#{@app.config.asset_dir}/shared_app_code/#{@app.shared_code_hash}"
87
+ },
88
+ 'handler' => @handler,
89
+ 'layers' => gem_layers,
90
+ 'runtime' => 'ruby3.2'
91
+ }
86
92
  end
87
93
 
88
94
  def function_url_template_addon
@@ -7,20 +7,20 @@ module Bauble
7
7
  module Resources
8
8
  # S3 bucket
9
9
  class S3Bucket < Resource
10
- attr_accessor :bucket_name, :force_destroy
10
+ attr_accessor :name, :force_destroy
11
11
 
12
- def initialize(app, bucket_name: 'bauble-bucket', force_destroy: false)
12
+ def initialize(app, name: 'bauble-bucket', force_destroy: false)
13
13
  super(app)
14
- @bucket_name = bucket_name
14
+ @name = name
15
15
  @force_destroy = force_destroy
16
16
  end
17
17
 
18
18
  def synthesize
19
19
  {
20
- @bucket_name => {
20
+ @name => {
21
21
  'type' => 'aws:s3:Bucket',
22
22
  'properties' => {
23
- 'bucket' => @bucket_name,
23
+ 'bucket' => resource_name(@name),
24
24
  'forceDestroy' => @force_destroy
25
25
  }
26
26
  }
@@ -2,17 +2,21 @@
2
2
 
3
3
  require_relative 'resource'
4
4
 
5
- # bauble resources to manage infrastructure
5
+ # Bauble resources to manage infrastructure
6
6
  module Bauble
7
7
  module Resources
8
8
  # SQS Queue
9
9
  class SQSQueue < Resource
10
- attr_accessor :name, :visibility_timeout, :lambda_targets
10
+ attr_accessor :name, :visibility_timeout, :lambda_targets, :message_retention, :dead_letter_queue,
11
+ :encryption, :encryption_master_key
11
12
 
12
- def initialize(app, name:, visibility_timeout: 30)
13
+ def initialize(app, **kwargs)
13
14
  super(app)
14
- @name = name
15
- @visibility_timeout = visibility_timeout
15
+ @name = kwargs.fetch(:name)
16
+ @visibility_timeout = kwargs.fetch(:visibility_timeout, 30)
17
+ @message_retention = kwargs.fetch(:message_retention, 345_600)
18
+ @dead_letter_queue = kwargs.fetch(:dead_letter_queue, nil)
19
+ @content_based_deduplication = kwargs.fetch(:content_based_deduplication, false)
16
20
  @lambda_targets = []
17
21
  end
18
22
 
@@ -21,12 +25,15 @@ module Bauble
21
25
  @name => {
22
26
  'type' => 'aws:sqs:Queue',
23
27
  'properties' => {
24
- 'name' => @name,
25
- 'visibilityTimeoutSeconds' => @visibility_timeout
26
- }
28
+ 'name' => resource_name(@name),
29
+ 'visibilityTimeoutSeconds' => @visibility_timeout,
30
+ 'messageRetentionSeconds' => @message_retention
31
+ }.compact
27
32
  }
28
33
  }
29
34
 
35
+ base_template.merge!(dead_letter_queue_template) if @dead_letter_queue
36
+
30
37
  @lambda_targets.each { |target| base_template.merge!(target) }
31
38
 
32
39
  base_template
@@ -36,7 +43,6 @@ module Bauble
36
43
  true
37
44
  end
38
45
 
39
- # Function to add a Lambda function as a target to the SQS Queue
40
46
  def add_target(function)
41
47
  @lambda_targets << {
42
48
  "#{@name}_to_#{function.name}" => {
@@ -54,6 +60,23 @@ module Bauble
54
60
  resources: ["${#{name}.arn}"]
55
61
  )
56
62
  end
63
+
64
+ private
65
+
66
+ def dead_letter_queue_template
67
+ {
68
+ 'redrivePolicy' => {
69
+ 'type' => 'aws:sqs:RedrivePolicy',
70
+ 'properties' => {
71
+ 'queueUrl' => "${#{name}}",
72
+ 'redrivePolicy' => {
73
+ 'deadLetterTargetArn' => "${#{@dead_letter_queue.name}.arn}",
74
+ 'maxReceiveCount' => 5
75
+ }.to_json
76
+ }
77
+ }
78
+ }
79
+ end
57
80
  end
58
81
  end
59
82
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bauble
4
- VERSION = '0.1.0'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bauble_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Hoegerl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-11 00:00:00.000000000 Z
11
+ date: 2024-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.1.0
27
- - !ruby/object:Gem::Dependency
28
- name: rubyzip
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 2.3.2
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 2.3.2
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: thor
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +84,7 @@ metadata:
98
84
  homepage_uri: https://github.com/la-jamesh/bauble
99
85
  source_code_uri: https://github.com/la-jamesh/bauble
100
86
  changelog_uri: https://github.com/la-jamesh/bauble
87
+ rubygems_mfa_required: 'true'
101
88
  post_install_message:
102
89
  rdoc_options: []
103
90
  require_paths: