jets 3.2.1 → 4.0.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 +4 -4
- data/CHANGELOG.md +21 -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/functions/jets/base_path.rb +93 -3
- data/lib/jets/internal/app/functions/jets/base_path_mapping.rb +65 -6
- data/lib/jets/internal/app/jobs/jets/preheat_job.rb +6 -2
- data/lib/jets/lambda/dsl.rb +6 -1
- 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/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: 557e01dec1b92f8a04213ef4b7f5ee9d8a35f25dd20231c96ba24b0d9890b7cd
|
4
|
+
data.tar.gz: 5c8c12ae959d76dc9e5a681c8f18a40d5d60defcc4eead52ed9d9ad2571a3fe1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 944a1d09ba4da26110e292cdf42d73a240d283d066dbe1ca677787c20b03ee925cf12e3d92555bc16e6327c7096ce59782cd271ff802f5d8554819674f040020
|
7
|
+
data.tar.gz: 987eac8ef96a9cc10b0ac071ff099c02245cf5143bb75d23622513aba73ba447414ab0c542f7a734c30ba6ce07f20cd479daecc030c02d9a5d3505c10c0a5c34
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,27 @@
|
|
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.0] - 2023-05-27
|
7
|
+
- [#641](https://github.com/boltops-tools/jets/pull/641) bundle check and prevent error from getting to aws lambda
|
8
|
+
- [#642](https://github.com/boltops-tools/jets/pull/642) Fix rack mounted apps: update interface with removed meth
|
9
|
+
- [#643](https://github.com/boltops-tools/jets/pull/643) JETS_EXTRA support, deprecate JETS_ENV_EXTRA
|
10
|
+
- [#644](https://github.com/boltops-tools/jets/pull/644) remove docs to separate repo
|
11
|
+
- [#645](https://github.com/boltops-tools/jets/pull/645) PreheatJob: fix function lookups and iam function permission
|
12
|
+
- [#646](https://github.com/boltops-tools/jets/pull/646) log debug uploading and setting content type
|
13
|
+
- [#647](https://github.com/boltops-tools/jets/pull/647) fix Jets.logger call
|
14
|
+
- [#648](https://github.com/boltops-tools/jets/pull/648) make sure logger level info is default
|
15
|
+
- [#649](https://github.com/boltops-tools/jets/pull/649) Custom Domain: Hard fail on IAM permission error
|
16
|
+
- [#650](https://github.com/boltops-tools/jets/pull/650) Validate lambda function names
|
17
|
+
- [#651](https://github.com/boltops-tools/jets/pull/651) allow custom rake tasks with params to work with jets as well as rake command
|
18
|
+
- [#652](https://github.com/boltops-tools/jets/pull/652) Validate lambda function names: fix regexp
|
19
|
+
- [#653](https://github.com/boltops-tools/jets/pull/653) refactor cleanup: rename Jets::Naming to Jets::Names
|
20
|
+
- [#654](https://github.com/boltops-tools/jets/pull/654) Ruby 3.2 Support
|
21
|
+
- apigw routes state save: fix to_json infinite loop from Grape apps
|
22
|
+
- delete .python-version: more general approach. fixes specs when specific version of python is not installed
|
23
|
+
|
24
|
+
## [3.2.2] - 2023-05-19
|
25
|
+
- [#640](https://github.com/boltops-tools/jets/pull/640) Base path mapping CloudFormation custom resource and lambda function hardening
|
26
|
+
|
6
27
|
## [3.2.1] - 2023-05-03
|
7
28
|
- [#637](https://github.com/boltops-tools/jets/pull/637) Readme: Replace "splat out" with "had" a baby
|
8
29
|
- [#638](https://github.com/boltops-tools/jets/pull/638) feature: update an array of reserved variables in aws lambda
|
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.
|