Skip to content

[CDRIVER-4454] Automatic Azure KMS Credentials #1097

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

Merged

Conversation

vector-of-bool
Copy link
Contributor

Refer: CDRIVER-4454

This implements automatic KMS credentials for Azure, in the same manner as are available for AWS.

To optimize for test-ability in the absence of an Azure environment, the following changes are made:

  1. The private HTTP API was refactored to allow inspection of the HTTP request string that would be sent. This way we can build a function that constructs an HTTP request, and then check it against a known-good request message, no HTTP server needed. This alleviates the necessity to have a "mock server" for the API, as we can assume that the proper server, when presented with such a known-good request, will respond as we expect it to. This assumes that the internal HTTP code sends/receives HTTP correctly, but that proposition can be validated and tested without implementing a fake Azure IMDS API server.
  2. The Azure code is implemented as 1) a request-generator that fills in an HTTP request object, and 2) A JSON-response parser that inspects the HTTP JSON body and decomposes it according to the Azure schema. Because (2) does not perform actual I/O, we can simply feed it known-good and known-bad JSON strings and validate that it behaves appropriately, and therefore assume that it will behave correctly later on when fed the actual HTTP responses from an IMDS server.

bson_set_error (
error,
MONGOC_ERROR_PROTOCOL_ERROR,
64,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 64 is arbitrary. The error domain/code system is getting pretty messy. What should be done to make this more useful?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the error codes in each domain can have a different meaning. Two domains can have the same error code.

Consider adding an error code to mongoc_error_code_t, like MONGOC_ERROR_PROTOCOL_HTTP to signal an error in an HTTP response.

Comment on lines +2682 to +2687
#define TEST_INSTALL(FuncName) \
if (1) { \
extern void FuncName (TestSuite *suite); \
FuncName (&suite); \
} else \
((void) 0)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a drive-by change to reduce some tedium in adding tests. Can be reverted/moved.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I like it.

@vector-of-bool vector-of-bool marked this pull request as ready for review August 26, 2022 01:18
@kevinAlbs kevinAlbs requested a review from eramongodb August 27, 2022 14:12
This allows easier code review, informal verification, and testing
@vector-of-bool
Copy link
Contributor Author

The HTTP retry-with-backoff logic has been moved to a separate function that doesn't concern itself with the request content. This allows easier informal verification of both the retry logic as well as code that invokes that that function.

Comment on lines +2682 to +2687
#define TEST_INSTALL(FuncName) \
if (1) { \
extern void FuncName (TestSuite *suite); \
FuncName (&suite); \
} else \
((void) 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I like it.

Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, LGTM!

Copy link
Contributor

@eramongodb eramongodb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last question regarding header file naming; otherwise, LGTM.

@vector-of-bool
Copy link
Contributor Author

The three added commits can be viewed in isolation in commit order to build off of each other.

@@ -71,8 +71,12 @@ mcd_azure_access_token_try_init_from_json_str (mcd_azure_access_token *out,
// token_type
found = bson_iter_init_find (&iter, &bson, "token_type");
const char *const token_type = !found ? NULL : bson_iter_utf8 (&iter, NULL);
// expires_on
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"expires_in"

*/
static bool
_try_add_azure_from_env (bson_t *out, bson_error_t *error)
_request_new_azure_mid_token (mcd_azure_access_token *out, bson_error_t *error)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "mid" refer to?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"managed identity" in this case. I can change that if it is unclear.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is the only reference to "mid", I suggest renaming to _request_new_azure_access_token or defining "mid" in a comment.

// The token is still valid for another minute
} else {
// The token is about to expire. Destroy it. We will then ask IMDS for
// a new oen.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"one"


#define RAW_STRING(...) #__VA_ARGS__

void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void
static void

mcd_azure_access_token_destroy (&token);
}

void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void
static void

Copy link
Contributor

@eramongodb eramongodb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New files should probably include copyright notices.
One minor question; otherwise LGTM.

Comment on lines 9 to 11
#ifdef __cplusplus
extern "C" {
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem particularly necessary. Remove?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Practically unecessary because everything is static and therefore bounded to the TU. This just becomes a habit when creating C headers.

@vector-of-bool vector-of-bool merged commit 686bff8 into mongodb:master Sep 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants