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,206 @@
|
|
|
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 'concurrent'
|
|
18
|
+
require_relative '../logging'
|
|
19
|
+
require_relative '../errors'
|
|
20
|
+
require_relative '../property_definition'
|
|
21
|
+
require_relative '../utils/rds_utils'
|
|
22
|
+
require_relative '../utils/rds_url_type'
|
|
23
|
+
require_relative 'host_info'
|
|
24
|
+
require_relative '../monitoring/cluster_topology_monitor'
|
|
25
|
+
|
|
26
|
+
module AwsAdvancedRubyDriverWrapper
|
|
27
|
+
module Host
|
|
28
|
+
# Dynamic host list provider for RDS/Aurora clusters.
|
|
29
|
+
# Manages topology cache reads and lazily creates a ClusterTopologyMonitor
|
|
30
|
+
# to keep the topology up to date in the background.
|
|
31
|
+
class RdsHostListProvider
|
|
32
|
+
include Logging
|
|
33
|
+
|
|
34
|
+
TOPOLOGY_CACHE_NAME = :topology
|
|
35
|
+
DEFAULT_TOPOLOGY_QUERY_TIMEOUT_SEC = 5.0
|
|
36
|
+
MONITOR_EXPIRATION_TIMEOUT_SEC = 900.0 # 15 minutes
|
|
37
|
+
|
|
38
|
+
attr_reader :cluster_id, :instance_template, :rds_url_type
|
|
39
|
+
|
|
40
|
+
# @param service_container [Services::ServiceContainer]
|
|
41
|
+
# @param topology_utils [Object] responds to #query_topology
|
|
42
|
+
def initialize(service_container:, topology_utils:)
|
|
43
|
+
@service_container = service_container
|
|
44
|
+
@topology_utils = topology_utils
|
|
45
|
+
|
|
46
|
+
props = @service_container.connection_service.wrapper_props
|
|
47
|
+
@cluster_id = PropertyDefinition::CLUSTER_ID.get_string(props)
|
|
48
|
+
@instance_template = build_instance_template(props)
|
|
49
|
+
validate_host_pattern!(@instance_template.host)
|
|
50
|
+
@rds_url_type = Utils::RdsUtils.identify_rds_type(initial_host_info.host)
|
|
51
|
+
|
|
52
|
+
prefixed_wrapper_config = @service_container.connection_service.prefixed_wrapper_config[PropertyDefinition::TOPOLOGY_MONITORING_PREFIX]
|
|
53
|
+
@monitoring_wrapper_props = build_monitoring_wrapper_props(prefixed_wrapper_config || ::Concurrent::Map.new)
|
|
54
|
+
prefixed_driver_config = @service_container.connection_service.prefixed_driver_config[PropertyDefinition::TOPOLOGY_MONITORING_PREFIX]
|
|
55
|
+
@monitoring_driver_props = build_monitoring_driver_props(prefixed_driver_config || ::Concurrent::Map.new)
|
|
56
|
+
|
|
57
|
+
register_monitor_type
|
|
58
|
+
register_topology_cache
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns cached topology, otherwise starts the topology monitor in the background and
|
|
62
|
+
# returns immediately without waiting for a fetch. Initial connections must not block on
|
|
63
|
+
# topology being available; the monitor warms the cache for subsequent connections. Callers
|
|
64
|
+
# that explicitly want to wait use force_refresh with a positive timeout.
|
|
65
|
+
#
|
|
66
|
+
# @return [Array<HostInfo>]
|
|
67
|
+
def refresh
|
|
68
|
+
stored = stored_topology
|
|
69
|
+
return stored unless stored.nil? || stored.empty?
|
|
70
|
+
|
|
71
|
+
return initial_host_list unless @service_container.dialect_service.dialect_final?
|
|
72
|
+
|
|
73
|
+
hosts = force_refresh(false, 0.0)
|
|
74
|
+
return hosts unless hosts.nil? || hosts.empty?
|
|
75
|
+
|
|
76
|
+
stored_topology || initial_host_list
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Forces monitor to fetch fresh topology.
|
|
80
|
+
# @param verify_writer [Boolean]
|
|
81
|
+
# @param timeout_sec [Float]
|
|
82
|
+
# @return [Array<HostInfo>, nil]
|
|
83
|
+
def force_refresh(verify_writer, timeout_sec)
|
|
84
|
+
unless @service_container.dialect_service.dialect_final?
|
|
85
|
+
logger.debug('force_refresh was called but the dialect must be finalized before starting a topology monitor. ' \
|
|
86
|
+
'Returning initial host list.')
|
|
87
|
+
return initial_host_list
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
monitor = @service_container.monitor_service.run_if_absent(:cluster_topology, @cluster_id, @service_container) do |_sc|
|
|
91
|
+
Monitoring::ClusterTopologyMonitor.new(
|
|
92
|
+
service_container: @service_container,
|
|
93
|
+
cluster_id: @cluster_id,
|
|
94
|
+
instance_template: @instance_template,
|
|
95
|
+
topology_utils: @topology_utils,
|
|
96
|
+
monitoring_driver_props: @monitoring_driver_props,
|
|
97
|
+
monitoring_wrapper_props: @monitoring_wrapper_props
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
monitor.force_refresh(verify_writer, timeout_sec)
|
|
101
|
+
rescue Timeout::Error
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Stops the topology monitor for this cluster.
|
|
106
|
+
def stop_monitor
|
|
107
|
+
@service_container.monitor_service.stop_and_remove(:cluster_topology, @cluster_id)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
def stored_topology
|
|
113
|
+
@service_container.storage_service.get(TOPOLOGY_CACHE_NAME, @cluster_id, register_access: true)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def initial_host_list
|
|
117
|
+
[initial_host_info]
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# --- Construction helpers ---
|
|
121
|
+
|
|
122
|
+
def build_instance_template(props)
|
|
123
|
+
pattern = PropertyDefinition::CLUSTER_INSTANCE_HOST_PATTERN.get(props)
|
|
124
|
+
if pattern
|
|
125
|
+
host, port = parse_host_port_pattern(pattern)
|
|
126
|
+
port ||= initial_host_info.port
|
|
127
|
+
HostInfo.new(host: host, port: port)
|
|
128
|
+
else
|
|
129
|
+
auto_pattern = Utils::RdsUtils.rds_instance_host_pattern(initial_host_info.host)
|
|
130
|
+
HostInfo.new(host: auto_pattern, port: initial_host_info.port)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def parse_host_port_pattern(pattern)
|
|
135
|
+
last_colon = pattern.rindex(':')
|
|
136
|
+
return [pattern, nil] if last_colon.nil?
|
|
137
|
+
|
|
138
|
+
possible_port = pattern[(last_colon + 1)..]
|
|
139
|
+
if possible_port.match?(/\A\d+\z/)
|
|
140
|
+
[pattern[0...last_colon], possible_port]
|
|
141
|
+
else
|
|
142
|
+
[pattern, nil]
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Splits prefixed overrides into driver-level and wrapper-level props.
|
|
147
|
+
# Driver overrides are merged onto base driver_props with defaults applied.
|
|
148
|
+
# @return Hash monitoring_driver_props
|
|
149
|
+
def build_monitoring_driver_props(prefixed_driver_props)
|
|
150
|
+
monitoring_driver_props = @service_container.connection_service.driver_props.dup
|
|
151
|
+
|
|
152
|
+
prefixed_driver_props.each do |key, value|
|
|
153
|
+
monitoring_driver_props[key] = value
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
monitoring_driver_props
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Driver overrides are merged onto base wrapper_props with defaults applied.
|
|
160
|
+
# @return Hash monitoring_wrapper_props
|
|
161
|
+
def build_monitoring_wrapper_props(prefixed_wrapper_props)
|
|
162
|
+
monitoring_wrapper_props = @service_container.connection_service.wrapper_props.dup
|
|
163
|
+
|
|
164
|
+
prefixed_wrapper_props.each do |key, value|
|
|
165
|
+
monitoring_wrapper_props[key] = value
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
monitoring_wrapper_props
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def validate_host_pattern!(pattern)
|
|
172
|
+
raise Errors::AwsError, "Invalid cluster instance host pattern: '#{pattern}'" unless Utils::RdsUtils.dns_pattern_valid?(pattern)
|
|
173
|
+
|
|
174
|
+
url_type = Utils::RdsUtils.identify_rds_type(pattern)
|
|
175
|
+
if [Utils::RdsUrlType::RDS_PROXY, Utils::RdsUrlType::RDS_PROXY_ENDPOINT].include?(url_type)
|
|
176
|
+
raise Errors::AwsError, "cluster_instance_host_pattern is not supported for RDS Proxy: '#{pattern}'"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
if url_type == Utils::RdsUrlType::RDS_CUSTOM_CLUSTER
|
|
180
|
+
raise Errors::AwsError, "cluster_instance_host_pattern is not supported for RDS Custom Clusters: '#{pattern}'"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
return unless Utils::RdsUtils.region_typo?(pattern)
|
|
184
|
+
|
|
185
|
+
raise Errors::AwsError,
|
|
186
|
+
"cluster_instance_host_pattern '#{pattern}' contains an unknown or misspelled AWS region"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def register_monitor_type
|
|
190
|
+
@service_container.monitor_service.register_type(
|
|
191
|
+
:cluster_topology,
|
|
192
|
+
expiration_timeout_sec: MONITOR_EXPIRATION_TIMEOUT_SEC,
|
|
193
|
+
produced_data_type: TOPOLOGY_CACHE_NAME
|
|
194
|
+
)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def register_topology_cache
|
|
198
|
+
@service_container.storage_service.register(TOPOLOGY_CACHE_NAME, ttl: 300)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def initial_host_info
|
|
202
|
+
@service_container.connection_service.initial_host_info
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
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 'logger'
|
|
18
|
+
|
|
19
|
+
module AwsAdvancedRubyDriverWrapper
|
|
20
|
+
# The value substituted for any redacted (sensitive) property value.
|
|
21
|
+
REDACTED = '***'
|
|
22
|
+
|
|
23
|
+
# Sensitive property markers. A property key is treated as secret when it
|
|
24
|
+
# equals one of these or contains one as a substring.
|
|
25
|
+
SECRET_PROPERTY_KEYS = %w[password token secret credential].freeze
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
# Returns the logger used by the wrapper. Defaults to a Logger writing to $stderr.
|
|
29
|
+
# Users can replace this with any object that responds to the standard Logger methods
|
|
30
|
+
# (debug, info, warn, error, fatal).
|
|
31
|
+
#
|
|
32
|
+
# @example Setting a custom logger
|
|
33
|
+
# AwsAdvancedRubyDriverWrapper.logger = Logger.new('wrapper.log')
|
|
34
|
+
#
|
|
35
|
+
# @example Using Rails logger
|
|
36
|
+
# AwsAdvancedRubyDriverWrapper.logger = Rails.logger
|
|
37
|
+
#
|
|
38
|
+
# @return [Logger]
|
|
39
|
+
attr_writer :logger
|
|
40
|
+
|
|
41
|
+
def logger
|
|
42
|
+
@logger ||= default_logger
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns a copy of the given properties with the values of any sensitive
|
|
46
|
+
# keys (password, token, secret, credential, or keys containing those
|
|
47
|
+
# substrings) replaced with a redaction marker. The original collection is
|
|
48
|
+
# never mutated. Use this whenever properties may be written to logs.
|
|
49
|
+
#
|
|
50
|
+
# Accepts a Hash, Concurrent::Map, or any object responding to #each_pair or
|
|
51
|
+
# #each_key/#[]. Returns a plain Hash so it is always safe to interpolate.
|
|
52
|
+
#
|
|
53
|
+
# @example
|
|
54
|
+
# logger.debug("connecting with #{AwsAdvancedRubyDriverWrapper.mask_properties(props)}")
|
|
55
|
+
#
|
|
56
|
+
# @param props [#each_pair, #to_h, nil] the properties to mask
|
|
57
|
+
# @param extra_secret_keys [Array<String, Symbol>] further property names to redact exactly, for
|
|
58
|
+
# properties whose name is configurable (such as the IAM token property)
|
|
59
|
+
# @return [Hash] a new hash with sensitive values redacted
|
|
60
|
+
def mask_properties(props, extra_secret_keys = [])
|
|
61
|
+
return {} if props.nil?
|
|
62
|
+
|
|
63
|
+
pairs =
|
|
64
|
+
if props.respond_to?(:each_pair)
|
|
65
|
+
props.each_pair
|
|
66
|
+
elsif props.respond_to?(:to_h)
|
|
67
|
+
props.to_h
|
|
68
|
+
else
|
|
69
|
+
return {}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
extra = extra_secret_keys.compact.map { |name| name.to_s.downcase }
|
|
73
|
+
pairs.each_with_object({}) do |(key, value), masked|
|
|
74
|
+
masked[key] = secret_key?(key, extra) ? REDACTED : value
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @param extra_secret_keys [Array<String>] further lower-case property names to treat as secret
|
|
79
|
+
# @return [Boolean] whether the given property key is considered sensitive
|
|
80
|
+
def secret_key?(key, extra_secret_keys = [])
|
|
81
|
+
normalized = key.to_s.downcase
|
|
82
|
+
extra_secret_keys.include?(normalized) || SECRET_PROPERTY_KEYS.any? { |marker| normalized.include?(marker) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def default_logger
|
|
88
|
+
logger = Logger.new($stderr)
|
|
89
|
+
logger.progname = 'AwsAdvancedRubyDriverWrapper'
|
|
90
|
+
logger.level = Logger::INFO
|
|
91
|
+
logger
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Include this module in any class that needs logging.
|
|
96
|
+
# Provides a private `logger` method that delegates to the module-level logger,
|
|
97
|
+
# and a private `mask_properties` helper for redacting sensitive values.
|
|
98
|
+
module Logging
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def logger
|
|
102
|
+
AwsAdvancedRubyDriverWrapper.logger
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @see AwsAdvancedRubyDriverWrapper.mask_properties
|
|
106
|
+
def mask_properties(props, extra_secret_keys = [])
|
|
107
|
+
AwsAdvancedRubyDriverWrapper.mask_properties(props, extra_secret_keys)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|