Coverage Report

Created: 2026-09-05 15:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/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
0
CredProviderType cred_provider_type_from_string(const std::string& type) {
59
0
    if (type.empty() || type == "DEFAULT") {
60
0
        return CredProviderType::Default;
61
0
    }
62
0
    if (type == "SIMPLE") {
63
0
        return CredProviderType::Simple;
64
0
    }
65
0
    if (type == "INSTANCE_PROFILE") {
66
0
        return CredProviderType::InstanceProfile;
67
0
    }
68
0
    if (type == "ENV") {
69
0
        return CredProviderType::Env;
70
0
    }
71
0
    if (type == "SYSTEM_PROPERTIES") {
72
0
        return CredProviderType::SystemProperties;
73
0
    }
74
0
    if (type == "WEB_IDENTITY") {
75
0
        return CredProviderType::WebIdentity;
76
0
    }
77
0
    if (type == "CONTAINER") {
78
0
        return CredProviderType::Container;
79
0
    }
80
0
    if (type == "ANONYMOUS") {
81
0
        return CredProviderType::Anonymous;
82
0
    }
83
0
    LOG(WARNING) << "Unknown credentials provider type: " << type << ", use default instead.";
84
0
    return CredProviderType::Default;
85
0
}
86
87
0
bool container_credentials_available() {
88
0
    return !Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI).empty() ||
89
0
           !Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_FULL_URI).empty();
90
0
}
91
92
4
std::shared_ptr<Aws::Auth::AWSCredentialsProvider> create_container_credentials_provider() {
93
4
    const auto relative_uri = Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_RELATIVE_URI);
94
4
    const auto absolute_uri = Aws::Environment::GetEnv(AWS_CONTAINER_CREDENTIALS_FULL_URI);
95
4
    const auto token = Aws::Environment::GetEnv(AWS_CONTAINER_AUTHORIZATION_TOKEN);
96
4
    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
4
    auto provider = Aws::MakeShared<Aws::Auth::GeneralHTTPCredentialsProvider>(
113
4
            CONTAINER_CREDENTIALS_PROVIDER_TAG, relative_uri, absolute_uri, token, token_path);
114
115
4
    const bool uses_relative_uri = !relative_uri.empty();
116
4
    const char* const uri_var = uses_relative_uri ? AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
117
4
                                                  : AWS_CONTAINER_CREDENTIALS_FULL_URI;
118
4
    const auto& uri = uses_relative_uri ? relative_uri : absolute_uri;
119
120
4
    if (relative_uri.empty() && absolute_uri.empty()) {
121
1
        LOG(WARNING) << "Container credentials provider has no endpoint to call and will return no "
122
1
                        "credentials: neither "
123
1
                     << AWS_CONTAINER_CREDENTIALS_RELATIVE_URI << " nor "
124
1
                     << AWS_CONTAINER_CREDENTIALS_FULL_URI << " is set.";
125
3
    } else {
126
3
        LOG(INFO)
127
3
                << "Created container credentials provider from " << uri_var << ": [" << uri
128
3
                << "] with a" << (token.empty() ? "n empty" : " non-empty")
129
3
                << " inline authorization token and a"
130
3
                << (token_path.empty() ? "n empty" : " non-empty")
131
3
                << " authorization token file path: [" << token_path
132
3
                << "]. If credentials come back empty, raise aws_log_level to 3 or higher for the "
133
3
                   "SDK's own reason.";
134
3
    }
135
4
    return provider;
136
4
}
137
138
7
std::string get_valid_ca_cert_path(const std::vector<std::string>& ca_cert_file_paths) {
139
7
    for (const auto& path : ca_cert_file_paths) {
140
7
        if (std::filesystem::exists(path)) {
141
7
            return path;
142
7
        }
143
7
    }
144
0
    return "";
145
7
}
146
147
void set_s3_client_default_http_scheme(Aws::Client::ClientConfiguration& client_config,
148
10
                                       const std::string& scheme) {
149
10
    if (client_config.endpointOverride.starts_with("http://") ||
150
10
        client_config.endpointOverride.starts_with("https://")) {
151
2
        return;
152
2
    }
153
8
    client_config.scheme = scheme == "http" ? Aws::Http::Scheme::HTTP : Aws::Http::Scheme::HTTPS;
154
8
}
155
} // namespace doris