common/cpp/aws_common.cpp
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include "aws_common.h" |
19 | | |
20 | | #include <aws/core/auth/GeneralHTTPCredentialsProvider.h> |
21 | | #include <aws/core/client/ClientConfiguration.h> |
22 | | #include <aws/core/platform/Environment.h> |
23 | | #include <aws/core/utils/memory/AWSMemory.h> |
24 | | #include <glog/logging.h> |
25 | | |
26 | | namespace doris { |
27 | | |
28 | | namespace { |
29 | | const char CONTAINER_CREDENTIALS_PROVIDER_TAG[] = "ContainerCredentialsProvider"; |
30 | | } // namespace |
31 | | |
32 | 0 | CredProviderType cred_provider_type_from_pb(cloud::CredProviderTypePB cred_provider_type) { |
33 | 0 | switch (cred_provider_type) { |
34 | 0 | case cloud::CredProviderTypePB::DEFAULT: |
35 | 0 | return CredProviderType::Default; |
36 | 0 | case cloud::CredProviderTypePB::SIMPLE: |
37 | 0 | return CredProviderType::Simple; |
38 | 0 | case cloud::CredProviderTypePB::INSTANCE_PROFILE: |
39 | 0 | return CredProviderType::InstanceProfile; |
40 | 0 | case cloud::CredProviderTypePB::ENV: |
41 | 0 | return CredProviderType::Env; |
42 | 0 | case cloud::CredProviderTypePB::SYSTEM_PROPERTIES: |
43 | 0 | return CredProviderType::SystemProperties; |
44 | 0 | case cloud::CredProviderTypePB::WEB_IDENTITY: |
45 | 0 | return CredProviderType::WebIdentity; |
46 | 0 | case cloud::CredProviderTypePB::CONTAINER: |
47 | 0 | return CredProviderType::Container; |
48 | 0 | case cloud::CredProviderTypePB::ANONYMOUS: |
49 | 0 | return CredProviderType::Anonymous; |
50 | 0 | default: |
51 | 0 | __builtin_unreachable(); |
52 | 0 | LOG(WARNING) << "Invalid CredProviderTypePB value: " << cred_provider_type |
53 | 0 | << ", use default instead."; |
54 | 0 | return CredProviderType::Default; |
55 | 0 | } |
56 | 0 | } |
57 | | |
58 | 22 | CredProviderType cred_provider_type_from_string(const std::string& type) { |
59 | 22 | if (type.empty() || type == "DEFAULT") { |
60 | 1 | return CredProviderType::Default; |
61 | 1 | } |
62 | 21 | if (type == "SIMPLE") { |
63 | 0 | return CredProviderType::Simple; |
64 | 0 | } |
65 | 21 | if (type == "INSTANCE_PROFILE") { |
66 | 1 | return CredProviderType::InstanceProfile; |
67 | 1 | } |
68 | 20 | if (type == "ENV") { |
69 | 1 | return CredProviderType::Env; |
70 | 1 | } |
71 | 19 | if (type == "SYSTEM_PROPERTIES") { |
72 | 1 | return CredProviderType::SystemProperties; |
73 | 1 | } |
74 | 18 | if (type == "WEB_IDENTITY") { |
75 | 2 | return CredProviderType::WebIdentity; |
76 | 2 | } |
77 | 16 | if (type == "CONTAINER") { |
78 | 1 | return CredProviderType::Container; |
79 | 1 | } |
80 | 15 | if (type == "ANONYMOUS") { |
81 | 15 | return CredProviderType::Anonymous; |
82 | 15 | } |
83 | 15 | LOG(WARNING) << "Unknown credentials provider type: " << type << ", use default instead."; |
84 | 0 | return CredProviderType::Default; |
85 | 15 | } |
86 | | |
87 | 6 | bool container_credentials_available() { |
88 | 6 | return !Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI).empty() || |
89 | 6 | !Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_FULL_URI).empty(); |
90 | 6 | } |
91 | | |
92 | 10 | std::shared_ptr<Aws::Auth::AWSCredentialsProvider> create_container_credentials_provider() { |
93 | 10 | const auto relative_uri = Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); |
94 | 10 | const auto absolute_uri = Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_FULL_URI); |
95 | 10 | const auto token = Aws::Environment::GetEnv(AWS_CONTAINER_AUTHORIZATION_TOKEN); |
96 | 10 | const auto token_path = Aws::Environment::GetEnv(AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE); |
97 | | |
98 | | // Both URIs are forwarded and the provider decides between them: a non-empty relative URI wins |
99 | | // and is resolved against the ECS agent's address, otherwise the full URI is used as-is. This |
100 | | // is the same precedence the AWS SDK's own default chain applies. |
101 | | // |
102 | | // Both token forms are forwarded for the same reason. The endpoint authenticates every fetch |
103 | | // with a bearer token, which the provider takes either inline or as a file path, and given a |
104 | | // path it re-reads the file before each fetch. ECS sets only the inline variable, EKS Pod |
105 | | // Identity sets only the file one - so forwarding the path is what makes the Authorization header |
106 | | // non-empty under Pod Identity, and what keeps it valid once the kubelet rotates the file. |
107 | | // |
108 | | // NOTE: The header file names its third parameter authTokenFilePath and its fourth authToken, |
109 | | // but the implementation binds them the other way round. The header is the side that is wrong, |
110 | | // not the definition. This is reported as aws/aws-sdk-cpp#3143, fixed by |
111 | | // aws/aws-sdk-cpp#3162. |
112 | 10 | auto provider = Aws::MakeShared<Aws::Auth::GeneralHTTPCredentialsProvider>( |
113 | 10 | CONTAINER_CREDENTIALS_PROVIDER_TAG, relative_uri, absolute_uri, token, token_path); |
114 | | |
115 | 10 | const bool uses_relative_uri = !relative_uri.empty(); |
116 | 10 | const char* const uri_var = uses_relative_uri ? AWS_CONTAINER_CREDENTIALS_RELATIVE_URI |
117 | 10 | : AWS_CONTAINER_CREDENTIALS_FULL_URI; |
118 | 10 | const auto& uri = uses_relative_uri ? relative_uri : absolute_uri; |
119 | | |
120 | 10 | if (relative_uri.empty() && absolute_uri.empty()) { |
121 | 2 | LOG(WARNING) << "Container credentials provider has no endpoint to call and will return no " |
122 | 2 | "credentials: neither " |
123 | 2 | << AWS_CONTAINER_CREDENTIALS_RELATIVE_URI << " nor " |
124 | 2 | << AWS_CONTAINER_CREDENTIALS_FULL_URI << " is set."; |
125 | 8 | } else { |
126 | 8 | LOG(INFO) |
127 | 8 | << "Created container credentials provider from " << uri_var << ": [" << uri |
128 | 8 | << "] with a" << (token.empty() ? "n empty" : " non-empty") |
129 | 8 | << " inline authorization token and a" |
130 | 8 | << (token_path.empty() ? "n empty" : " non-empty") |
131 | 8 | << " authorization token file path: [" << token_path |
132 | 8 | << "]. If credentials come back empty, raise aws_log_level to 3 or higher for the " |
133 | 8 | "SDK's own reason."; |
134 | 8 | } |
135 | 10 | return provider; |
136 | 10 | } |
137 | | |
138 | 10 | std::string get_valid_ca_cert_path(const std::vector<std::string>& ca_cert_file_paths) { |
139 | 10 | for (const auto& path : ca_cert_file_paths) { |
140 | 10 | if (std::filesystem::exists(path)) { |
141 | 9 | return path; |
142 | 9 | } |
143 | 10 | } |
144 | 1 | return ""; |
145 | 10 | } |
146 | | |
147 | | void set_s3_client_default_http_scheme(Aws::Client::ClientConfiguration& client_config, |
148 | 27 | const std::string& scheme) { |
149 | 27 | if (client_config.endpointOverride.starts_with("http://") || |
150 | 27 | client_config.endpointOverride.starts_with("https://")) { |
151 | 5 | return; |
152 | 5 | } |
153 | 22 | client_config.scheme = scheme == "http" ? Aws::Http::Scheme::HTTP : Aws::Http::Scheme::HTTPS; |
154 | 22 | } |
155 | | } // namespace doris |