aws_advanced_ruby_driver_wrapper 1.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 +7 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE +175 -0
- data/NOTICE +1 -0
- data/README.md +168 -0
- data/THIRD-PARTY-LICENSES +473 -0
- data/aws_advanced_ruby_driver_wrapper.gemspec +73 -0
- data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_mysql2_adapter.rb +73 -0
- data/lib/aws_advanced_ruby_driver_wrapper/active_record/aws_postgresql_adapter.rb +95 -0
- data/lib/aws_advanced_ruby_driver_wrapper/custom_configuration.rb +58 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/aurora_mysql_dialect.rb +103 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/aurora_pg_dialect.rb +124 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/dialect_codes.rb +38 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/global_mysql_dialect.rb +91 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/global_pg_dialect.rb +92 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/multi_az_cluster_mysql_dialect.rb +95 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/multi_az_cluster_pg_dialect.rb +86 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/mysql_dialect.rb +98 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/pg_dialect.rb +95 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/rds_mysql_dialect.rb +88 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/rds_pg_dialect.rb +86 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/unknown_dialect.rb +72 -0
- data/lib/aws_advanced_ruby_driver_wrapper/db_dialects/utils/dialect_utils.rb +71 -0
- data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/driver_dialect.rb +154 -0
- data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/driver_dialect_manager.rb +55 -0
- data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/mysql_driver_dialect.rb +165 -0
- data/lib/aws_advanced_ruby_driver_wrapper/driver_dialects/pg_driver_dialect.rb +201 -0
- data/lib/aws_advanced_ruby_driver_wrapper/errors/error_handler.rb +62 -0
- data/lib/aws_advanced_ruby_driver_wrapper/errors/mysql_error_handler.rb +80 -0
- data/lib/aws_advanced_ruby_driver_wrapper/errors/pg_error_handler.rb +126 -0
- data/lib/aws_advanced_ruby_driver_wrapper/errors.rb +59 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/connection_string_host_list_provider.rb +95 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/global_aurora_host_list_provider.rb +65 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/host_availability.rb +24 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/host_availability_strategy.rb +27 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/host_info.rb +137 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/host_role.rb +25 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/random_host_selector.rb +40 -0
- data/lib/aws_advanced_ruby_driver_wrapper/host/rds_host_list_provider.rb +206 -0
- data/lib/aws_advanced_ruby_driver_wrapper/logging.rb +110 -0
- data/lib/aws_advanced_ruby_driver_wrapper/monitoring/cluster_topology_monitor.rb +709 -0
- data/lib/aws_advanced_ruby_driver_wrapper/monitoring/global_cluster_topology_monitor.rb +72 -0
- data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor.rb +99 -0
- data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor_connection.rb +57 -0
- data/lib/aws_advanced_ruby_driver_wrapper/monitoring/monitor_state.rb +25 -0
- data/lib/aws_advanced_ruby_driver_wrapper/mysql.rb +429 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/blue_green_plugin.rb +205 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/host_mapper.rb +132 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/iam_host_tracker.rb +84 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/interim_status.rb +92 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/interval_rate.rb +27 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/phase.rb +69 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/phase_event_log.rb +85 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/phase_time_info.rb +25 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/role.rb +38 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/base_routing.rb +83 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/reject_connect_routing.rb +40 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/substitute_connect_routing.rb +136 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_connect_routing.rb +53 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_execute_routing.rb +52 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/routing/suspend_until_corresponding_host_found_connect_routing.rb +83 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status.rb +68 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_builder.rb +244 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_info.rb +30 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_monitor.rb +564 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/status_provider.rb +414 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/switchover_state.rb +98 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/blue_green/switchover_timer.rb +46 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/custom_endpoint_monitor.rb +266 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/custom_endpoint_plugin.rb +158 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/info.rb +111 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/member_list_type.rb +31 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/custom_endpoint/role.rb +45 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/default_plugin.rb +108 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/failover_mode.rb +43 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/failover_plugin.rb +467 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/gdb/gdb_failover_mode.rb +68 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/gdb/gdb_failover_plugin.rb +403 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/iam_auth_plugin.rb +159 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/initial_connection_strategy_plugin.rb +485 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/audit_logger.rb +157 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/column_cipher.rb +159 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/column_encryption_config.rb +61 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/connection_source.rb +91 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/data_key_cache.rb +220 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/encryption_algorithm.rb +75 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/encryption_config.rb +146 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/encryption_service.rb +391 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/error_context.rb +198 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/errors.rb +259 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_management_utility.rb +435 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_manager.rb +378 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/key_metadata.rb +86 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/kms_encryption_plugin.rb +890 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/kms_encryption_utility.rb +281 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/metadata_manager.rb +332 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/sanitizer.rb +147 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/schema_name.rb +70 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/schema_validator.rb +211 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/sql_runner.rb +147 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/kms_encryption/type_marker.rb +109 -0
- data/lib/aws_advanced_ruby_driver_wrapper/plugins/secrets_manager_plugin.rb +358 -0
- data/lib/aws_advanced_ruby_driver_wrapper/postgresql.rb +659 -0
- data/lib/aws_advanced_ruby_driver_wrapper/property_definition.rb +409 -0
- data/lib/aws_advanced_ruby_driver_wrapper/ruby_method.rb +122 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/connection_service.rb +143 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/dialect_service.rb +267 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/host_service.rb +199 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/monitor_service.rb +186 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/plugin_call_context.rb +63 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/plugin_manager.rb +273 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/service_container.rb +30 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/service_utility.rb +78 -0
- data/lib/aws_advanced_ruby_driver_wrapper/services/session_state_service.rb +56 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/accessible_regions.rb +52 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/ar_constants.rb +25 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/aurora_topology_utils.rb +99 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/aws_credentials_utils.rb +62 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/connection_config.rb +91 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/connection_config_parser.rb +368 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/conversion_utils.rb +51 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/events/batching_event_publisher.rb +119 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/events/data_access_event.rb +26 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/events/monitor_reset_event.rb +26 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/global_aurora_topology_utils.rb +185 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/host_list_utils.rb +27 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/iam_auth_utils.rb +112 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/multi_az_topology_utils.rb +117 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/encryption_annotation_parser.rb +99 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/mysql_statement_analyzer.rb +641 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/pg_statement_analyzer.rb +502 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/query_analysis.rb +63 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/query_type.rb +35 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/routing_hint.rb +27 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/routing_hint_parser.rb +50 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/parser/sql_parser.rb +139 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/rds_url_type.rb +71 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/rds_utils.rb +575 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/retry_util.rb +153 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/sql_encoding.rb +56 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/sql_method_analyzer.rb +195 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/cache_entry.rb +56 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/expiration_cache.rb +108 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/sliding_expiration_cache.rb +137 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/storage/storage_service.rb +172 -0
- data/lib/aws_advanced_ruby_driver_wrapper/utils/topology_utils.rb +127 -0
- data/lib/aws_advanced_ruby_driver_wrapper/version.rb +19 -0
- data/lib/aws_advanced_ruby_driver_wrapper/wrapper_property.rb +64 -0
- data/lib/aws_advanced_ruby_driver_wrapper.rb +116 -0
- metadata +227 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License").
|
|
6
|
+
# You may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
require_relative '../../host/host_info'
|
|
18
|
+
require_relative '../../utils/rds_utils'
|
|
19
|
+
require_relative 'phase'
|
|
20
|
+
require_relative 'role'
|
|
21
|
+
require_relative 'routing/base_routing'
|
|
22
|
+
require_relative 'routing/substitute_connect_routing'
|
|
23
|
+
require_relative 'routing/reject_connect_routing'
|
|
24
|
+
require_relative 'routing/suspend_connect_routing'
|
|
25
|
+
require_relative 'routing/suspend_execute_routing'
|
|
26
|
+
require_relative 'routing/suspend_until_corresponding_host_found_connect_routing'
|
|
27
|
+
|
|
28
|
+
module AwsAdvancedRubyDriverWrapper
|
|
29
|
+
module Plugins
|
|
30
|
+
module BlueGreen
|
|
31
|
+
# Constructs the appropriate Status object for each Blue/Green phase.
|
|
32
|
+
# Each method encodes the routing rules that apply during that phase:
|
|
33
|
+
# created — no routing; normal connect/execute behaviour.
|
|
34
|
+
# preparation — blue connects routed to their IP addresses to avoid stale DNS.
|
|
35
|
+
# in_progress — all blue/green connects and executes suspended.
|
|
36
|
+
# post — blue connects redirected to corresponding green hosts; green connects rerouted to IPs.
|
|
37
|
+
# completed — no routing; normal behaviour resumes.
|
|
38
|
+
# If the switchover timer has expired, falls back to created (rollback) or completed.
|
|
39
|
+
class StatusBuilder
|
|
40
|
+
def initialize(bgd_id, host_mapper, timer, interim_statuses, iam_tracker, switchover_state)
|
|
41
|
+
@bgd_id = bgd_id
|
|
42
|
+
@host_mapper = host_mapper
|
|
43
|
+
@timer = timer
|
|
44
|
+
@interim_statuses = interim_statuses
|
|
45
|
+
@iam_tracker = iam_tracker
|
|
46
|
+
@switchover_state = switchover_state
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def created
|
|
50
|
+
Status.new(@bgd_id, Phase::CREATED,
|
|
51
|
+
connect_routing: [],
|
|
52
|
+
execute_routing: [],
|
|
53
|
+
role_by_host: @host_mapper.role_by_host,
|
|
54
|
+
corresponding_hosts: @host_mapper.corresponding_hosts)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# BGD reports COMPLETED. If DNS hasn't fully propagated yet, delegates to post.
|
|
58
|
+
# Clears corresponding_hosts once DNS is confirmed settled.
|
|
59
|
+
def completed(rollback)
|
|
60
|
+
if @timer.expired?
|
|
61
|
+
return created if rollback
|
|
62
|
+
|
|
63
|
+
return Status.new(@bgd_id, Phase::COMPLETED,
|
|
64
|
+
connect_routing: [],
|
|
65
|
+
execute_routing: [],
|
|
66
|
+
role_by_host: @host_mapper.role_by_host,
|
|
67
|
+
corresponding_hosts: @host_mapper.corresponding_hosts)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
return post(rollback) unless @switchover_state.blue_dns_update_completed && @switchover_state.green_dns_removed
|
|
71
|
+
|
|
72
|
+
Status.new(@bgd_id, Phase::COMPLETED,
|
|
73
|
+
connect_routing: [],
|
|
74
|
+
execute_routing: [],
|
|
75
|
+
role_by_host: @host_mapper.role_by_host,
|
|
76
|
+
corresponding_hosts: {})
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# POST phase: blue connects are redirected to green hosts (or suspended until a green host is found).
|
|
80
|
+
# Green connects are rerouted to IPs (topology not yet updated) or rejected (DNS removed).
|
|
81
|
+
def post(rollback)
|
|
82
|
+
return (rollback ? created : completed(rollback)) if @timer.expired?
|
|
83
|
+
|
|
84
|
+
Status.new(@bgd_id, Phase::POST,
|
|
85
|
+
connect_routing: post_connect_routing,
|
|
86
|
+
execute_routing: [],
|
|
87
|
+
role_by_host: @host_mapper.role_by_host,
|
|
88
|
+
corresponding_hosts: @host_mapper.corresponding_hosts)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# IN_PROGRESS: all blue/green connects and executes are suspended.
|
|
92
|
+
# IP-addressed connections to known blue/green IPs are also suspended.
|
|
93
|
+
def in_progress(rollback)
|
|
94
|
+
return (rollback ? created : completed(rollback)) if @timer.expired?
|
|
95
|
+
|
|
96
|
+
connect_routing = [
|
|
97
|
+
Routing::SuspendConnectRouting.new(nil, nil, Role::SOURCE, @bgd_id),
|
|
98
|
+
Routing::SuspendConnectRouting.new(nil, nil, Role::TARGET, @bgd_id)
|
|
99
|
+
]
|
|
100
|
+
execute_routing = [
|
|
101
|
+
Routing::SuspendExecuteRouting.new(nil, nil, Role::SOURCE, @bgd_id),
|
|
102
|
+
Routing::SuspendExecuteRouting.new(nil, nil, Role::TARGET, @bgd_id)
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
ip_connect, ip_execute = @host_mapper.host_ip_addresses.values.compact.uniq
|
|
106
|
+
.each_with_object([[], []]) do |ip, (ic, ie)|
|
|
107
|
+
matched = [Role::SOURCE, Role::TARGET].find do |r|
|
|
108
|
+
interim = @interim_statuses[r]
|
|
109
|
+
interim && interim.start_ip_addresses_by_host.values.compact.include?(ip)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
if matched
|
|
113
|
+
interim = @interim_statuses[matched]
|
|
114
|
+
port = interim.port.positive? ? interim.port : nil
|
|
115
|
+
ic << Routing::SuspendConnectRouting.new(ip, nil, nil, @bgd_id)
|
|
116
|
+
ic << Routing::SuspendConnectRouting.new(ip, port, nil, @bgd_id)
|
|
117
|
+
ie << Routing::SuspendExecuteRouting.new(ip, nil, nil, @bgd_id)
|
|
118
|
+
ie << Routing::SuspendExecuteRouting.new(ip, port, nil, @bgd_id)
|
|
119
|
+
else
|
|
120
|
+
ie << Routing::SuspendExecuteRouting.new(ip, nil, nil, @bgd_id)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
Status.new(@bgd_id, Phase::IN_PROGRESS,
|
|
125
|
+
connect_routing: connect_routing + ip_connect,
|
|
126
|
+
execute_routing: execute_routing + ip_execute,
|
|
127
|
+
role_by_host: @host_mapper.role_by_host,
|
|
128
|
+
corresponding_hosts: @host_mapper.corresponding_hosts)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# PREPARATION: blue connects are routed to their current IP addresses to avoid
|
|
132
|
+
# stale DNS resolving to the wrong host during the upcoming switchover.
|
|
133
|
+
def preparation(rollback)
|
|
134
|
+
return (rollback ? created : completed(rollback)) if @timer.expired?
|
|
135
|
+
|
|
136
|
+
Status.new(@bgd_id, Phase::PREPARATION,
|
|
137
|
+
connect_routing: substitute_blue_with_ip_routing,
|
|
138
|
+
execute_routing: [],
|
|
139
|
+
role_by_host: @host_mapper.role_by_host,
|
|
140
|
+
corresponding_hosts: @host_mapper.corresponding_hosts)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
private
|
|
144
|
+
|
|
145
|
+
def post_connect_routing
|
|
146
|
+
routing = []
|
|
147
|
+
append_source_post_routing(routing)
|
|
148
|
+
append_target_post_routing(routing)
|
|
149
|
+
routing
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Builds source-side POST routing: redirects blue connects to corresponding green hosts.
|
|
153
|
+
# If the green host isn't found yet, suspends until it appears.
|
|
154
|
+
# Skipped once blue DNS has fully updated and all green hosts have changed their IAM name.
|
|
155
|
+
def append_source_post_routing(routing)
|
|
156
|
+
return if @switchover_state.blue_dns_update_completed || @iam_tracker.all_changed?
|
|
157
|
+
|
|
158
|
+
@host_mapper.role_by_host.each do |blue_host, role|
|
|
159
|
+
next if role != Role::SOURCE
|
|
160
|
+
next unless @host_mapper.corresponding_hosts.key?(blue_host)
|
|
161
|
+
|
|
162
|
+
host_pair = @host_mapper.corresponding_hosts[blue_host]
|
|
163
|
+
green_host_spec = host_pair&.[](1)
|
|
164
|
+
interim_status = @interim_statuses[role]
|
|
165
|
+
port = interim_status&.port&.positive? ? interim_status.port : nil
|
|
166
|
+
is_instance = Utils::RdsUtils.rds_instance?(blue_host)
|
|
167
|
+
|
|
168
|
+
if green_host_spec.nil?
|
|
169
|
+
routing << Routing::SuspendUntilCorrespondingHostFoundConnectRouting.new(blue_host, nil, role, @bgd_id)
|
|
170
|
+
routing << Routing::SuspendUntilCorrespondingHostFoundConnectRouting.new(blue_host, port, role, @bgd_id) if port
|
|
171
|
+
else
|
|
172
|
+
green_host = green_host_spec.host
|
|
173
|
+
green_ip = @host_mapper.host_ip_addresses[green_host]
|
|
174
|
+
green_with_ip = green_ip ? Host::HostInfo.new(host: green_ip, port: green_host_spec.port,
|
|
175
|
+
role: green_host_spec.role) : green_host_spec
|
|
176
|
+
iam_blue_host = Host::HostInfo.new(host: Utils::RdsUtils.remove_green_instance_prefix(green_host),
|
|
177
|
+
port: green_host_spec.port, role: green_host_spec.role)
|
|
178
|
+
iam_hosts = @iam_tracker.connected?(green_host, iam_blue_host.host) ? [iam_blue_host] : [green_host_spec, iam_blue_host]
|
|
179
|
+
notify = is_instance ? ->(h) { @iam_tracker.register(green_host, h) } : nil
|
|
180
|
+
|
|
181
|
+
routing << Routing::SubstituteConnectRouting.new(blue_host, nil, role, green_with_ip, iam_hosts, notify)
|
|
182
|
+
routing << Routing::SubstituteConnectRouting.new(blue_host, port, role, green_with_ip, iam_hosts, notify) if port
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Builds target-side POST routing:
|
|
188
|
+
# - If green topology hasn't changed yet, reroutes green connects to their IP addresses.
|
|
189
|
+
# - If green topology changed but DNS isn't removed yet, rejects new green connects.
|
|
190
|
+
def append_target_post_routing(routing)
|
|
191
|
+
if !@switchover_state.green_topology_changed
|
|
192
|
+
@host_mapper.role_by_host.each do |green_host, role|
|
|
193
|
+
next if role != Role::TARGET
|
|
194
|
+
|
|
195
|
+
blue_host = Utils::RdsUtils.remove_green_instance_prefix(green_host)
|
|
196
|
+
interim_status = @interim_statuses[role]
|
|
197
|
+
port = interim_status&.port&.positive? ? interim_status.port : nil
|
|
198
|
+
is_instance = Utils::RdsUtils.rds_instance?(green_host)
|
|
199
|
+
|
|
200
|
+
blue_host_spec = Host::HostInfo.new(host: blue_host, **({ port: port } if port).to_h)
|
|
201
|
+
green_host_spec = Host::HostInfo.new(host: green_host, **({ port: port } if port).to_h)
|
|
202
|
+
green_ip = @host_mapper.host_ip_addresses[green_host]
|
|
203
|
+
green_with_ip = green_ip ? Host::HostInfo.new(host: green_ip,
|
|
204
|
+
**({ port: port } if port).to_h) : Host::HostInfo.new(host: green_host)
|
|
205
|
+
iam_hosts = @iam_tracker.connected?(green_host, blue_host) ? [blue_host_spec] : [green_host_spec, blue_host_spec]
|
|
206
|
+
notify = is_instance ? ->(h) { @iam_tracker.register(green_host, h) } : nil
|
|
207
|
+
|
|
208
|
+
routing << Routing::SubstituteConnectRouting.new(green_host, nil, role, green_with_ip, iam_hosts, notify)
|
|
209
|
+
routing << Routing::SubstituteConnectRouting.new(green_host, port, role, green_with_ip, iam_hosts, notify) if port
|
|
210
|
+
end
|
|
211
|
+
elsif !@switchover_state.green_dns_removed
|
|
212
|
+
routing << Routing::RejectConnectRouting.new(nil, nil, Role::TARGET)
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Builds PREPARATION routing: substitutes blue hostname connects with their resolved IP
|
|
217
|
+
# addresses so connections bypass DNS during the switchover window.
|
|
218
|
+
def substitute_blue_with_ip_routing
|
|
219
|
+
@host_mapper.role_by_host.flat_map do |host, role|
|
|
220
|
+
next [] if role != Role::SOURCE
|
|
221
|
+
|
|
222
|
+
host_pair = @host_mapper.corresponding_hosts[host]
|
|
223
|
+
next [] if host_pair.nil?
|
|
224
|
+
|
|
225
|
+
blue_host_spec = host_pair[0]
|
|
226
|
+
blue_ip_entry = @host_mapper.host_ip_addresses[blue_host_spec.host]
|
|
227
|
+
blue_ip_host_spec = blue_ip_entry ? Host::HostInfo.new(host: blue_ip_entry, port: blue_host_spec.port,
|
|
228
|
+
role: blue_host_spec.role) : blue_host_spec
|
|
229
|
+
|
|
230
|
+
entries = [Routing::SubstituteConnectRouting.new(host, nil, role, blue_ip_host_spec, [blue_host_spec], nil)]
|
|
231
|
+
|
|
232
|
+
interim_status = @interim_statuses[role]
|
|
233
|
+
if interim_status
|
|
234
|
+
port = interim_status.port.positive? ? interim_status.port : nil
|
|
235
|
+
entries << Routing::SubstituteConnectRouting.new(host, port, role, blue_ip_host_spec, [blue_host_spec], nil) if port
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
entries
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License").
|
|
6
|
+
# You may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
require_relative 'phase'
|
|
18
|
+
require_relative 'role'
|
|
19
|
+
|
|
20
|
+
module AwsAdvancedRubyDriverWrapper
|
|
21
|
+
module Plugins
|
|
22
|
+
module BlueGreen
|
|
23
|
+
StatusInfo = Struct.new(:version, :endpoint, :port, :phase, :role) do
|
|
24
|
+
def to_s
|
|
25
|
+
"StatusInfo [version: #{version}, endpoint: #{endpoint}, port: #{port}, phase: #{phase}, role: #{role}]"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|