jets 3.2.2 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/jets.gemspec +1 -1
- data/lib/jets/application/defaults.rb +2 -0
- data/lib/jets/application.rb +6 -7
- data/lib/jets/aws_info.rb +2 -2
- data/lib/jets/booter.rb +48 -1
- data/lib/jets/builders/code_builder.rb +2 -21
- data/lib/jets/builders/gem_replacer.rb +2 -7
- data/lib/jets/builders/ruby_packager.rb +37 -4
- data/lib/jets/cfn/builders/api_deployment_builder.rb +1 -1
- data/lib/jets/cfn/builders/api_gateway_builder.rb +25 -22
- data/lib/jets/cfn/builders/api_resources_builder.rb +1 -1
- data/lib/jets/cfn/builders/authorizer_builder.rb +1 -1
- data/lib/jets/cfn/builders/base_child_builder.rb +20 -1
- data/lib/jets/cfn/builders/interface.rb +19 -0
- data/lib/jets/cfn/builders/parent_builder.rb +3 -3
- data/lib/jets/cfn/builders/shared_builder.rb +1 -1
- data/lib/jets/cfn/built_template.rb +1 -1
- data/lib/jets/cfn/ship.rb +2 -2
- data/lib/jets/cfn/status.rb +1 -1
- data/lib/jets/cfn/upload.rb +2 -2
- data/lib/jets/cli.rb +10 -4
- data/lib/jets/commands/call/base_guesser.rb +1 -1
- data/lib/jets/commands/clean/log.rb +3 -3
- data/lib/jets/commands/configure.rb +1 -1
- data/lib/jets/commands/delete.rb +1 -1
- data/lib/jets/commands/deploy.rb +2 -2
- data/lib/jets/commands/stack_info.rb +1 -1
- data/lib/jets/commands/templates/skeleton/config/application.rb.tt +1 -1
- data/lib/jets/commands/url.rb +1 -1
- data/lib/jets/core.rb +14 -2
- data/lib/jets/core_ext/file.rb +9 -0
- data/lib/jets/dotenv.rb +2 -2
- data/lib/jets/erb.rb +1 -1
- data/lib/jets/inflections.rb +1 -1
- data/lib/jets/internal/app/controllers/jets/bare_controller.rb +1 -1
- data/lib/jets/internal/app/jobs/jets/preheat_job.rb +9 -5
- data/lib/jets/lambda/dsl.rb +9 -2
- data/lib/jets/{naming.rb → names.rb} +3 -3
- data/lib/jets/preheat.rb +9 -6
- data/lib/jets/resource/api_gateway/base_path/role.rb +1 -1
- data/lib/jets/resource/api_gateway/cors.rb +1 -1
- data/lib/jets/resource/api_gateway/deployment.rb +2 -2
- data/lib/jets/resource/api_gateway/rest_api/logical_id.rb +1 -1
- data/lib/jets/resource/api_gateway/rest_api/routes/change/base.rb +1 -1
- data/lib/jets/resource/api_gateway/rest_api/routes/change/media_types.rb +1 -1
- data/lib/jets/resource/api_gateway/rest_api/routes/change/page.rb +2 -2
- data/lib/jets/resource/api_gateway/rest_api/routes/change.rb +1 -1
- data/lib/jets/resource/api_gateway/rest_api.rb +1 -1
- data/lib/jets/resource/child_stack/api_deployment.rb +1 -1
- data/lib/jets/resource/child_stack/api_resource/page.rb +1 -1
- data/lib/jets/resource/child_stack/api_resource.rb +1 -1
- data/lib/jets/resource/child_stack/app_class.rb +1 -1
- data/lib/jets/resource/child_stack/shared.rb +1 -1
- data/lib/jets/resource/iam/base_role_definition.rb +0 -5
- data/lib/jets/resource/iam/policy.rb +31 -0
- data/lib/jets/resource/lambda/function/environment.rb +2 -1
- data/lib/jets/resource/lambda/function.rb +3 -3
- data/lib/jets/router/route.rb +16 -4
- data/lib/jets/tmp_loader.rb +1 -1
- data/lib/jets/turbo/database_yaml.rb +1 -1
- data/lib/jets/util/yamler.rb +16 -0
- data/lib/jets/version.rb +1 -1
- data/lib/jets.rb +1 -0
- metadata +7 -9
- data/.python-version +0 -1
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 822ebcd3afbcb8bc1f98310e874f0637bf6be2e8eac8ffa88047eabe37aa3b89
|
4
|
+
data.tar.gz: 7f7fef65966114c720ca1baf04b2ec9766a9f2c2f8a0052be0f5014d9dc08e46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ea8e9c62cd4a340d860f3da2c2849dc2c7a7472ffea80c7794002718eb139996fdf6d75cdbefaedde150d314b9e2bb6968afdccec5c585ba45e90ec78e959fe
|
7
|
+
data.tar.gz: dd5ae3f105882cd8fe057e3fcece81b5197e0c04bd0700384427c61ac6554a777d191d6682d3d2549a72905e7d9a8e1bcd36a4e726c53c7c776bde99c9cbd240
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,28 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
|
5
5
|
|
6
|
+
## [4.0.1] - 2023-06-06
|
7
|
+
- [#655](https://github.com/boltops-tools/jets/pull/655) fix cors when using authorizers
|
8
|
+
- [#656](https://github.com/boltops-tools/jets/pull/656) fix prewarming iam permission
|
9
|
+
|
10
|
+
## [4.0.0] - 2023-05-27
|
11
|
+
- [#641](https://github.com/boltops-tools/jets/pull/641) bundle check and prevent error from getting to aws lambda
|
12
|
+
- [#642](https://github.com/boltops-tools/jets/pull/642) Fix rack mounted apps: update interface with removed meth
|
13
|
+
- [#643](https://github.com/boltops-tools/jets/pull/643) JETS_EXTRA support, deprecate JETS_ENV_EXTRA
|
14
|
+
- [#644](https://github.com/boltops-tools/jets/pull/644) remove docs to separate repo
|
15
|
+
- [#645](https://github.com/boltops-tools/jets/pull/645) PreheatJob: fix function lookups and iam function permission
|
16
|
+
- [#646](https://github.com/boltops-tools/jets/pull/646) log debug uploading and setting content type
|
17
|
+
- [#647](https://github.com/boltops-tools/jets/pull/647) fix Jets.logger call
|
18
|
+
- [#648](https://github.com/boltops-tools/jets/pull/648) make sure logger level info is default
|
19
|
+
- [#649](https://github.com/boltops-tools/jets/pull/649) Custom Domain: Hard fail on IAM permission error
|
20
|
+
- [#650](https://github.com/boltops-tools/jets/pull/650) Validate lambda function names
|
21
|
+
- [#651](https://github.com/boltops-tools/jets/pull/651) allow custom rake tasks with params to work with jets as well as rake command
|
22
|
+
- [#652](https://github.com/boltops-tools/jets/pull/652) Validate lambda function names: fix regexp
|
23
|
+
- [#653](https://github.com/boltops-tools/jets/pull/653) refactor cleanup: rename Jets::Naming to Jets::Names
|
24
|
+
- [#654](https://github.com/boltops-tools/jets/pull/654) Ruby 3.2 Support
|
25
|
+
- apigw routes state save: fix to_json infinite loop from Grape apps
|
26
|
+
- delete .python-version: more general approach. fixes specs when specific version of python is not installed
|
27
|
+
|
6
28
|
## [3.2.2] - 2023-05-19
|
7
29
|
- [#640](https://github.com/boltops-tools/jets/pull/640) Base path mapping CloudFormation custom resource and lambda function hardening
|
8
30
|
|
data/jets.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = "https://rubyonjets.com"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
|
-
spec.required_ruby_version = ['>= 2.5.0'
|
17
|
+
spec.required_ruby_version = ['>= 2.5.0']
|
18
18
|
spec.rdoc_options += Jets::Rdoc.options
|
19
19
|
|
20
20
|
vendor_files = Dir.glob("vendor/**/*")
|
@@ -51,6 +51,7 @@ class Jets::Application
|
|
51
51
|
config.autoload_paths = [] # allows for customization
|
52
52
|
config.ignore_paths = [] # allows for customization
|
53
53
|
config.logger = Jets::Logger.new($stderr)
|
54
|
+
config.logger.level = Logger::INFO
|
54
55
|
config.time_zone = "UTC"
|
55
56
|
|
56
57
|
# function properties defaults
|
@@ -162,6 +163,7 @@ class Jets::Application
|
|
162
163
|
|
163
164
|
config.ruby = ActiveSupport::OrderedOptions.new
|
164
165
|
config.ruby.check = true
|
166
|
+
config.ruby.supported_versions = %w[2.5 2.7 3.2] # supported by AWS Lambda
|
165
167
|
|
166
168
|
config
|
167
169
|
end
|
data/lib/jets/application.rb
CHANGED
@@ -163,13 +163,12 @@ class Jets::Application
|
|
163
163
|
staging: 'stag',
|
164
164
|
}
|
165
165
|
def set_computed_configs!
|
166
|
-
#
|
167
|
-
|
168
|
-
|
169
|
-
#
|
170
|
-
# Without env_extra: project-dev
|
166
|
+
# env var JETS_EXTRA higher precedence than config.extra
|
167
|
+
config.extra = Jets.extra
|
168
|
+
# IE: With extra: project-dev-1
|
169
|
+
# Without extra: project-dev
|
171
170
|
config.short_env = ENV_MAP[Jets.env.to_sym] || Jets.env
|
172
|
-
# table_namespace does not have the
|
171
|
+
# table_namespace does not have the extra, more common case desired.
|
173
172
|
config.table_namespace = [config.project_name, config.short_env].compact.join('-')
|
174
173
|
|
175
174
|
config.project_namespace = Jets.project_namespace
|
@@ -205,7 +204,7 @@ class Jets::Application
|
|
205
204
|
if File.exist?(database_yml)
|
206
205
|
require "active_record/database_configurations" # lazy require
|
207
206
|
text = Jets::Erb.result(database_yml)
|
208
|
-
db_configs =
|
207
|
+
db_configs = Jets::Util::Yamler.load(text)
|
209
208
|
configurations = ActiveRecord::DatabaseConfigurations.new(db_configs)
|
210
209
|
config.database = configurations
|
211
210
|
end
|
data/lib/jets/aws_info.rb
CHANGED
@@ -73,7 +73,7 @@ module Jets
|
|
73
73
|
return "fake-test-s3-bucket" if Jets.env.test?
|
74
74
|
return @@s3_bucket unless @@s3_bucket == BUCKET_DOES_NOT_YET_EXIST
|
75
75
|
|
76
|
-
resp = cfn.describe_stacks(stack_name: Jets::
|
76
|
+
resp = cfn.describe_stacks(stack_name: Jets::Names.parent_stack_name)
|
77
77
|
stack = resp.stacks.first
|
78
78
|
output = stack["outputs"].find { |o| o["output_key"] == "S3Bucket" }
|
79
79
|
@@s3_bucket = output["output_value"] # s3_bucket
|
@@ -83,7 +83,7 @@ module Jets
|
|
83
83
|
# not been loaded in the config yet. We do some trickery with loading
|
84
84
|
# the config twice in Application#load_app_config
|
85
85
|
# The first load will result in a Aws::CloudFormation::Errors::ValidationError
|
86
|
-
# since the Jets::
|
86
|
+
# since the Jets::Names.parent_stack_name has not been properly set yet.
|
87
87
|
#
|
88
88
|
# Rescuing all exceptions in case there are other exceptions dont know about yet
|
89
89
|
# Here are the known ones: Aws::CloudFormation::Errors::ValidationError, Aws::CloudFormation::Errors::InvalidClientTokenId
|
data/lib/jets/booter.rb
CHANGED
@@ -10,6 +10,7 @@ class Jets::Booter
|
|
10
10
|
Jets::Bundle.require
|
11
11
|
|
12
12
|
Jets.application.setup!
|
13
|
+
check_ruby_version!
|
13
14
|
|
14
15
|
# Turbines are loaded after setup_autoload_paths in Jets.application.setup! Some Turbine options are defined
|
15
16
|
# in the project so setup must happen before internal Turbines are loaded.
|
@@ -98,7 +99,7 @@ class Jets::Booter
|
|
98
99
|
primary_hash_config = ActiveRecord::Base.configurations.configs_for(env_name: Jets.env).find { |hash_config|
|
99
100
|
hash_config.name == "primary"
|
100
101
|
}
|
101
|
-
|
102
|
+
|
102
103
|
primary_config = primary_hash_config.configuration_hash # configuration_hash is a normal Ruby Hash
|
103
104
|
|
104
105
|
ActiveRecord::Base.establish_connection(primary_config)
|
@@ -174,5 +175,51 @@ class Jets::Booter
|
|
174
175
|
exit 1
|
175
176
|
end
|
176
177
|
end
|
178
|
+
|
179
|
+
def check_ruby_version!
|
180
|
+
return if ENV['JETS_RUBY_CHECK'] == '0'
|
181
|
+
return if !Jets.config.ruby.check
|
182
|
+
return if ruby_version_supported?
|
183
|
+
|
184
|
+
puts <<~EOL.color(:red)
|
185
|
+
You are using Ruby #{RUBY_VERSION}
|
186
|
+
AWS Lambda does not support this version.
|
187
|
+
Please use one of the supported Ruby versions: #{supported_ruby_versions.join(' ')}
|
188
|
+
EOL
|
189
|
+
|
190
|
+
puts <<~EOL
|
191
|
+
If you would like to skip this check, you can set: JETS_RUBY_CHECK=0 or configure
|
192
|
+
|
193
|
+
config/application.rb
|
194
|
+
|
195
|
+
Jets.application.configure do
|
196
|
+
config.ruby.check = false
|
197
|
+
end
|
198
|
+
|
199
|
+
Or if you want to allow additional Ruby versions, then configure:
|
200
|
+
|
201
|
+
config/application.rb
|
202
|
+
|
203
|
+
Jets.application.configure do
|
204
|
+
config.ruby.supported_versions = ["2.5", "2.7", "3.2"]
|
205
|
+
end
|
206
|
+
|
207
|
+
Note: If AWS Lambda does not officially support the Ruby version,
|
208
|
+
you'll need to also provide the Ruby Custom Runtime Layer.
|
209
|
+
Related Docs: https://rubyonjets.com/docs/extras/custom-runtime/
|
210
|
+
EOL
|
211
|
+
exit 1
|
212
|
+
end
|
213
|
+
|
214
|
+
def ruby_version_supported?
|
215
|
+
md = RUBY_VERSION.match(/(\d+)\.(\d+)\.\d+/)
|
216
|
+
major, minor = md[1], md[2]
|
217
|
+
detected_ruby = [major, minor].join('.')
|
218
|
+
supported_ruby_versions.include?(detected_ruby)
|
219
|
+
end
|
220
|
+
|
221
|
+
def supported_ruby_versions
|
222
|
+
Jets.config.ruby.supported_versions
|
223
|
+
end
|
177
224
|
end
|
178
225
|
end
|
@@ -26,7 +26,6 @@ module Jets::Builders
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def build
|
29
|
-
check_ruby_version
|
30
29
|
@version_purger.purge
|
31
30
|
cache_check_message
|
32
31
|
|
@@ -80,6 +79,7 @@ module Jets::Builders
|
|
80
79
|
return false if ENV['JETS_BUILD_NO_INTERNET']
|
81
80
|
s3_key = "jets/code/#{filename}"
|
82
81
|
begin
|
82
|
+
Jets.logger.debug "Checking s3://#{s3_bucket}/#{s3_key}"
|
83
83
|
s3.head_object(bucket: s3_bucket, key: s3_key)
|
84
84
|
true
|
85
85
|
rescue Aws::S3::Errors::NotFound, Aws::S3::Errors::Forbidden
|
@@ -355,7 +355,7 @@ module Jets::Builders
|
|
355
355
|
webpacker_yml = "#{"#{stage_area}/code"}/config/webpacker.yml"
|
356
356
|
return unless File.exist?(webpacker_yml)
|
357
357
|
|
358
|
-
config =
|
358
|
+
config = Jets::Util::Yamler.load_file(webpacker_yml)
|
359
359
|
config["development"]["compile"] = false # force this to be false for deployment
|
360
360
|
new_yaml = YAML.dump(config)
|
361
361
|
IO.write(webpacker_yml, new_yaml)
|
@@ -412,25 +412,6 @@ module Jets::Builders
|
|
412
412
|
FileUtils.cp_r(ruby_version_path, build_area)
|
413
413
|
end
|
414
414
|
|
415
|
-
SUPPORTED_RUBY_VERSIONS = %w[2.5 2.7]
|
416
|
-
def check_ruby_version
|
417
|
-
return unless ENV['JETS_RUBY_CHECK'] == '0' || Jets.config.ruby.check == false
|
418
|
-
return if ruby_version_supported?
|
419
|
-
puts <<~EOL.color(:red)
|
420
|
-
You are using Ruby version #{RUBY_VERSION} which is not supported by Jets.
|
421
|
-
Please use one of the Jets supported ruby versions: #{SUPPORTED_RUBY_VERSIONS.join(' ')}
|
422
|
-
If you would like to skip this check you can set: JETS_RUBY_CHECK=0
|
423
|
-
EOL
|
424
|
-
exit 1
|
425
|
-
end
|
426
|
-
|
427
|
-
def ruby_version_supported?
|
428
|
-
md = RUBY_VERSION.match(/(\d+)\.(\d+)\.\d+/)
|
429
|
-
major, minor = md[1], md[2]
|
430
|
-
detected_ruby = [major, minor].join('.')
|
431
|
-
SUPPORTED_RUBY_VERSIONS.include?(detected_ruby)
|
432
|
-
end
|
433
|
-
|
434
415
|
# Group all the path settings together here
|
435
416
|
def self.tmp_code
|
436
417
|
Jets::Commands::Build.tmp_code
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Jets::Builders
|
2
2
|
class GemReplacer
|
3
3
|
extend Memoist
|
4
|
+
include Util
|
5
|
+
|
4
6
|
def initialize(options)
|
5
7
|
@options = options
|
6
8
|
end
|
@@ -37,13 +39,6 @@ module Jets::Builders
|
|
37
39
|
FileUtils.mv(src, dest) unless File.exist?(dest) # looks like rename_gem actually runs twice
|
38
40
|
end
|
39
41
|
|
40
|
-
def sh(command)
|
41
|
-
puts "=> #{command}".color(:green)
|
42
|
-
success = system(command)
|
43
|
-
abort("Command Failed: #{command}") unless success
|
44
|
-
success
|
45
|
-
end
|
46
|
-
|
47
42
|
def ruby_folder
|
48
43
|
Jets::Gems.ruby_folder
|
49
44
|
end
|
@@ -3,9 +3,9 @@ require "bundler" # for clean_old_submodules only
|
|
3
3
|
module Jets::Builders
|
4
4
|
class RubyPackager
|
5
5
|
include Util
|
6
|
-
|
7
|
-
GEM_REGEXP = /-(arm|x)\d+.*-(darwin|linux)/
|
8
|
-
|
6
|
+
|
7
|
+
GEM_REGEXP = /-(arm|x)\d+.*-(darwin|linux)/
|
8
|
+
|
9
9
|
attr_reader :full_app_root
|
10
10
|
def initialize(relative_app_root)
|
11
11
|
@full_app_root = "#{build_area}/#{relative_app_root}"
|
@@ -16,6 +16,7 @@ module Jets::Builders
|
|
16
16
|
|
17
17
|
clean_old_submodules
|
18
18
|
bundle_install
|
19
|
+
bundle_check
|
19
20
|
copy_bundle_config
|
20
21
|
copy_cache_gems
|
21
22
|
end
|
@@ -75,7 +76,39 @@ module Jets::Builders
|
|
75
76
|
# For example we add the jets-rails to the Gemfile.
|
76
77
|
copy_back_gemfile_lock
|
77
78
|
|
78
|
-
puts 'Bundle install
|
79
|
+
puts 'Bundle install completed'
|
80
|
+
end
|
81
|
+
|
82
|
+
# Example `bundle check` error:
|
83
|
+
#
|
84
|
+
# The following gems are missing
|
85
|
+
# * date (3.3.3)
|
86
|
+
# * timeout (0.3.2)
|
87
|
+
# Install missing gems with `bundle install`
|
88
|
+
#
|
89
|
+
# Example success:
|
90
|
+
#
|
91
|
+
# The Gemfile's dependencies are satisfied
|
92
|
+
#
|
93
|
+
def bundle_check
|
94
|
+
out = ''
|
95
|
+
Bundler.with_unbundled_env do
|
96
|
+
out = `cd #{cache_area} && bundle check 2>&1`
|
97
|
+
end
|
98
|
+
if out.include?("missing")
|
99
|
+
puts "Failed: bundle check".color(:red)
|
100
|
+
puts <<~EOL
|
101
|
+
This means something went wrong with the bundle install.
|
102
|
+
Jets will prevent the deployment to AWS Lambda.
|
103
|
+
It's better to error now instead of finding out on AWS Lambda.
|
104
|
+
The bundle install can fail for different system-specific reasons.
|
105
|
+
It could be an outdated or incompatible version of RubyGems and Ruby.
|
106
|
+
|
107
|
+
Related: https://community.boltops.com/t/could-not-find-timeout-0-3-1-in-any-of-the-sources/996
|
108
|
+
|
109
|
+
EOL
|
110
|
+
exit 1
|
111
|
+
end
|
79
112
|
end
|
80
113
|
|
81
114
|
def copy_back_gemfile_lock
|
@@ -18,7 +18,7 @@ module Jets::Cfn::Builders
|
|
18
18
|
|
19
19
|
# template_path is an interface method
|
20
20
|
def template_path
|
21
|
-
Jets::
|
21
|
+
Jets::Names.api_gateway_template_path
|
22
22
|
end
|
23
23
|
|
24
24
|
# do not bother writing a template if routes are empty
|
@@ -55,7 +55,7 @@ module Jets::Cfn::Builders
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
def create_domain_name
|
58
|
+
def create_domain_name
|
59
59
|
resource = Jets::Resource::ApiGateway::DomainName.new
|
60
60
|
|
61
61
|
return {
|
@@ -70,41 +70,44 @@ module Jets::Cfn::Builders
|
|
70
70
|
apigateway.get_domain_name({
|
71
71
|
domain_name: resource.domain_name
|
72
72
|
})
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
true
|
74
|
+
# IE: Aws::APIGateway::Errors::NotFoundException Invalid domain name identifier specified
|
75
|
+
rescue Aws::APIGateway::Errors::NotFoundException
|
76
|
+
false
|
76
77
|
end
|
77
78
|
memoize :existing_domain_name?
|
78
79
|
|
79
80
|
def existing_domain_name_on_stack?
|
80
|
-
cfn.describe_stack_resource(
|
81
|
+
cfn.describe_stack_resource(
|
81
82
|
stack_name: api_gateway_physical_resource_id,
|
82
83
|
logical_resource_id: "DomainName"
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
)
|
85
|
+
true
|
86
|
+
# IE: Aws::CloudFormation::Errors::ValidationError (Resource DomainName does not exist for stack demo-dev)
|
87
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
88
|
+
false
|
87
89
|
end
|
88
90
|
|
89
91
|
def existing_dns_record_on_stack?
|
90
|
-
cfn.describe_stack_resource(
|
92
|
+
cfn.describe_stack_resource(
|
91
93
|
stack_name: api_gateway_physical_resource_id,
|
92
94
|
logical_resource_id: "DnsRecord"
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
95
|
+
)
|
96
|
+
true
|
97
|
+
# IE: Aws::CloudFormation::Errors::ValidationError (Resource DnsRecord does not exist for stack demo-dev)
|
98
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
99
|
+
false
|
97
100
|
end
|
98
101
|
|
99
102
|
def api_gateway_physical_resource_id
|
100
|
-
cfn.describe_stack_resource(
|
101
|
-
stack_name: Jets::
|
103
|
+
resp = cfn.describe_stack_resource(
|
104
|
+
stack_name: Jets::Names.parent_stack_name,
|
102
105
|
logical_resource_id: "ApiGateway"
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
rescue
|
107
|
-
|
106
|
+
)
|
107
|
+
resp&.stack_resource_detail&.physical_resource_id
|
108
|
+
# IE: Aws::CloudFormation::Errors::ValidationError (Resource ApiGateway does not exist for stack demo-dev)
|
109
|
+
rescue Aws::CloudFormation::Errors::ValidationError
|
110
|
+
nil
|
108
111
|
end
|
109
112
|
memoize :api_gateway_physical_resource_id
|
110
113
|
|
@@ -18,7 +18,7 @@ module Jets::Cfn::Builders
|
|
18
18
|
|
19
19
|
# template_path is an interface method for Interface module
|
20
20
|
def template_path
|
21
|
-
Jets::
|
21
|
+
Jets::Names.app_template_path(@app_class)
|
22
22
|
end
|
23
23
|
|
24
24
|
def add_common_parameters
|
@@ -40,6 +40,7 @@ module Jets::Cfn::Builders
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def add_functions
|
43
|
+
validate_function_names!
|
43
44
|
add_class_iam_policy
|
44
45
|
@app_class.tasks.each do |task|
|
45
46
|
add_function(task)
|
@@ -65,5 +66,23 @@ module Jets::Cfn::Builders
|
|
65
66
|
resource = Jets::Resource::Iam::FunctionRole.new(task)
|
66
67
|
add_resource(resource)
|
67
68
|
end
|
69
|
+
|
70
|
+
def validate_function_names!
|
71
|
+
invalids = @app_class.tasks.reject do |task|
|
72
|
+
task.meth.to_s =~ /^[a-zA-Z][a-zA-Z0-9_]/
|
73
|
+
end
|
74
|
+
return if invalids.empty?
|
75
|
+
list = invalids.map do |task|
|
76
|
+
" #{task.class_name}##{task.meth}" # IE: PostsController#index
|
77
|
+
end.join("\n")
|
78
|
+
puts "ERROR: Detected invalid AWS Lambda function names".color(:red)
|
79
|
+
puts <<~EOL
|
80
|
+
Lambda function names must start with a letter and can only contain letters, numbers, and underscores.
|
81
|
+
Invalid function names:
|
82
|
+
|
83
|
+
#{list}
|
84
|
+
EOL
|
85
|
+
exit 1
|
86
|
+
end
|
68
87
|
end
|
69
88
|
end
|
@@ -88,8 +88,27 @@ module Jets::Cfn::Builders
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
+
# Note: Jets::Resource::Iam classes are special treated. They are the only resources that result
|
92
|
+
# in creating 2 CloudFormation resources: Iam::Policy and Iam::Role.
|
93
|
+
# This allows the user to refer to the Lambda Function name in the IAM Policy itself.
|
94
|
+
# We need separate resources to avoid CloudFormation erroring with a circular dependency.
|
95
|
+
# Using separate IAM::Policy and IAM::Role resources allows us avoid the circular dependency error.
|
96
|
+
#
|
97
|
+
# Handling logic here also centralizes code for this special behavior.
|
98
|
+
# Also important to note, this does not change the user-facing interface.
|
99
|
+
# IE: Users still uses code like:
|
100
|
+
#
|
101
|
+
# iam_policy("s3", "sns")
|
102
|
+
#
|
103
|
+
# and be none-the-wiser about the special behavior.
|
91
104
|
def add_resource(resource)
|
92
105
|
add_template_resource(resource.logical_id, resource.type, resource.attributes)
|
106
|
+
|
107
|
+
if resource.class.to_s.include?("Jets::Resource::Iam")
|
108
|
+
role = resource # for clarity: resource is a Iam::*Role class
|
109
|
+
iam_policy = Jets::Resource::Iam::Policy.new(role)
|
110
|
+
add_template_resource(iam_policy.logical_id, iam_policy.type, iam_policy.attributes)
|
111
|
+
end
|
93
112
|
end
|
94
113
|
|
95
114
|
# The add_resource method can take an options Hash with both with either
|
@@ -19,7 +19,7 @@ module Jets::Cfn::Builders
|
|
19
19
|
|
20
20
|
# template_path is an interface method
|
21
21
|
def template_path
|
22
|
-
Jets::
|
22
|
+
Jets::Names.parent_template_path
|
23
23
|
end
|
24
24
|
|
25
25
|
def build_minimal_resources
|
@@ -90,7 +90,7 @@ module Jets::Cfn::Builders
|
|
90
90
|
# #{Jets.build_root}/templates/demo-dev-2-app-comments_controller.yml
|
91
91
|
# #{Jets.build_root}/templates/demo-dev-2-authorizers-main_authorizer.yml
|
92
92
|
def for_each_path(type)
|
93
|
-
expression = "#{Jets::
|
93
|
+
expression = "#{Jets::Names.template_path_prefix}-#{type}-*"
|
94
94
|
Dir.glob(expression).each do |path|
|
95
95
|
next unless File.file?(path)
|
96
96
|
yield(path)
|
@@ -123,7 +123,7 @@ module Jets::Cfn::Builders
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def add_api_resources
|
126
|
-
expression = "#{Jets::
|
126
|
+
expression = "#{Jets::Names.template_path_prefix}-api-resources-*"
|
127
127
|
# IE: path: #{Jets.build_root}/templates/demo-dev-2-api-resources-1.yml"
|
128
128
|
Dir.glob(expression).sort.each do |path|
|
129
129
|
next unless File.file?(path)
|
data/lib/jets/cfn/ship.rb
CHANGED
@@ -5,7 +5,7 @@ module Jets::Cfn
|
|
5
5
|
|
6
6
|
def initialize(options)
|
7
7
|
@options = options
|
8
|
-
@parent_stack_name = Jets::
|
8
|
+
@parent_stack_name = Jets::Names.parent_stack_name
|
9
9
|
end
|
10
10
|
|
11
11
|
def run
|
@@ -81,7 +81,7 @@ module Jets::Cfn
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def template
|
84
|
-
@template ||= TemplateSource.new(Jets::
|
84
|
+
@template ||= TemplateSource.new(Jets::Names.parent_template_path, @options)
|
85
85
|
end
|
86
86
|
|
87
87
|
# check for /(_COMPLETE|_FAILED)$/ status
|
data/lib/jets/cfn/status.rb
CHANGED
data/lib/jets/cfn/upload.rb
CHANGED
@@ -21,7 +21,7 @@ module Jets::Cfn
|
|
21
21
|
|
22
22
|
def upload_cfn_templates
|
23
23
|
puts "Uploading CloudFormation templates to S3."
|
24
|
-
expression = "#{Jets::
|
24
|
+
expression = "#{Jets::Names.template_path_prefix}-*"
|
25
25
|
Dir.glob(expression).each do |path|
|
26
26
|
next unless File.file?(path)
|
27
27
|
|
@@ -93,7 +93,7 @@ module Jets::Cfn
|
|
93
93
|
key = s3_key(full_path)
|
94
94
|
obj = s3_resource.bucket(bucket_name).object(key)
|
95
95
|
content_type = content_type_headers(full_path)
|
96
|
-
|
96
|
+
Jets.logger.debug "Uploading and setting content type for s3://#{bucket_name}/#{key} content_type #{content_type[:content_type].inspect}"
|
97
97
|
obj.upload_file(full_path, { acl: "public-read", cache_control: cache_control }.merge(content_type))
|
98
98
|
end
|
99
99
|
|
data/lib/jets/cli.rb
CHANGED
@@ -137,10 +137,16 @@ class Jets::CLI
|
|
137
137
|
end
|
138
138
|
|
139
139
|
return unless jets_project?
|
140
|
-
|
141
|
-
if rake_task_found
|
142
|
-
|
143
|
-
|
140
|
+
|
141
|
+
Jets::Commands::RakeCommand if rake_task_found
|
142
|
+
end
|
143
|
+
|
144
|
+
def rake_task_found
|
145
|
+
return false unless full_command # can be nil for subcommands and would break jets help without this check
|
146
|
+
bracket_regex = /\[.*/ # matches everything after the first [
|
147
|
+
command = full_command.sub(bracket_regex, '') # remove everything after the first [
|
148
|
+
namespaced_commands = Jets::Commands::RakeCommand.namespaced_commands.map {|x| x.sub(bracket_regex, '') }
|
149
|
+
namespaced_commands.include?(command)
|
144
150
|
end
|
145
151
|
|
146
152
|
def jets_project?
|
@@ -56,7 +56,7 @@ class Jets::Commands::Call
|
|
56
56
|
|
57
57
|
@@parent_stack = nil
|
58
58
|
def parent_stack
|
59
|
-
@@parent_stack ||= cfn.describe_stacks(stack_name: Jets::
|
59
|
+
@@parent_stack ||= cfn.describe_stacks(stack_name: Jets::Names.parent_stack_name).stacks.first
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# /aws/lambda/demo-dev-2-jets-preheat_job-warm
|
5
5
|
# /aws/lambda/demo-dev-2-jets-public_controller-show
|
6
6
|
#
|
7
|
-
# We're doing this because
|
7
|
+
# We're doing this because Jets.extra environments can create additional matching
|
8
8
|
# log groups and we don't want to overly-aggressively delete them.
|
9
9
|
#
|
10
10
|
# The `keep_prefixes(log_group_names)` method calcuates the log groups to keep.
|
@@ -49,7 +49,7 @@ class Jets::Commands::Clean
|
|
49
49
|
|
50
50
|
private
|
51
51
|
def prefix_guess
|
52
|
-
Jets::
|
52
|
+
Jets::Names.parent_stack_name
|
53
53
|
end
|
54
54
|
|
55
55
|
def log_groups
|
@@ -78,7 +78,7 @@ class Jets::Commands::Clean
|
|
78
78
|
|
79
79
|
# Check for the prefixes to keep. The slightly tricky thing to watch for is
|
80
80
|
# for the prefix matching addiitonal log groups that belong to other
|
81
|
-
#
|
81
|
+
# JETS_EXTRA=xxx created environments.
|
82
82
|
#
|
83
83
|
# We find and store the prefixes to keep so we don't over aggressively delete
|
84
84
|
# log groups.
|