1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include "yql_generic_cluster_config.h"
#include "yql_generic_settings.h"
#include <ydb/library/yql/providers/common/structured_token/yql_token_builder.h>
#include <ydb/library/yql/utils/log/log.h>
#include <util/system/env.h>
namespace NYql {
void TGenericConfiguration::Init(const NYql::TGenericGatewayConfig& gatewayConfig,
const std::shared_ptr<NYql::IDatabaseAsyncResolver> databaseResolver,
NYql::IDatabaseAsyncResolver::TDatabaseAuthMap& databaseAuth,
const TCredentials::TPtr& credentials)
{
for (const auto& cluster : gatewayConfig.GetClusterMapping()) {
AddCluster(cluster, databaseResolver, databaseAuth, credentials);
}
// TODO: check if it's necessary
this->FreezeDefaults();
}
void TGenericConfiguration::AddCluster(const TGenericClusterConfig& clusterConfig,
const std::shared_ptr<NYql::IDatabaseAsyncResolver> databaseResolver,
NYql::IDatabaseAsyncResolver::TDatabaseAuthMap& databaseAuth,
const TCredentials::TPtr& credentials) {
ValidateGenericClusterConfig(clusterConfig, "TGenericConfiguration::AddCluster");
const auto& clusterName = clusterConfig.GetName();
const auto& databaseId = clusterConfig.GetDatabaseId();
const auto& endpoint = clusterConfig.GetEndpoint();
YQL_CLOG(DEBUG, ProviderGeneric)
<< "add cluster"
<< ": name = " << clusterName
<< ", database id = " << databaseId
<< ", endpoint = " << endpoint;
if (databaseId) {
if (!databaseResolver) {
ythrow yexception() << "You're trying to access managed database, but database resolver is not configured.";
}
const auto token = MakeStructuredToken(clusterConfig, credentials);
databaseAuth[std::make_pair(databaseId, DataSourceKindToDatabaseType(clusterConfig.GetKind()))] =
NYql::TDatabaseAuth{token, /*AddBearer=*/true, clusterConfig.GetUseSsl()};
DatabaseIdsToClusterNames[databaseId].emplace_back(clusterName);
YQL_CLOG(DEBUG, ProviderGeneric) << "database id '" << databaseId << "' added to mapping";
}
// NOTE: Tokens map is filled just because it's required by DQ/KQP.
// The only reason for provider to store these tokens is
// to keep compatibility with these engines.
// Real credentials are stored in TGenericClusterConfig.
Tokens[clusterConfig.GetName()] =
TStructuredTokenBuilder()
.SetBasicAuth(
clusterConfig.GetCredentials().basic().username(),
clusterConfig.GetCredentials().basic().password())
.ToJson();
// preserve cluster config entirely for the further use
ClusterNamesToClusterConfigs[clusterName] = clusterConfig;
// Add cluster to the list of valid clusters
this->ValidClusters.insert(clusterConfig.GetName());
}
// Structured tokens are used to access MDB API. They can be constructed either from IAM tokens, or from SA credentials.
TString TGenericConfiguration::MakeStructuredToken(const TGenericClusterConfig& cluster, const TCredentials::TPtr& credentials) const {
TStructuredTokenBuilder b;
const auto iamToken = credentials->FindCredentialContent("default_" + cluster.name(), "default_generic", cluster.GetToken());
if (iamToken) {
return b.SetIAMToken(iamToken).ToJson();
}
if (cluster.HasServiceAccountId() && cluster.HasServiceAccountIdSignature()) {
return b.SetServiceAccountIdAuth(cluster.GetServiceAccountId(), cluster.GetServiceAccountIdSignature()).ToJson();
}
ythrow yexception() << "you should either provide IAM Token via credential system or cluster config, "
"or set (ServiceAccountId && ServiceAccountIdSignature) in cluster config";
}
TGenericSettings::TConstPtr TGenericConfiguration::Snapshot() const {
return std::make_shared<const TGenericSettings>(*this);
}
bool TGenericConfiguration::HasCluster(TStringBuf cluster) const {
return ValidClusters.contains(cluster);
}
}
|