mongo 2.20.1 → 2.21.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/README.md +3 -0
- data/Rakefile +2 -2
- data/lib/mongo/address.rb +22 -3
- data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
- data/lib/mongo/auth/base.rb +1 -1
- data/lib/mongo/bulk_write.rb +35 -2
- data/lib/mongo/client.rb +38 -6
- data/lib/mongo/client_encryption.rb +6 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
- data/lib/mongo/cluster/sdam_flow.rb +20 -7
- data/lib/mongo/cluster.rb +14 -4
- data/lib/mongo/collection/helpers.rb +1 -1
- data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
- data/lib/mongo/collection/view/aggregation.rb +33 -99
- data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
- data/lib/mongo/collection/view/change_stream.rb +80 -27
- data/lib/mongo/collection/view/iterable.rb +76 -60
- data/lib/mongo/collection/view/map_reduce.rb +25 -8
- data/lib/mongo/collection/view/readable.rb +79 -30
- data/lib/mongo/collection/view/writable.rb +109 -48
- data/lib/mongo/collection/view.rb +43 -3
- data/lib/mongo/collection.rb +158 -23
- data/lib/mongo/crypt/auto_encrypter.rb +4 -6
- data/lib/mongo/crypt/binding.rb +4 -4
- data/lib/mongo/crypt/context.rb +20 -14
- data/lib/mongo/crypt/encryption_io.rb +56 -26
- data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
- data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
- data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
- data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
- data/lib/mongo/csot_timeout_holder.rb +119 -0
- data/lib/mongo/cursor/kill_spec.rb +5 -2
- data/lib/mongo/cursor/nontailable.rb +27 -0
- data/lib/mongo/cursor.rb +86 -24
- data/lib/mongo/cursor_host.rb +82 -0
- data/lib/mongo/database/view.rb +81 -14
- data/lib/mongo/database.rb +88 -18
- data/lib/mongo/error/operation_failure.rb +209 -204
- data/lib/mongo/error/server_timeout_error.rb +12 -0
- data/lib/mongo/error/socket_timeout_error.rb +3 -1
- data/lib/mongo/error/timeout_error.rb +23 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/grid/fs_bucket.rb +45 -12
- data/lib/mongo/grid/stream/read.rb +15 -1
- data/lib/mongo/grid/stream/write.rb +21 -4
- data/lib/mongo/index/view.rb +77 -16
- data/lib/mongo/operation/context.rb +40 -2
- data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
- data/lib/mongo/operation/find/op_msg.rb +45 -0
- data/lib/mongo/operation/get_more/op_msg.rb +33 -0
- data/lib/mongo/operation/insert/op_msg.rb +3 -2
- data/lib/mongo/operation/insert/result.rb +4 -2
- data/lib/mongo/operation/list_collections/result.rb +1 -1
- data/lib/mongo/operation/map_reduce/result.rb +1 -1
- data/lib/mongo/operation/op_msg_base.rb +3 -1
- data/lib/mongo/operation/result.rb +26 -5
- data/lib/mongo/operation/shared/executable.rb +12 -1
- data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
- data/lib/mongo/operation/shared/response_handling.rb +3 -3
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
- data/lib/mongo/operation/shared/timed.rb +52 -0
- data/lib/mongo/operation/shared/write.rb +4 -1
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/protocol/message.rb +1 -4
- data/lib/mongo/protocol/msg.rb +2 -2
- data/lib/mongo/retryable/read_worker.rb +69 -29
- data/lib/mongo/retryable/write_worker.rb +49 -18
- data/lib/mongo/retryable.rb +8 -2
- data/lib/mongo/server/connection.rb +11 -5
- data/lib/mongo/server/connection_base.rb +22 -2
- data/lib/mongo/server/connection_pool.rb +32 -14
- data/lib/mongo/server/description/features.rb +1 -1
- data/lib/mongo/server/description.rb +18 -5
- data/lib/mongo/server/monitor.rb +7 -4
- data/lib/mongo/server/pending_connection.rb +7 -3
- data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
- data/lib/mongo/server.rb +11 -6
- data/lib/mongo/server_selector/base.rb +25 -9
- data/lib/mongo/session.rb +78 -9
- data/lib/mongo/socket/ssl.rb +109 -17
- data/lib/mongo/socket/tcp.rb +40 -6
- data/lib/mongo/socket.rb +154 -25
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +1 -0
- data/spec/atlas/atlas_connectivity_spec.rb +4 -0
- data/spec/atlas/operations_spec.rb +4 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
- data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
- data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +66 -22
- data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
- data/spec/integration/connection_pool_populator_spec.rb +2 -0
- data/spec/integration/cursor_pinning_spec.rb +15 -60
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/docs_examples_spec.rb +1 -1
- data/spec/integration/operation_failure_code_spec.rb +1 -1
- data/spec/integration/operation_failure_message_spec.rb +3 -3
- data/spec/integration/retryable_errors_spec.rb +2 -2
- data/spec/integration/sdam_error_handling_spec.rb +2 -1
- data/spec/integration/search_indexes_prose_spec.rb +4 -0
- data/spec/integration/server_spec.rb +4 -3
- data/spec/integration/transactions_api_examples_spec.rb +2 -0
- data/spec/kerberos/kerberos_spec.rb +4 -0
- data/spec/lite_spec_helper.rb +3 -1
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/caching_cursor_spec.rb +1 -1
- data/spec/mongo/client_encryption_spec.rb +1 -0
- data/spec/mongo/client_spec.rb +158 -4
- data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
- data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
- data/spec/mongo/collection_spec.rb +5 -6
- data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
- data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
- data/spec/mongo/crypt/handle_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +26 -9
- data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
- data/spec/mongo/operation/context_spec.rb +79 -0
- data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
- data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
- data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
- data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
- data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
- data/spec/mongo/operation/shared/csot/examples.rb +113 -0
- data/spec/mongo/query_cache_spec.rb +243 -225
- data/spec/mongo/retryable_spec.rb +1 -0
- data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
- data/spec/mongo/socket/ssl_spec.rb +0 -10
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/crud/operation.rb +1 -1
- data/spec/runners/crud/verifier.rb +3 -1
- data/spec/runners/transactions/operation.rb +4 -6
- data/spec/runners/unified/ambiguous_operations.rb +13 -0
- data/spec/runners/unified/assertions.rb +4 -0
- data/spec/runners/unified/change_stream_operations.rb +14 -24
- data/spec/runners/unified/crud_operations.rb +82 -59
- data/spec/runners/unified/ddl_operations.rb +38 -7
- data/spec/runners/unified/grid_fs_operations.rb +37 -2
- data/spec/runners/unified/support_operations.rb +43 -4
- data/spec/runners/unified/test.rb +22 -10
- data/spec/runners/unified.rb +1 -1
- data/spec/solo/clean_exit_spec.rb +2 -0
- data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
- data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
- data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
- data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
- data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
- data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
- data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
- data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
- data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
- data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
- data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
- data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
- data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +4 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +4 -0
- data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
- data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
- data/spec/support/certificates/atlas-ocsp-ca.crt +81 -83
- data/spec/support/certificates/atlas-ocsp.crt +107 -107
- data/spec/support/cluster_tools.rb +3 -3
- data/spec/support/common_shortcuts.rb +2 -2
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/utils.rb +3 -1
- metadata +78 -91
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -253
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1688
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -294
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -906
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1685
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1681
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1698
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -330
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -425
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -227
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -328
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -320
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -337
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -914
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -519
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -912
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -908
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -925
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -326
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -425
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -225
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -324
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -320
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -339
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -255
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -255
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -44
@@ -73,47 +73,66 @@ module Mongo
|
|
73
73
|
# filter
|
74
74
|
#
|
75
75
|
# @param [ Hash ] filter
|
76
|
+
# @param [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
77
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
78
|
+
# The default value is unset which means the feature is not enabled.
|
76
79
|
#
|
77
80
|
# @return [ Array<BSON::Document> ] The query results
|
78
|
-
def find_keys(filter)
|
79
|
-
key_vault_collection.find(filter).to_a
|
81
|
+
def find_keys(filter, timeout_ms: nil)
|
82
|
+
key_vault_collection.find(filter, timeout_ms: timeout_ms).to_a
|
80
83
|
end
|
81
84
|
|
82
85
|
# Insert a document into the key vault collection
|
83
86
|
#
|
84
87
|
# @param [ Hash ] document
|
88
|
+
# @param [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
89
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
90
|
+
# The default value is unset which means the feature is not enabled.
|
85
91
|
#
|
86
92
|
# @return [ Mongo::Operation::Insert::Result ] The insertion result
|
87
|
-
def insert_data_key(document)
|
88
|
-
key_vault_collection.insert_one(document)
|
93
|
+
def insert_data_key(document, timeout_ms: nil)
|
94
|
+
key_vault_collection.insert_one(document, timeout_ms: timeout_ms)
|
89
95
|
end
|
90
96
|
|
91
97
|
# Get collection info for a collection matching the provided filter
|
92
98
|
#
|
93
99
|
# @param [ Hash ] filter
|
100
|
+
# @param [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
101
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
102
|
+
# The default value is unset which means the feature is not enabled.
|
94
103
|
#
|
95
104
|
# @return [ Hash ] The collection information
|
96
|
-
def collection_info(db_name, filter)
|
105
|
+
def collection_info(db_name, filter, timeout_ms: nil)
|
97
106
|
unless @metadata_client
|
98
107
|
raise ArgumentError, 'collection_info requires metadata_client to have been passed to the constructor, but it was not'
|
99
108
|
end
|
100
109
|
|
101
|
-
@metadata_client
|
110
|
+
@metadata_client
|
111
|
+
.use(db_name)
|
112
|
+
.database
|
113
|
+
.list_collections(filter: filter, deserialize_as_bson: true, timeout_ms: timeout_ms)
|
114
|
+
.first
|
102
115
|
end
|
103
116
|
|
104
117
|
# Send the command to mongocryptd to be marked with intent-to-encrypt markings
|
105
118
|
#
|
106
119
|
# @param [ Hash ] cmd
|
120
|
+
# @param [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
121
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
122
|
+
# The default value is unset which means the feature is not enabled.
|
107
123
|
#
|
108
124
|
# @return [ Hash ] The marked command
|
109
|
-
def mark_command(cmd)
|
125
|
+
def mark_command(cmd, timeout_ms: nil)
|
110
126
|
unless @mongocryptd_client
|
111
127
|
raise ArgumentError, 'mark_command requires mongocryptd_client to have been passed to the constructor, but it was not'
|
112
128
|
end
|
113
129
|
|
114
130
|
# Ensure the response from mongocryptd is deserialized with { mode: :bson }
|
115
131
|
# to prevent losing type information in commands
|
116
|
-
options = {
|
132
|
+
options = {
|
133
|
+
execution_options: { deserialize_as_bson: true },
|
134
|
+
timeout_ms: timeout_ms
|
135
|
+
}
|
117
136
|
|
118
137
|
begin
|
119
138
|
response = @mongocryptd_client.database.command(cmd, options)
|
@@ -136,9 +155,12 @@ module Mongo
|
|
136
155
|
# to send on that connection.
|
137
156
|
# @param [ Hash ] tls_options. TLS options to connect to KMS provider.
|
138
157
|
# The options are same as for Mongo::Client.
|
139
|
-
|
158
|
+
# @param [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
159
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
160
|
+
# The default value is unset which means the feature is not enabled.
|
161
|
+
def feed_kms(kms_context, tls_options, timeout_ms: nil)
|
140
162
|
with_ssl_socket(kms_context.endpoint, tls_options) do |ssl_socket|
|
141
|
-
Timeout.timeout(SOCKET_TIMEOUT, Error::SocketTimeoutError,
|
163
|
+
Timeout.timeout(timeout_ms || SOCKET_TIMEOUT, Error::SocketTimeoutError,
|
142
164
|
'Socket write operation timed out'
|
143
165
|
) do
|
144
166
|
ssl_socket.syswrite(kms_context.message)
|
@@ -146,7 +168,7 @@ module Mongo
|
|
146
168
|
|
147
169
|
bytes_needed = kms_context.bytes_needed
|
148
170
|
while bytes_needed > 0 do
|
149
|
-
bytes = Timeout.timeout(SOCKET_TIMEOUT, Error::SocketTimeoutError,
|
171
|
+
bytes = Timeout.timeout(timeout_ms || SOCKET_TIMEOUT, Error::SocketTimeoutError,
|
150
172
|
'Socket read operation timed out'
|
151
173
|
) do
|
152
174
|
ssl_socket.sysread(bytes_needed)
|
@@ -160,38 +182,39 @@ module Mongo
|
|
160
182
|
|
161
183
|
# Adds a key_alt_name to the key_alt_names array of the key document
|
162
184
|
# in the key vault collection with the given id.
|
163
|
-
def add_key_alt_name(id, key_alt_name)
|
185
|
+
def add_key_alt_name(id, key_alt_name, timeout_ms: nil)
|
164
186
|
key_vault_collection.find_one_and_update(
|
165
187
|
{ _id: id },
|
166
188
|
{ '$addToSet' => { keyAltNames: key_alt_name } },
|
189
|
+
timeout_ms: timeout_ms
|
167
190
|
)
|
168
191
|
end
|
169
192
|
|
170
193
|
# Removes the key document with the given id
|
171
194
|
# from the key vault collection.
|
172
|
-
def delete_key(id)
|
173
|
-
key_vault_collection.delete_one(_id: id)
|
195
|
+
def delete_key(id, timeout_ms: nil)
|
196
|
+
key_vault_collection.delete_one(_id: id, timeout_ms: timeout_ms)
|
174
197
|
end
|
175
198
|
|
176
199
|
# Finds a single key document with the given id.
|
177
|
-
def get_key(id)
|
178
|
-
key_vault_collection.find(_id: id).first
|
200
|
+
def get_key(id, timeout_ms: nil)
|
201
|
+
key_vault_collection.find(_id: id, timeout_ms: timeout_ms).first
|
179
202
|
end
|
180
203
|
|
181
204
|
# Returns a key document in the key vault collection with
|
182
205
|
# the given key_alt_name.
|
183
|
-
def get_key_by_alt_name(key_alt_name)
|
184
|
-
key_vault_collection.find(keyAltNames: key_alt_name).first
|
206
|
+
def get_key_by_alt_name(key_alt_name, timeout_ms: nil)
|
207
|
+
key_vault_collection.find(keyAltNames: key_alt_name, timeout_ms: timeout_ms).first
|
185
208
|
end
|
186
209
|
|
187
210
|
# Finds all documents in the key vault collection.
|
188
|
-
def get_keys
|
189
|
-
key_vault_collection.find
|
211
|
+
def get_keys(timeout_ms: nil)
|
212
|
+
key_vault_collection.find(nil, timeout_ms: timeout_ms)
|
190
213
|
end
|
191
214
|
|
192
215
|
# Removes a key_alt_name from the key_alt_names array of the key document
|
193
216
|
# in the key vault collection with the given id.
|
194
|
-
def remove_key_alt_name(id, key_alt_name)
|
217
|
+
def remove_key_alt_name(id, key_alt_name, timeout_ms: nil)
|
195
218
|
key_vault_collection.find_one_and_update(
|
196
219
|
{ _id: id },
|
197
220
|
[
|
@@ -211,7 +234,8 @@ module Mongo
|
|
211
234
|
}
|
212
235
|
}
|
213
236
|
}
|
214
|
-
]
|
237
|
+
],
|
238
|
+
timeout_ms: timeout_ms
|
215
239
|
)
|
216
240
|
end
|
217
241
|
|
@@ -220,8 +244,8 @@ module Mongo
|
|
220
244
|
# @param [ Array<Hash> ] requests The bulk write requests.
|
221
245
|
#
|
222
246
|
# @return [ BulkWrite::Result ] The result of the operation.
|
223
|
-
def update_data_keys(updates)
|
224
|
-
key_vault_collection.bulk_write(updates)
|
247
|
+
def update_data_keys(updates, timeout_ms: nil)
|
248
|
+
key_vault_collection.bulk_write(updates, timeout_ms: timeout_ms)
|
225
249
|
end
|
226
250
|
|
227
251
|
private
|
@@ -322,15 +346,21 @@ module Mongo
|
|
322
346
|
#
|
323
347
|
# @note The socket is always closed when the provided block has finished
|
324
348
|
# executing
|
325
|
-
def with_ssl_socket(endpoint, tls_options)
|
349
|
+
def with_ssl_socket(endpoint, tls_options, timeout_ms: nil)
|
350
|
+
csot = !timeout_ms.nil?
|
326
351
|
address = begin
|
327
352
|
host, port = endpoint.split(':')
|
328
353
|
port ||= 443 # All supported KMS APIs use this port by default.
|
329
354
|
Address.new([host, port].join(':'))
|
330
355
|
end
|
356
|
+
socket_options = { ssl: true, csot: csot }.tap do |opts|
|
357
|
+
if csot
|
358
|
+
opts[:connect_timeout] = (timeout_ms / 1_000.0)
|
359
|
+
end
|
360
|
+
end
|
331
361
|
mongo_socket = address.socket(
|
332
362
|
SOCKET_TIMEOUT,
|
333
|
-
tls_options.merge(
|
363
|
+
tls_options.merge(socket_options)
|
334
364
|
)
|
335
365
|
yield(mongo_socket.socket)
|
336
366
|
rescue => e
|
@@ -35,7 +35,9 @@ module Mongo
|
|
35
35
|
# providers. Keys of the hash should be KSM provider names; values
|
36
36
|
# should be hashes of TLS connection options. The options are equivalent
|
37
37
|
# to TLS connection options of Mongo::Client.
|
38
|
-
|
38
|
+
# @param [ Integer | nil ] timeout_ms Timeout for every operation executed
|
39
|
+
# on this object.
|
40
|
+
def initialize(key_vault_client, key_vault_namespace, kms_providers, kms_tls_options, timeout_ms = nil)
|
39
41
|
Crypt.validate_ffi!
|
40
42
|
@crypt_handle = Handle.new(
|
41
43
|
kms_providers,
|
@@ -47,6 +49,7 @@ module Mongo
|
|
47
49
|
metadata_client: nil,
|
48
50
|
key_vault_namespace: key_vault_namespace
|
49
51
|
)
|
52
|
+
@timeout_ms = timeout_ms
|
50
53
|
end
|
51
54
|
|
52
55
|
# Generates a data key used for encryption/decryption and stores
|
@@ -71,9 +74,11 @@ module Mongo
|
|
71
74
|
master_key_document,
|
72
75
|
key_alt_names,
|
73
76
|
key_material
|
74
|
-
).run_state_machine
|
77
|
+
).run_state_machine(timeout_holder)
|
75
78
|
|
76
|
-
@encryption_io.insert_data_key(
|
79
|
+
@encryption_io.insert_data_key(
|
80
|
+
data_key_document, timeout_ms: timeout_holder.remaining_timeout_ms!
|
81
|
+
).inserted_id
|
77
82
|
end
|
78
83
|
|
79
84
|
# Encrypts a value using the specified encryption key and algorithm
|
@@ -111,7 +116,7 @@ module Mongo
|
|
111
116
|
@encryption_io,
|
112
117
|
{ v: value },
|
113
118
|
options
|
114
|
-
).run_state_machine['v']
|
119
|
+
).run_state_machine(timeout_holder)['v']
|
115
120
|
end
|
116
121
|
|
117
122
|
# Encrypts a Match Expression or Aggregate Expression to query a range index.
|
@@ -125,7 +130,7 @@ module Mongo
|
|
125
130
|
# {'$and' => [{'$gt' => ['$field', 10]}, {'$lt' => ['$field', 20]}}
|
126
131
|
# )
|
127
132
|
# {$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]
|
128
|
-
# Only supported when queryType is "
|
133
|
+
# Only supported when queryType is "range" and algorithm is "Range".
|
129
134
|
# @note: The Range algorithm is experimental only. It is not intended
|
130
135
|
# for public use. It is subject to breaking changes.
|
131
136
|
#
|
@@ -137,24 +142,25 @@ module Mongo
|
|
137
142
|
# @option options [ String ] :key_alt_name The alternate name for the
|
138
143
|
# encryption key.
|
139
144
|
# @option options [ String ] :algorithm The algorithm used to encrypt the
|
140
|
-
# expression. The only allowed value is "
|
145
|
+
# expression. The only allowed value is "Range"
|
141
146
|
# @option options [ Integer | nil ] :contention_factor Contention factor
|
142
147
|
# to be applied If not provided, it defaults to a value of 0.
|
143
148
|
# @option options [ String | nil ] query_type Query type to be applied.
|
144
|
-
# The only allowed value is "
|
149
|
+
# The only allowed value is "range".
|
145
150
|
# @option options [ Hash | nil ] :range_opts Specifies index options for
|
146
|
-
# a Queryable Encryption field supporting "
|
151
|
+
# a Queryable Encryption field supporting "range" queries.
|
147
152
|
# Allowed options are:
|
148
153
|
# - :min
|
149
154
|
# - :max
|
155
|
+
# - :trim_factor
|
150
156
|
# - :sparsity
|
151
157
|
# - :precision
|
152
|
-
# min, max, sparsity, and
|
158
|
+
# min, max, trim_factor, sparsity, and precision must match the values set in
|
153
159
|
# the encryptedFields of the destination collection.
|
154
160
|
# For double and decimal128, min/max/precision must all be set,
|
155
161
|
# or all be unset.
|
156
162
|
#
|
157
|
-
# @note The
|
163
|
+
# @note The Range algorithm is experimental only. It is not
|
158
164
|
# intended for public use.
|
159
165
|
#
|
160
166
|
# @note The :key_id and :key_alt_name options are mutually exclusive. Only
|
@@ -170,7 +176,7 @@ module Mongo
|
|
170
176
|
@encryption_io,
|
171
177
|
{ v: expression },
|
172
178
|
options
|
173
|
-
).run_state_machine['v']
|
179
|
+
).run_state_machine(timeout_holder)['v']
|
174
180
|
end
|
175
181
|
|
176
182
|
# Decrypts a value that has already been encrypted
|
@@ -184,7 +190,7 @@ module Mongo
|
|
184
190
|
@crypt_handle,
|
185
191
|
@encryption_io,
|
186
192
|
{ v: value }
|
187
|
-
).run_state_machine['v']
|
193
|
+
).run_state_machine(timeout_holder)['v']
|
188
194
|
end
|
189
195
|
|
190
196
|
# Adds a key_alt_name for the key in the key vault collection with the given id.
|
@@ -195,7 +201,7 @@ module Mongo
|
|
195
201
|
# @return [ BSON::Document | nil ] Document describing the identified key
|
196
202
|
# before adding the key alt name, or nil if no such key.
|
197
203
|
def add_key_alt_name(id, key_alt_name)
|
198
|
-
@encryption_io.add_key_alt_name(id, key_alt_name)
|
204
|
+
@encryption_io.add_key_alt_name(id, key_alt_name, timeout_ms: @timeout_ms)
|
199
205
|
end
|
200
206
|
|
201
207
|
# Removes the key with the given id from the key vault collection.
|
@@ -204,7 +210,9 @@ module Mongo
|
|
204
210
|
#
|
205
211
|
# @return [ Operation::Result ] The response from the database for the delete_one
|
206
212
|
# operation that deletes the key.
|
207
|
-
|
213
|
+
def delete_key(id)
|
214
|
+
@encryption_io.delete_key(id, timeout_ms: @timeout_ms)
|
215
|
+
end
|
208
216
|
|
209
217
|
# Finds a single key with the given id.
|
210
218
|
#
|
@@ -212,7 +220,9 @@ module Mongo
|
|
212
220
|
#
|
213
221
|
# @return [ BSON::Document | nil ] The found key document or nil
|
214
222
|
# if not found.
|
215
|
-
|
223
|
+
def get_key(id)
|
224
|
+
@encryption_io.get_key(id, timeout_ms: @timeout_ms)
|
225
|
+
end
|
216
226
|
|
217
227
|
# Returns a key in the key vault collection with the given key_alt_name.
|
218
228
|
#
|
@@ -220,12 +230,19 @@ module Mongo
|
|
220
230
|
#
|
221
231
|
# @return [ BSON::Document | nil ] The found key document or nil
|
222
232
|
# if not found.
|
223
|
-
|
233
|
+
def get_key_by_alt_name(key_alt_name)
|
234
|
+
@encryption_io.get_key_by_alt_name(key_alt_name, timeout_ms: @timeout_ms)
|
235
|
+
end
|
224
236
|
|
225
237
|
# Returns all keys in the key vault collection.
|
226
238
|
#
|
227
239
|
# @return [ Collection::View ] Keys in the key vault collection.
|
228
|
-
|
240
|
+
# rubocop:disable Naming/AccessorMethodName
|
241
|
+
# Name of this method is defined in the FLE spec
|
242
|
+
def get_keys
|
243
|
+
@encryption_io.get_keys(timeout_ms: @timeout_ms)
|
244
|
+
end
|
245
|
+
# rubocop:enable Naming/AccessorMethodName
|
229
246
|
|
230
247
|
# Removes a key_alt_name from a key in the key vault collection with the given id.
|
231
248
|
#
|
@@ -234,7 +251,9 @@ module Mongo
|
|
234
251
|
#
|
235
252
|
# @return [ BSON::Document | nil ] Document describing the identified key
|
236
253
|
# before removing the key alt name, or nil if no such key.
|
237
|
-
|
254
|
+
def remove_key_alt_name(id, key_alt_name)
|
255
|
+
@encryption_io.remove_key_alt_name(id, key_alt_name, timeout_ms: @timeout_ms)
|
256
|
+
end
|
238
257
|
|
239
258
|
# Decrypts multiple data keys and (re-)encrypts them with a new master_key,
|
240
259
|
# or with their current master_key if a new one is not given.
|
@@ -257,12 +276,14 @@ module Mongo
|
|
257
276
|
@encryption_io,
|
258
277
|
filter,
|
259
278
|
master_key_document
|
260
|
-
).run_state_machine
|
279
|
+
).run_state_machine(timeout_holder)
|
261
280
|
|
262
281
|
return RewrapManyDataKeyResult.new(nil) if rewrap_result.nil?
|
263
282
|
|
264
283
|
updates = updates_from_data_key_documents(rewrap_result.fetch('v'))
|
265
|
-
RewrapManyDataKeyResult.new(
|
284
|
+
RewrapManyDataKeyResult.new(
|
285
|
+
@encryption_io.update_data_keys(updates, timeout_ms: @timeout_ms)
|
286
|
+
)
|
266
287
|
end
|
267
288
|
|
268
289
|
private
|
@@ -318,6 +339,14 @@ module Mongo
|
|
318
339
|
}
|
319
340
|
end
|
320
341
|
end
|
342
|
+
|
343
|
+
def timeout_holder
|
344
|
+
CsotTimeoutHolder.new(
|
345
|
+
operation_timeouts: {
|
346
|
+
operation_timeout_ms: @timeout_ms
|
347
|
+
}
|
348
|
+
)
|
349
|
+
end
|
321
350
|
end
|
322
351
|
end
|
323
352
|
end
|
@@ -39,27 +39,28 @@ module Mongo
|
|
39
39
|
# that will be used to encrypt the value.
|
40
40
|
# @option options [ String ] :algorithm The algorithm used to encrypt the
|
41
41
|
# value. Valid algorithms are "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
|
42
|
-
# "AEAD_AES_256_CBC_HMAC_SHA_512-Random", "Indexed", "Unindexed", "
|
42
|
+
# "AEAD_AES_256_CBC_HMAC_SHA_512-Random", "Indexed", "Unindexed", "Range".
|
43
43
|
# @option options [ Integer | nil ] :contention_factor Contention factor
|
44
44
|
# to be applied if encryption algorithm is set to "Indexed". If not
|
45
45
|
# provided, it defaults to a value of 0. Contention factor should be set
|
46
46
|
# only if encryption algorithm is set to "Indexed".
|
47
47
|
# @option options [ String | nil ] query_type Query type to be applied
|
48
|
-
# if encryption algorithm is set to "Indexed" or "
|
49
|
-
# Allowed values are "equality" and "
|
48
|
+
# if encryption algorithm is set to "Indexed" or "Range".
|
49
|
+
# Allowed values are "equality" and "range".
|
50
50
|
# @option options [ Hash | nil ] :range_opts Specifies index options for
|
51
|
-
# a Queryable Encryption field supporting "
|
51
|
+
# a Queryable Encryption field supporting "range" queries.
|
52
52
|
# Allowed options are:
|
53
53
|
# - :min
|
54
54
|
# - :max
|
55
|
+
# - :trim_factor
|
55
56
|
# - :sparsity
|
56
57
|
# - :precision
|
57
|
-
# min, max, sparsity, and
|
58
|
+
# min, max, trim_factor, sparsity, and precision must match the values set in
|
58
59
|
# the encryptedFields of the destination collection.
|
59
60
|
# For double and decimal128, min/max/precision must all be set,
|
60
61
|
# or all be unset.
|
61
62
|
#
|
62
|
-
# @note The
|
63
|
+
# @note The Range algorithm is experimental only. It is not intended for
|
63
64
|
# public use.
|
64
65
|
#
|
65
66
|
# @raise [ ArgumentError|Mongo::Error::CryptError ] If invalid options are provided
|
@@ -116,7 +117,7 @@ module Mongo
|
|
116
117
|
|
117
118
|
def set_algorithm_opts(options)
|
118
119
|
Binding.ctx_setopt_algorithm(self, options[:algorithm])
|
119
|
-
if %w(Indexed
|
120
|
+
if %w(Indexed Range).include?(options[:algorithm])
|
120
121
|
if options[:contention_factor]
|
121
122
|
Binding.ctx_setopt_contention_factor(self, options[:contention_factor])
|
122
123
|
end
|
@@ -125,20 +126,25 @@ module Mongo
|
|
125
126
|
end
|
126
127
|
else
|
127
128
|
if options[:contention_factor]
|
128
|
-
raise ArgumentError.new(':contention_factor is allowed only for "Indexed" or "
|
129
|
+
raise ArgumentError.new(':contention_factor is allowed only for "Indexed" or "Range" algorithms')
|
129
130
|
end
|
130
131
|
if options[:query_type]
|
131
|
-
raise ArgumentError.new(':query_type is allowed only for "Indexed" or "
|
132
|
+
raise ArgumentError.new(':query_type is allowed only for "Indexed" or "Range" algorithms')
|
132
133
|
end
|
133
134
|
end
|
134
|
-
if options[:algorithm] == '
|
135
|
+
if options[:algorithm] == 'Range'
|
135
136
|
Binding.ctx_setopt_algorithm_range(self, convert_range_opts(options[:range_opts]))
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
139
140
|
def convert_range_opts(range_opts)
|
140
141
|
range_opts.dup.tap do |opts|
|
141
|
-
|
142
|
+
if opts[:sparsity] && !opts[:sparsity].is_a?(BSON::Int64)
|
143
|
+
opts[:sparsity] = BSON::Int64.new(opts[:sparsity])
|
144
|
+
end
|
145
|
+
if opts[:trim_factor]
|
146
|
+
opts[:trimFactor] = opts.delete(:trim_factor)
|
147
|
+
end
|
142
148
|
end
|
143
149
|
end
|
144
150
|
end
|
@@ -34,13 +34,16 @@ module Mongo
|
|
34
34
|
# request. This is used for testing.
|
35
35
|
# @param [String | nil] metadata_host Azure metadata host. This
|
36
36
|
# is used for testing.
|
37
|
+
# @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
|
37
38
|
#
|
38
39
|
# @return [ KMS::Azure::AccessToken ] Azure access token.
|
39
40
|
#
|
40
41
|
# @raise [KMS::CredentialsNotFound] If credentials could not be found.
|
41
|
-
|
42
|
+
# @raise Error::TimeoutError if credentials cannot be retrieved within
|
43
|
+
# the timeout.
|
44
|
+
def self.fetch_access_token(extra_headers: {}, metadata_host: nil, timeout_holder: nil)
|
42
45
|
uri, req = prepare_request(extra_headers, metadata_host)
|
43
|
-
parsed_response = fetch_response(uri, req)
|
46
|
+
parsed_response = fetch_response(uri, req, timeout_holder)
|
44
47
|
Azure::AccessToken.new(
|
45
48
|
parsed_response.fetch('access_token'),
|
46
49
|
Integer(parsed_response.fetch('expires_in'))
|
@@ -78,13 +81,16 @@ module Mongo
|
|
78
81
|
#
|
79
82
|
# @param [URI] uri URI to Azure metadata host.
|
80
83
|
# @param [Net::HTTP::Get] req Request object.
|
84
|
+
# @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
|
81
85
|
#
|
82
86
|
# @return [Hash] Parsed response.
|
83
87
|
#
|
84
88
|
# @raise [KMS::CredentialsNotFound] If cannot fetch response or
|
85
89
|
# response is invalid.
|
86
|
-
|
87
|
-
|
90
|
+
# @raise Error::TimeoutError if credentials cannot be retrieved within
|
91
|
+
# the timeout.
|
92
|
+
def self.fetch_response(uri, req, timeout_holder)
|
93
|
+
resp = do_request(uri, req, timeout_holder)
|
88
94
|
if resp.code != '200'
|
89
95
|
raise KMS::CredentialsNotFound,
|
90
96
|
"Azure metadata host responded with code #{resp.code}"
|
@@ -100,12 +106,22 @@ module Mongo
|
|
100
106
|
#
|
101
107
|
# @param [URI] uri URI to Azure metadata host.
|
102
108
|
# @param [Net::HTTP::Get] req Request object.
|
109
|
+
# @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
|
103
110
|
#
|
104
111
|
# @return [Net::HTTPResponse] Response object.
|
105
112
|
#
|
106
113
|
# @raise [KMS::CredentialsNotFound] If cannot execute request.
|
107
|
-
|
108
|
-
|
114
|
+
# @raise Error::TimeoutError if credentials cannot be retrieved within
|
115
|
+
# the timeout.
|
116
|
+
def self.do_request(uri, req, timeout_holder)
|
117
|
+
timeout_holder&.check_timeout!
|
118
|
+
timeout = timeout_holder&.remaining_timeout_sec || 10
|
119
|
+
exception_class = if timeout_holder&.csot?
|
120
|
+
Error::TimeoutError
|
121
|
+
else
|
122
|
+
nil
|
123
|
+
end
|
124
|
+
::Timeout.timeout(timeout, exception_class) do
|
109
125
|
Net::HTTP.start(uri.hostname, uri.port, use_ssl: false) do |http|
|
110
126
|
http.request(req)
|
111
127
|
end
|
@@ -29,14 +29,20 @@ module Mongo
|
|
29
29
|
|
30
30
|
DEFAULT_HOST = 'metadata.google.internal'
|
31
31
|
|
32
|
-
|
32
|
+
# Fetch GCP access token.
|
33
|
+
#
|
34
|
+
# @param [ CsotTimeoutHolder | nil ] timeout_holder CSOT timeout.
|
35
|
+
#
|
36
|
+
# @return [ String ] GCP access token.
|
37
|
+
#
|
38
|
+
# @raise [ KMS::CredentialsNotFound ]
|
39
|
+
# @raise [ Error::TimeoutError ]
|
40
|
+
def self.fetch_access_token(timeout_holder = nil)
|
33
41
|
host = ENV.fetch(METADATA_HOST_ENV) { DEFAULT_HOST }
|
34
42
|
uri = URI("http://#{host}/computeMetadata/v1/instance/service-accounts/default/token")
|
35
43
|
req = Net::HTTP::Get.new(uri)
|
36
44
|
req['Metadata-Flavor'] = 'Google'
|
37
|
-
resp =
|
38
|
-
http.request(req)
|
39
|
-
end
|
45
|
+
resp = fetch_response(uri, req, timeout_holder)
|
40
46
|
if resp.code != '200'
|
41
47
|
raise KMS::CredentialsNotFound,
|
42
48
|
"GCE metadata host responded with code #{resp.code}"
|
@@ -50,6 +56,25 @@ module Mongo
|
|
50
56
|
raise KMS::CredentialsNotFound,
|
51
57
|
"Could not receive GCP metadata response; #{e.class}: #{e.message}"
|
52
58
|
end
|
59
|
+
|
60
|
+
def self.fetch_response(uri, req, timeout_holder)
|
61
|
+
timeout_holder&.check_timeout!
|
62
|
+
if timeout_holder&.timeout?
|
63
|
+
::Timeout.timeout(timeout_holder.remaining_timeout_sec, Error:TimeoutError) do
|
64
|
+
do_fetch(uri, req)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
do_fetch(uri, req)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
private_class_method :fetch_response
|
71
|
+
|
72
|
+
def self.do_fetch(uri, req)
|
73
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: false) do |http|
|
74
|
+
http.request(req)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
private_class_method :do_fetch
|
53
78
|
end
|
54
79
|
end
|
55
80
|
end
|