mongo 2.20.0 → 2.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +40 -1
- data/Rakefile +59 -23
- 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/config.rb +2 -2
- 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/base_worker.rb +28 -3
- data/lib/mongo/retryable/read_worker.rb +76 -35
- data/lib/mongo/retryable/write_worker.rb +53 -22
- 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 +25 -8
- 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 +131 -18
- 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 -5
- data/lib/mongo.rb +1 -0
- data/mongo.gemspec +8 -11
- 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 +67 -20
- 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/retryable_reads_errors_spec.rb +35 -23
- data/spec/integration/sdam_error_handling_spec.rb +4 -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 -11
- 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_crud_spec.rb +1 -0
- 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/connection_spec.rb +22 -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/fle2v2-BypassQueryAnalysis.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.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 +6 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -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/spec_tests/transactions_unified_spec.rb +2 -1
- data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
- data/spec/support/certificates/atlas-ocsp.crt +117 -122
- data/spec/support/certificates/retrieve-atlas-cert +1 -1
- 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 +88 -173
- checksums.yaml.gz.sig +0 -0
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -298
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -281
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -417
- data/spec/shared/shlib/set_env.sh +0 -146
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
- data/spec/support/faas/app/aws_lambda/mongodb/Gemfile.lock +0 -19
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -3
@@ -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
|