diff options
author | Oleg Doronin <dorooleg@yandex.ru> | 2024-09-24 19:12:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 20:12:28 +0300 |
commit | 5807f623fc0a5845bb3e15caebf368bf223eb67b (patch) | |
tree | a5966f5098ca06b692e6ca73b9ea92c499733981 | |
parent | ddd43c1dfcf3f3f3ad358fe0b5c7f7ed5153b019 (diff) | |
download | ydb-5807f623fc0a5845bb3e15caebf368bf223eb67b.tar.gz |
shared secrets have been supported (#9553)
-rw-r--r-- | ydb/core/external_sources/s3/ut/s3_aws_credentials_ut.cpp | 62 | ||||
-rw-r--r-- | ydb/core/kqp/federated_query/kqp_federated_query_actors.cpp | 36 | ||||
-rw-r--r-- | ydb/services/metadata/secret/snapshot.cpp | 14 | ||||
-rw-r--r-- | ydb/services/metadata/secret/snapshot.h | 1 |
4 files changed, 102 insertions, 11 deletions
diff --git a/ydb/core/external_sources/s3/ut/s3_aws_credentials_ut.cpp b/ydb/core/external_sources/s3/ut/s3_aws_credentials_ut.cpp index 08ddac807eb..0369aabea5c 100644 --- a/ydb/core/external_sources/s3/ut/s3_aws_credentials_ut.cpp +++ b/ydb/core/external_sources/s3/ut/s3_aws_credentials_ut.cpp @@ -61,7 +61,9 @@ Y_UNIT_TEST_SUITE(S3AwsCredentials) { AWS_ACCESS_KEY_ID_SECRET_NAME="id", AWS_SECRET_ACCESS_KEY_SECRET_NAME="key", AWS_REGION="ru-central-1" - );)", + ); + GRANT ALL ON `{external_source}` TO `root1@builtin`; + )", "external_source"_a = externalDataSourceName, "location"_a = "localhost:" + GetExternalPort("minio", "9000") + "/datalake/" ); @@ -125,6 +127,64 @@ Y_UNIT_TEST_SUITE(S3AwsCredentials) { UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnParser(0).GetUtf8(), "2"); UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnParser(1).GetUtf8(), "hello world"); } + + { + auto db = kikimr->GetQueryClient(NYdb::NQuery::TClientSettings().AuthToken("root1@builtin")); + { + auto scriptExecutionOperation = db.ExecuteScript(fmt::format(R"( + SELECT * FROM `{external_source}`.`/a/` WITH ( + format="json_each_row", + schema( + key Utf8 NOT NULL, + value Utf8 NOT NULL + ) + ) + )", "external_source"_a = externalDataSourceName)).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(scriptExecutionOperation.Status().GetStatus(), EStatus::SUCCESS, scriptExecutionOperation.Status().GetIssues().ToString()); + UNIT_ASSERT(scriptExecutionOperation.Metadata().ExecutionId); + + NYdb::NQuery::TScriptExecutionOperation readyOp = WaitScriptExecutionOperation(scriptExecutionOperation.Id(), kikimr->GetDriver()); + UNIT_ASSERT_EQUAL_C(readyOp.Metadata().ExecStatus, EExecStatus::Failed, readyOp.Status().GetIssues().ToString()); + UNIT_ASSERT_STRING_CONTAINS_C(readyOp.Status().GetIssues().ToString(), "secret with name 'id' not found", readyOp.Status().GetIssues().ToString()); + } + { + const TString query = R"( + CREATE OBJECT `id:root1@builtin` (TYPE SECRET_ACCESS); + CREATE OBJECT `key:root1@builtin` (TYPE SECRET_ACCESS); + )"; + auto result = session.ExecuteSchemeQuery(query).GetValueSync(); + UNIT_ASSERT_C(result.GetStatus() == NYdb::EStatus::SUCCESS, result.GetIssues().ToString()); + } + { + auto scriptExecutionOperation = db.ExecuteScript(fmt::format(R"( + SELECT * FROM `{external_source}`.`/a/` WITH ( + format="json_each_row", + schema( + key Utf8 NOT NULL, + value Utf8 NOT NULL + ) + ) + )", "external_source"_a = externalDataSourceName)).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(scriptExecutionOperation.Status().GetStatus(), EStatus::SUCCESS, scriptExecutionOperation.Status().GetIssues().ToString()); + UNIT_ASSERT(scriptExecutionOperation.Metadata().ExecutionId); + + NYdb::NQuery::TScriptExecutionOperation readyOp = WaitScriptExecutionOperation(scriptExecutionOperation.Id(), kikimr->GetDriver()); + UNIT_ASSERT_EQUAL_C(readyOp.Metadata().ExecStatus, EExecStatus::Completed, readyOp.Status().GetIssues().ToString()); + TFetchScriptResultsResult results = db.FetchScriptResults(scriptExecutionOperation.Id(), 0).ExtractValueSync(); + UNIT_ASSERT_C(results.IsSuccess(), results.GetIssues().ToString()); + + TResultSetParser resultSet(results.ExtractResultSet()); + UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnsCount(), 2); + UNIT_ASSERT_VALUES_EQUAL(resultSet.RowsCount(), 2); + UNIT_ASSERT(resultSet.TryNextRow()); + UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnParser(0).GetUtf8(), "1"); + UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnParser(1).GetUtf8(), "trololo"); + UNIT_ASSERT(resultSet.TryNextRow()); + UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnParser(0).GetUtf8(), "2"); + UNIT_ASSERT_VALUES_EQUAL(resultSet.ColumnParser(1).GetUtf8(), "hello world"); + } + } + } } diff --git a/ydb/core/kqp/federated_query/kqp_federated_query_actors.cpp b/ydb/core/kqp/federated_query/kqp_federated_query_actors.cpp index c6150636e5d..6cc75e9915b 100644 --- a/ydb/core/kqp/federated_query/kqp_federated_query_actors.cpp +++ b/ydb/core/kqp/federated_query/kqp_federated_query_actors.cpp @@ -20,17 +20,31 @@ class TDescribeSecretsActor: public NActors::TActorBootstrapped<TDescribeSecrets secretValues.reserve(SecretIds.size()); for (const auto& secretId: SecretIds) { TString secretValue; - const bool isFound = snapshot->GetSecretValue(NMetadata::NSecret::TSecretIdOrValue::BuildAsId(secretId), secretValue); - if (!isFound) { - if (!AskSent) { - AskSent = true; - Send(NMetadata::NProvider::MakeServiceId(SelfId().NodeId()), new NMetadata::NProvider::TEvAskSnapshot(GetSecretsSnapshotParser())); - } else { - CompleteAndPassAway(TEvDescribeSecretsResponse::TDescription(Ydb::StatusIds::BAD_REQUEST, { NYql::TIssue("secret with name '" + secretId.GetSecretId() + "' not found") })); - } + bool isFound = snapshot->GetSecretValue(NMetadata::NSecret::TSecretIdOrValue::BuildAsId(secretId), secretValue); + if (isFound) { + secretValues.push_back(secretValue); + continue; + } + + auto secretIds = snapshot->GetSecretIds(UserToken, secretId.GetSecretId()); + if (secretIds.size() > 1) { + CompleteAndPassAway(TEvDescribeSecretsResponse::TDescription(Ydb::StatusIds::BAD_REQUEST, { NYql::TIssue("several secrets with name '" + secretId.GetSecretId() + "' were found") })); return; } - secretValues.push_back(secretValue); + + isFound = !secretIds.empty() && snapshot->GetSecretValue(NMetadata::NSecret::TSecretIdOrValue::BuildAsId(secretIds[0]), secretValue); + if (isFound) { + secretValues.push_back(secretValue); + continue; + } + + if (!AskSent) { + AskSent = true; + Send(NMetadata::NProvider::MakeServiceId(SelfId().NodeId()), new NMetadata::NProvider::TEvAskSnapshot(GetSecretsSnapshotParser())); + } else { + CompleteAndPassAway(TEvDescribeSecretsResponse::TDescription(Ydb::StatusIds::BAD_REQUEST, { NYql::TIssue("secret with name '" + secretId.GetSecretId() + "' not found") })); + } + return; } CompleteAndPassAway(TEvDescribeSecretsResponse::TDescription(secretValues)); @@ -49,7 +63,8 @@ class TDescribeSecretsActor: public NActors::TActorBootstrapped<TDescribeSecrets public: TDescribeSecretsActor(const TString& ownerUserId, const std::vector<TString>& secretIds, NThreading::TPromise<TEvDescribeSecretsResponse::TDescription> promise) - : SecretIds(CreateSecretIds(ownerUserId, secretIds)) + : UserToken(NACLib::TUserToken{ownerUserId, TVector<NACLib::TSID>{}}) + , SecretIds(CreateSecretIds(ownerUserId, secretIds)) , Promise(promise) {} @@ -74,6 +89,7 @@ private: } private: + std::optional<NACLib::TUserToken> UserToken; const std::vector<NMetadata::NSecret::TSecretId> SecretIds; NThreading::TPromise<TEvDescribeSecretsResponse::TDescription> Promise; bool AskSent = false; diff --git a/ydb/services/metadata/secret/snapshot.cpp b/ydb/services/metadata/secret/snapshot.cpp index 26aa9ca7bd5..2a1a38121fb 100644 --- a/ydb/services/metadata/secret/snapshot.cpp +++ b/ydb/services/metadata/secret/snapshot.cpp @@ -75,4 +75,18 @@ bool TSnapshot::GetSecretValue(const TSecretIdOrValue& sId, TString& result) con return true; } +std::vector<TSecretId> TSnapshot::GetSecretIds(const std::optional<NACLib::TUserToken>& userToken, const TString& secretId) const { + std::vector<TSecretId> secretIds; + for (const auto& [key, value]: Secrets) { + if (key.GetSecretId() != secretId) { + continue; + } + if (!CheckSecretAccess(NMetadata::NSecret::TSecretIdOrValue::BuildAsId(key), userToken)) { + continue; + } + secretIds.push_back(key); + } + return secretIds; +} + } diff --git a/ydb/services/metadata/secret/snapshot.h b/ydb/services/metadata/secret/snapshot.h index 9acff259c7a..6b1f97871d6 100644 --- a/ydb/services/metadata/secret/snapshot.h +++ b/ydb/services/metadata/secret/snapshot.h @@ -21,6 +21,7 @@ public: bool CheckSecretAccess(const TSecretIdOrValue& sIdOrValue, const std::optional<NACLib::TUserToken>& userToken) const; bool PatchString(TString& stringForPath) const; bool GetSecretValue(const TSecretIdOrValue& secretId, TString& result) const; + std::vector<TSecretId> GetSecretIds(const std::optional<NACLib::TUserToken>& userToken, const TString& secretId) const; }; } |