-
Notifications
You must be signed in to change notification settings - Fork 899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GODRIVER-2391 add encryptedFields to CreateCollection and Drop #913
GODRIVER-2391 add encryptedFields to CreateCollection and Drop #913
Conversation
Get canary test passing.
add fle2-CreateCollection.json test
It is redundant with new spec tests
commandName => command_name databaseName => database_name
Split into: - getEncryptedFieldsFromMap - getEncryptedFieldsFromServer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great! I have some initial comments about the changes to Drop
. I think I'll look at CreateCollection
and the test runner changes after we discuss those.
mongo/collection.go
Outdated
@@ -1664,7 +1664,94 @@ func (coll *Collection) Indexes() IndexView { | |||
|
|||
// Drop drops the collection on the server. This method ignores "namespace not found" errors so it is safe to drop | |||
// a collection that does not exist on the server. | |||
func (coll *Collection) Drop(ctx context.Context) error { | |||
func (coll *Collection) Drop(ctx context.Context, opts ...*options.DropCollectionOptions) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify, this is not a breaking change because opts
is a variadic parameter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question. I think this is a possible backwards break.
Consider a possible interface in user code:
// MockCollection implements methods of a mongo.Collection.
type MockCollection interface {
Drop(ctx context.Context) error
// (Other methods)
}
With the proposed changes, mongo.Collection
no longer implements MockCollection
.
I am not sure how common that pattern is. And IMO it would be a straightforward change for users to update interface definitions.
I had not considered this could be a backwards breaking change in drivers when adding to the specification. Since encryptedFields
can also be obtained from the EncryptedFieldsMap
and server-side. IMO I prefer erring towards reducing risk of breaking user code rather than strict specification conformance. We can consider adding an argument in a major release.
Updated to remove DropCollectionOptions and skip the tests that require it.
// EncryptedFields configures encrypted fields for encrypted collections. | ||
// | ||
// This option is only valid for MongoDB versions >= 6.0 | ||
EncryptedFields interface{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any more meaningful type representation for EncryptedFields
? interface{}
can certainly be helpful if there is a need for forward compatibility. But, what exactly is the structure of encryptedFields
on the server? map[string]string
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any more meaningful type representation for EncryptedFields?
The rationale in the scope is consistency with JSONSchema representation. See Q8 in the scope:
Q8: Should encryptedFieldsEncryptedFieldConfig be BSON or a class?
Proposed Answer: BSON. This is consistent with the schema in the SchemaMap. Users only need to construct encryptedFieldsEncryptedFieldConfig for ClientEncryption.CreateEncryptedCollection.
AutoEncryptionOptions.SchemaMap
is map[string]interface{}
.
But, what exactly is the structure of encryptedFields on the server? map[string]string?
The server IDL has the definition. Here is an example:
{
"encryptedFields" : {
"escCollection" : "fle2.testColl.esc",
"eccCollection" : "fle2.testColl.ecc",
"ecocCollection" : "fle2.testColl.ecoc",
"fields" : [
{
"keyId" : UUID("11d58b8a-0c6c-4d69-a0bd-70c6d9befae9"),
"path" : "encryptedField",
"bsonType" : "string",
"queries" : {
"queryType" : "equality",
"contention" : NumberLong(0)
}
},
{
"keyId" : UUID("11d58b8a-0c6c-4d69-a0bd-70c6d9befae9"),
"path" : "nested.otherEncryptedField",
"bsonType" : "string",
"queries" : [
{
"queryType" : "equality",
"contention" : NumberLong(0)
}
]
}
]
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the quick response to the feedback! A few more questions.
mongo/database.go
Outdated
} | ||
|
||
// getEncryptedStateCollectionName returns the encrypted state collection name associated with dataCollectionName. | ||
func getEncryptedStateCollectionName(efBSON *bsoncore.Document, dataCollectionName string, stateCollectionSuffix string) (*string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this return *string
instead of just string
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to return nil
on error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm ok; I suppose you could just return ""
on error, since you're probably not checking the string value if the returned error
is non-nil. Up to you, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning a string
and the string zero-value (""
) on error is typically more idiomatic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to return string
.
@@ -55,6 +56,9 @@ var ( | |||
// i/o timeout. | |||
"Ignore network timeout error on find": godriver2123SkipReason, | |||
"Network error on minPoolSize background creation": godriver2123SkipReason, | |||
"CreateCollection from encryptedFields.": godriver2413SkipReason, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this test also try to drop the collection with encrypted fields as an option for Drop
? Why are we skipping this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It uses Drop
with encrypted fields for test cleanup. Added a non-specification test: TestFLE2CreateCollection
to test the behavior from this specification test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome thanks for adding that local test.
Tests skipped spec test behavior from the "CreateCollection from encryptedFields." test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Great work 😄
mongo/database.go
Outdated
return nil, fmt.Errorf("expected encryptedFields of %v to be document, got %v", collectionName, rawValue.Type) | ||
} | ||
|
||
return &encryptedFields, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to pass by reference here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Updated to return without taking address.
mongo/database.go
Outdated
} | ||
|
||
// getEncryptedStateCollectionName returns the encrypted state collection name associated with dataCollectionName. | ||
func getEncryptedStateCollectionName(efBSON *bsoncore.Document, dataCollectionName string, stateCollectionSuffix string) (*string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm ok; I suppose you could just return ""
on error, since you're probably not checking the string value if the returned error
is non-nil. Up to you, though.
@@ -55,6 +56,9 @@ var ( | |||
// i/o timeout. | |||
"Ignore network timeout error on find": godriver2123SkipReason, | |||
"Network error on minPoolSize background creation": godriver2123SkipReason, | |||
"CreateCollection from encryptedFields.": godriver2413SkipReason, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome thanks for adding that local test.
mongo/database.go
Outdated
} | ||
|
||
// getEncryptedStateCollectionName returns the encrypted state collection name associated with dataCollectionName. | ||
func getEncryptedStateCollectionName(efBSON *bsoncore.Document, dataCollectionName string, stateCollectionSuffix string) (*string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning a string
and the string zero-value (""
) on error is typically more idiomatic.
mongo/database.go
Outdated
} | ||
|
||
// getEncryptedStateCollectionName returns the encrypted state collection name associated with dataCollectionName. | ||
func getEncryptedStateCollectionName(efBSON *bsoncore.Document, dataCollectionName string, stateCollectionSuffix string) (*string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the efBSON
param be a bsoncore.Document
instead of a *bsoncore.Document
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍 , pending resolution of the questions about the getEncryptedStateCollectionName
function signature.
GODRIVER-2391
GODRIVER-2404
Summary
EncryptedFieldsMap
toAutoEncryptionOpts
EncryptedFields
toCreateCollectionOptions
and required behavior.DropCollectionOptions
withEncryptedFields
and required behavior.Background & Motivation
Please see mongodb/specifications#1183 for the specification changes.
The name for the FLE 2.0 feature is still being decided by product. I left it out of public API documentation.
The fle2-CreateCollection test is written in the Client Side Encryption specification test format.