forked from rubyonjets/jets
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
paginate api gateway resources to support more routes
* update route change detection to account for pagination
- Loading branch information
Showing
25 changed files
with
541 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
module Jets::Cfn::Builders | ||
class ApiResourcesBuilder | ||
include Interface | ||
include Jets::AwsServices | ||
|
||
def initialize(options={}, paths=[], page) | ||
@options, @paths, @page = options, paths, page | ||
@template = ActiveSupport::HashWithIndifferentAccess.new(Resources: {}) | ||
end | ||
|
||
# compose is an interface method | ||
def compose | ||
return unless @options[:templates] || @options[:stack_type] != :minimal | ||
|
||
add_rest_api_parameter | ||
add_gateway_routes | ||
end | ||
|
||
# template_path is an interface method | ||
def template_path | ||
Jets::Naming.api_resources_template_path(@page) | ||
end | ||
|
||
def add_rest_api_parameter | ||
add_parameter("RestApi", Description: "RestApi") | ||
end | ||
|
||
def add_gateway_routes | ||
@paths.each do |path| | ||
homepage = path == '' | ||
next if homepage # handled by RootResourceId output already | ||
|
||
resource = Jets::Resource::ApiGateway::Resource.new(path) | ||
add_resource(resource) | ||
add_outputs(resource.outputs) | ||
|
||
parent_path = resource.parent_path_parameter | ||
add_parameter(parent_path) unless part_of_template?(parent_path) | ||
end | ||
end | ||
|
||
def part_of_template?(parent_path) | ||
@template["Resources"].key?(parent_path) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module Jets::Cfn | ||
# Caches the built template to reduce filesystem IO calls. | ||
class BuiltTemplate | ||
class << self | ||
@@cache = {} | ||
def get(path) | ||
if @@cache[path] | ||
@@cache[path] # using cache | ||
else | ||
@@cache[path] = YAML.load_file(path) # setting and using cache | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,16 @@ | ||
# Detects route changes | ||
class Jets::Resource::ApiGateway::RestApi::Routes | ||
class Change | ||
include Jets::AwsServices | ||
|
||
def changed? | ||
To.changed? || Variable.changed? || ENV['JETS_REPLACE_API'] | ||
return false unless parent_stack_exists? | ||
|
||
MediaTypes.changed? || To.changed? || Variable.changed? || Page.changed? || ENV['JETS_REPLACE_API'] | ||
end | ||
|
||
def parent_stack_exists? | ||
stack_exists?(Jets::Naming.parent_stack_name) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
lib/jets/resource/api_gateway/rest_api/routes/change/media_types.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
class Jets::Resource::ApiGateway::RestApi::Routes::Change | ||
class MediaTypes < Base | ||
def changed? | ||
current_binary_media_types != new_binary_media_types | ||
end | ||
|
||
def new_binary_media_types | ||
rest_api = Jets::Resource::ApiGateway::RestApi.new | ||
rest_api.binary_media_types | ||
end | ||
memoize :new_binary_media_types | ||
|
||
def current_binary_media_types | ||
return nil unless parent_stack_exists? | ||
|
||
stack = cfn.describe_stacks(stack_name: parent_stack_name).stacks.first | ||
|
||
api_gateway_stack_arn = lookup(stack[:outputs], "ApiGateway") | ||
|
||
stack = cfn.describe_stacks(stack_name: api_gateway_stack_arn).stacks.first | ||
rest_api_id = lookup(stack[:outputs], "RestApi") | ||
|
||
resp = apigateway.get_rest_api(rest_api_id: rest_api_id) | ||
resp.binary_media_types | ||
end | ||
memoize :current_binary_media_types | ||
|
||
def parent_stack_exists? | ||
stack_exists?(parent_stack_name) | ||
end | ||
|
||
def parent_stack_name | ||
Jets::Naming.parent_stack_name | ||
end | ||
end | ||
end |
93 changes: 93 additions & 0 deletions
93
lib/jets/resource/api_gateway/rest_api/routes/change/page.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
class Jets::Resource::ApiGateway::RestApi::Routes::Change | ||
class Page < Base | ||
def changed? | ||
route_page_moved? || old_api_template? | ||
end | ||
|
||
def route_page_moved? | ||
moved?(new_pages, deployed_pages) | ||
end | ||
|
||
# Routes page to logical ids | ||
def moved?(new_pages, deployed_pages) | ||
not_moved = true # page has not moved | ||
new_pages.each do |logical_id, new_page_number| | ||
if !deployed_pages[logical_id].nil? && deployed_pages[logical_id] != new_page_number | ||
not_moved = false # page has moved | ||
break | ||
end | ||
end | ||
!not_moved # moved | ||
end | ||
|
||
def new_pages | ||
local_logical_ids_map | ||
end | ||
memoize :new_pages | ||
|
||
def deployed_pages | ||
remote_logical_ids_map | ||
end | ||
memoize :deployed_pages | ||
|
||
# logical id to page map | ||
# Important: In Cfn::Builders::ApiGatewayBuilder, the add_gateway_routes and ApiResourcesBuilder needs to run | ||
# before the parent add_gateway_rest_api method. | ||
def local_logical_ids_map(path_expression="#{Jets::Naming.template_path_prefix}-api-resources-*.yml") | ||
logical_ids = {} # logical id => page number | ||
|
||
Dir.glob(path_expression).each do |path| | ||
md = path.match(/-api-resources-(\d+).yml/) | ||
page_number = md[1] | ||
|
||
template = Jets::Cfn::BuiltTemplate.get(path) | ||
template['Resources'].keys.each do |logical_id| | ||
logical_ids[logical_id] = page_number | ||
end | ||
end | ||
|
||
logical_ids | ||
end | ||
|
||
# aws cloudformation describe-stack-resources --stack-name demo-dev-ApiResources1-DYGLIEY3VAWT | jq -r '.StackResources[].LogicalResourceId' | ||
def remote_logical_ids_map | ||
logical_ids = {} # logical id => page number | ||
|
||
parent_resources.each do |resource| | ||
stack_name = resource.physical_resource_id # full physical id can be used as stack name also | ||
regexp = Regexp.new("#{Jets.config.project_namespace}-ApiResources(\\d+)-") # tricky to escape \d pattern | ||
md = stack_name.match(regexp) | ||
if md | ||
page_number = md[1] | ||
|
||
resp = cfn.describe_stack_resources(stack_name: stack_name) | ||
resp.stack_resources.map(&:logical_resource_id).each do |logical_id| | ||
logical_ids[logical_id] = page_number | ||
end | ||
end | ||
end | ||
|
||
logical_ids | ||
end | ||
|
||
def old_api_template? | ||
logical_resource_ids = parent_resources.map(&:logical_resource_id) | ||
|
||
api_gateway_found = logical_resource_ids.detect do |logical_id| | ||
logical_id == "ApiGateway" | ||
end | ||
return false unless api_gateway_found | ||
|
||
api_resources_found = logical_resource_ids.detect do |logical_id| | ||
logical_id.match(/^ApiResources\d+$/) | ||
end | ||
!api_resources_found # if api_resources_found then it's the new structure. so opposite is old structure | ||
end | ||
|
||
def parent_resources | ||
resp = cfn.describe_stack_resources(stack_name: Jets::Naming.parent_stack_name) | ||
resp.stack_resources | ||
end | ||
memoize :parent_resources | ||
end | ||
end |
Oops, something went wrong.