-
Notifications
You must be signed in to change notification settings - Fork 4k
[DO NOT MERGE, WIP]Add support to fetch cacertfiles from Amazon S3 #14572
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
Conversation
031d6b0 to
e711234
Compare
lukebakken
left a comment
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.
Let's chat about cacerts.
| lists:foreach(fun({_Key, Arn, Handler}) -> | ||
| case resolve_arn(Arn) of | ||
| {ok, Content} -> | ||
| FilePath = write_to_file(Arn, Content), |
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.
There is no need to write these files to the filesystem if we use the cacerts configuration option. Please see this discussion for more information:
|
|
||
| %% Export all for unit tests | ||
| -ifdef(TEST). | ||
| -compile(export_all). |
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.
It would be better to be specific about which functions are exported for tests.
|
|
||
| -spec resolve_arn(string()) -> {ok, binary()} | {error, term()}. | ||
| resolve_arn(Arn) -> | ||
| ?LOG_INFO("Attempting to resolve ARN: ~p", [Arn]), |
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.
| ?LOG_INFO("Attempting to resolve ARN: ~p", [Arn]), | |
| ?LOG_DEBUG("aws arn: resolving: ~p", [Arn]), |
| end, | ||
| ?LOG_INFO("Fetched ARN ~p and stored to ~p", [Arn, FilePath]); | ||
| {error, Reason} -> | ||
| ?LOG_ERROR("Failed to resolve ARN ~p: ~p", [Arn, Reason]) |
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.
| ?LOG_ERROR("Failed to resolve ARN ~p: ~p", [Arn, Reason]) | |
| ?LOG_ERROR("aws arn: failed to resolve ~p: ~p", [Arn, Reason]) |
| ldap_ssl_options_cacertfile -> | ||
| update_env(rabbitmq_auth_backend_ldap, ssl_options, cacertfile, FilePath) | ||
| end, | ||
| ?LOG_INFO("Fetched ARN ~p and stored to ~p", [Arn, FilePath]); |
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.
| ?LOG_INFO("Fetched ARN ~p and stored to ~p", [Arn, FilePath]); | |
| ?LOG_INFO("aws arn: fetched ~p and stored to ~p", [Arn, FilePath]); |
| {ok, #{service := "s3"}} -> | ||
| fetch_s3_object(Arn); | ||
| {ok, #{service := Service}} -> | ||
| ?LOG_ERROR("Unsupported service: ~p", [Service]), |
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.
| ?LOG_ERROR("Unsupported service: ~p", [Service]), | |
| ?LOG_ERROR("aws arn: unsupported service: ~p", [Service]), |
| ?LOG_ERROR("Unsupported service: ~p", [Service]), | ||
| {error, {unsupported_service, Service}}; | ||
| {error, _} = Error -> | ||
| ?LOG_ERROR("Failed to parse ARN ~p: ~p", [Arn, 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.
| ?LOG_ERROR("Failed to parse ARN ~p: ~p", [Arn, Error]), | |
| ?LOG_ERROR("aws arn: failed to parse ~p: ~p", [Arn, Error]), |
| case binary:split(ArnBin, <<":">>, [global]) of | ||
| [<<"arn">>, Partition, Service, Region, Account, Resource] -> | ||
| {ok, #{ | ||
| partition => binary_to_list(Partition), |
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 are we doing conversions to lists 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.
+1 I also noted the conversion here. The input from {mapping, "aws.arns.auth_ldap.ssl_options.cacertfile", "rabbit.aws_arns", [{datatype, string}]}. is a binary.Can we just use binary:split ? @sunfinite
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.
If the reason of using list is because you need to use string:tokens against the output, considering using string:lexemes which takes in either list or binary
|
An alternative to using |
e711234 to
07d22a9
Compare
07d22a9 to
789669f
Compare
|
|
7df552b to
baf7519
Compare
| {ok, ExistingConfig} -> ExistingConfig; | ||
| undefined -> [] | ||
| end, | ||
| NewConfig = lists:keystore(Key, 1, Config, {Key, Value}), |
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.
This code applies if the configuration value is of type list. However, for many config, they are just a tuple. For example, when you run
rabbitmqctl eval "application:get_all_env(rabbitmq_auth_backend_ldap)."
assuming you have configured the ldap, you will get:
[...
{ssl_options,[{verify,verify_none}]},
{user_dn_pattern,"${username}"},
..
]
some fields are array while others are just tuple.
In next rev, I will create modify the code to call different functions based on the nature of the configuration
2777062 to
903ef14
Compare
4763a64 to
5a9e4d4
Compare
ab397b0 to
03f0591
Compare
* Add comprehensive tests for the `rabbitmq_aws` cuttlefish schema. * Move `aws_prefer_imdsv2` setting to the `rabbitmq_aws` application.
… used with IMDSv2 previously.
* Update ARN handling to not require file system access for CA certs
…it_aws when it should be rabbitmq_aws
…. Solve bug where STS is called more than once. 3. Solve bugs where type mismatches happened during refactoring. 4. Solve bugs where AWS_LOG_ERROR receives more than 2 args
03f0591 to
4e96997
Compare
In collaboration with Sunfinite - thanks for kicking off first commit
Proposed Changes
Please describe the big picture of your changes here to communicate to the RabbitMQ team why we should accept this pull request.
If it fixes a bug or resolves a feature request, be sure to link to that issue.
When rabbitmq user configures or operates rabbitmq, user may want to configure rabbitmq to access information such as private CA certs/credentials etc, in AWS service rather than passing those information as local file or plain-text configuration to improve security and usability. For example, if user intends to configure LDAP for authentication and authorization, user as of today needs to define a local certs file and inform rabbitmq with config or environment variable .
With this AWS Resource Fetcher feature, user can pass in Amazon Resource Name(ARN) of the certs through new configuration schema eg:
aws.arns.auth_ldap.ssl_options.cacertfile. The fetcher will fetch the relevant cert files from AWS S3 from user's account and assign it to the appropriate LDAP plugin application environment.For corner case handling:
This PR is working in progress to solicit early feedbacks. We are working on to add more functionalities such as allowing customer to configure Secret Manager arn for rabbitmq to retrieve credentials.
Types of Changes
What types of changes does your code introduce to this project?
Put an
xin the boxes that applyChecklist
Put an
xin the boxes that apply.You can also fill these out after creating the PR.
This is simply a reminder of what we are going to look for before merging your code.
CONTRIBUTING.mddocumentFurther Comments
If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution
you did and what alternatives you considered, etc.