aboutsummaryrefslogtreecommitdiffstats
path: root/ydb/library/yql/providers/generic/provider/yql_generic_settings.cpp
blob: 6afb57a2efa9e20e322043501374d4d89913bbdf (plain) (blame)
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);
    }

}