Coverage Report

Created: 2026-09-03 13:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
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
11
std::string get_valid_ca_cert_path(const std::vector<std::string>& ca_cert_file_paths) {
139
11
    for (const auto& path : ca_cert_file_paths) {
140
11
        if (std::filesystem::exists(path)) {
141
10
            return path;
142
10
        }
143
11
    }
144
1
    return "";
145
11
}
146
147
void set_s3_client_default_http_scheme(Aws::Client::ClientConfiguration& client_config,
148
31
                                       const std::string& scheme) {
149
31
    if (client_config.endpointOverride.starts_with("http://") ||
150
31
        client_config.endpointOverride.starts_with("https://")) {
151
6
        return;
152
6
    }
153
25
    client_config.scheme = scheme == "http" ? Aws::Http::Scheme::HTTP : Aws::Http::Scheme::HTTPS;
154
25
}
155
} // namespace doris