summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Sukhov <[email protected]>2026-06-24 14:36:22 +0300
committerGitHub <[email protected]>2026-06-24 14:36:22 +0300
commitd9d835a0fc89ce514b88eb18ef5cbdce51a1f2b2 (patch)
tree941415b4f2b629f4153d3488033c98d597758c85
parent788ed869f7d0886f60d5909de5e7c3a495797a8a (diff)
Updated yq cp cms grpc actor to provide required permissions to created sls-dbs (#42506)
-rw-r--r--ydb/core/fq/libs/compute/ydb/control_plane/cms_grpc_client_actor.cpp120
-rw-r--r--ydb/core/fq/libs/compute/ydb/control_plane/compute_database_control_plane_service.cpp2
-rw-r--r--ydb/core/fq/libs/compute/ydb/events/events.h5
-rw-r--r--ydb/core/fq/libs/config/protos/compute.proto1
4 files changed, 106 insertions, 22 deletions
diff --git a/ydb/core/fq/libs/compute/ydb/control_plane/cms_grpc_client_actor.cpp b/ydb/core/fq/libs/compute/ydb/control_plane/cms_grpc_client_actor.cpp
index 8bbdca5135a..f9e6c0ffc60 100644
--- a/ydb/core/fq/libs/compute/ydb/control_plane/cms_grpc_client_actor.cpp
+++ b/ydb/core/fq/libs/compute/ydb/control_plane/cms_grpc_client_actor.cpp
@@ -1,6 +1,7 @@
#include "ydb_grpc_helpers.h"
#include <ydb/public/api/grpc/ydb_cms_v1.grpc.pb.h>
+#include <ydb/public/api/grpc/ydb_scheme_v1.grpc.pb.h>
#include <ydb/core/fq/libs/compute/ydb/events/events.h>
#include <ydb/library/services/services.pb.h>
@@ -30,6 +31,8 @@ struct TEvPrivate {
enum EEv {
EvCreateDatabaseRequest = EventSpaceBegin(NActors::TEvents::ES_PRIVATE),
EvCreateDatabaseResponse,
+ EvModifyPermissionsRequest,
+ EvModifyPermissionsResponse,
EvListDatabasesRequest,
EvListDatabasesResponse,
@@ -40,22 +43,37 @@ struct TEvPrivate {
struct TEvCreateDatabaseRequest : NCloud::TEvGrpcProtoRequest<TEvCreateDatabaseRequest, EvCreateDatabaseRequest, Ydb::Cms::CreateDatabaseRequest> {};
struct TEvCreateDatabaseResponse : NCloud::TEvGrpcProtoResponse<TEvCreateDatabaseResponse, EvCreateDatabaseResponse, Ydb::Cms::CreateDatabaseResponse> {};
+ struct TEvModifyPermissionsRequest : NCloud::TEvGrpcProtoRequest<TEvModifyPermissionsRequest, EvModifyPermissionsRequest, Ydb::Scheme::ModifyPermissionsRequest> {};
+ struct TEvModifyPermissionsResponse : NCloud::TEvGrpcProtoResponse<TEvModifyPermissionsResponse, EvModifyPermissionsResponse, Ydb::Scheme::ModifyPermissionsResponse> {};
struct TEvListDatabasesRequest : NCloud::TEvGrpcProtoRequest<TEvListDatabasesRequest, EvListDatabasesRequest, Ydb::Cms::ListDatabasesRequest> {};
struct TEvListDatabasesResponse : NCloud::TEvGrpcProtoResponse<TEvListDatabasesResponse, EvListDatabasesResponse, Ydb::Cms::ListDatabasesResponse> {};
};
}
-class TCmsGrpcServiceActor : public NActors::TActor<TCmsGrpcServiceActor>, NGrpcActorClient::TGrpcServiceClient<Ydb::Cms::V1::CmsService> {
+class TCmsGrpcServiceActor
+ : public NActors::TActor<TCmsGrpcServiceActor>
+ , NGrpcActorClient::TGrpcServiceClient<Ydb::Cms::V1::CmsService>
+ , NGrpcActorClient::TGrpcServiceClient<Ydb::Scheme::V1::SchemeService>
+{
public:
using TBase = NActors::TActor<TCmsGrpcServiceActor>;
- struct TCreateDatabaseGrpcRequest : TGrpcRequest {
+ using TCmsGrpcClient = NGrpcActorClient::TGrpcServiceClient<Ydb::Cms::V1::CmsService>;
+ using TSchemeGrpcClient = NGrpcActorClient::TGrpcServiceClient<Ydb::Scheme::V1::SchemeService>;
+
+ struct TCreateDatabaseGrpcRequest : TCmsGrpcClient::TGrpcRequest {
static constexpr auto Request = &Ydb::Cms::V1::CmsService::Stub::AsyncCreateDatabase;
using TRequestEventType = TEvPrivate::TEvCreateDatabaseRequest;
using TResponseEventType = TEvPrivate::TEvCreateDatabaseResponse;
};
- struct TListDatabasesGrpcRequest : TGrpcRequest {
+ struct TModifyPermissionsGrpcRequest : TSchemeGrpcClient::TGrpcRequest {
+ static constexpr auto Request = &Ydb::Scheme::V1::SchemeService::Stub::AsyncModifyPermissions;
+ using TRequestEventType = TEvPrivate::TEvModifyPermissionsRequest;
+ using TResponseEventType = TEvPrivate::TEvModifyPermissionsResponse;
+ };
+
+ struct TListDatabasesGrpcRequest : TCmsGrpcClient::TGrpcRequest {
static constexpr auto Request = &Ydb::Cms::V1::CmsService::Stub::AsyncListDatabases;
using TRequestEventType = TEvPrivate::TEvListDatabasesRequest;
using TResponseEventType = TEvPrivate::TEvListDatabasesResponse;
@@ -63,7 +81,8 @@ public:
TCmsGrpcServiceActor(const NGrpcActorClient::TGrpcClientSettings& settings, const NYdb::TCredentialsProviderPtr& credentialsProvider)
: TBase(&TCmsGrpcServiceActor::StateFunc)
- , TGrpcServiceClient(settings)
+ , TCmsGrpcClient(settings)
+ , TSchemeGrpcClient(settings)
, Settings(settings)
, CredentialsProvider(credentialsProvider)
{}
@@ -71,6 +90,7 @@ public:
STRICT_STFUNC(StateFunc,
hFunc(TEvYdbCompute::TEvCreateDatabaseRequest, Handle);
hFunc(TEvPrivate::TEvCreateDatabaseResponse, Handle);
+ hFunc(TEvPrivate::TEvModifyPermissionsResponse, Handle);
hFunc(TEvYdbCompute::TEvListDatabasesRequest, Handle);
hFunc(TEvPrivate::TEvListDatabasesResponse, Handle);
)
@@ -78,9 +98,8 @@ public:
void Handle(TEvYdbCompute::TEvCreateDatabaseRequest::TPtr& ev) {
const auto& request = *ev.Get()->Get();
- const TString folderId = NYdb::NFq::TScope(request.Scope).ParseFolder();
- const TString cloudId = request.CloudId;
- const TString databaseId = GetSharedDatabaseId(request.BasePath);
+ const TString folderId = request.SharedFolderId;
+ const TString databaseId = GetPathLastComponent(request.Path);
auto forwardRequest = std::make_unique<TEvPrivate::TEvCreateDatabaseRequest>();
forwardRequest->Request.mutable_operation_params()->set_operation_mode(Ydb::Operations::OperationParams::SYNC);
@@ -88,16 +107,13 @@ public:
if (!folderId.empty()) {
forwardRequest->Request.mutable_attributes()->emplace("folder_id", folderId);
}
- if (!cloudId.empty()) {
- forwardRequest->Request.mutable_attributes()->emplace("cloud_id", cloudId);
- }
if (!databaseId.empty()) {
forwardRequest->Request.mutable_attributes()->emplace("database_id", databaseId);
}
forwardRequest->Request.set_path(request.Path);
SetYdbRequestToken(*forwardRequest, CredentialsProvider->GetAuthInfo());
TEvPrivate::TEvCreateDatabaseRequest::TPtr forwardEvent = (NActors::TEventHandle<TEvPrivate::TEvCreateDatabaseRequest>*)new IEventHandle(SelfId(), SelfId(), forwardRequest.release(), 0, Cookie);
- MakeCall<TCreateDatabaseGrpcRequest>(std::move(forwardEvent));
+ TCmsGrpcClient::MakeCall<TCreateDatabaseGrpcRequest>(std::move(forwardEvent));
Requests[Cookie++] = ev;
}
@@ -138,11 +154,41 @@ public:
return;
}
- forwardResponse->Result.set_id(request.Get()->Get()->Path);
- forwardResponse->Result.mutable_connection()->set_endpoint(request->Get()->ExecutionConnection.GetEndpoint());
- forwardResponse->Result.mutable_connection()->set_database(request.Get()->Get()->Path);
- forwardResponse->Result.mutable_connection()->set_usessl(request->Get()->ExecutionConnection.GetUseSsl());
+ ModifyDatabasePermissions(request);
+ }
+
+ void Handle(TEvPrivate::TEvModifyPermissionsResponse::TPtr& ev) {
+ const auto& status = ev->Get()->Status;
+ auto it = ModifyPermissionsRequests.find(ev->Cookie);
+ if (it == ModifyPermissionsRequests.end()) {
+ LOG_E("Request doesn't exist (ModifyPermissionsResponse). Need to fix this bug urgently");
+ return;
+ }
+ auto request = it->second;
+ ModifyPermissionsRequests.erase(it);
+
+ auto forwardResponse = std::make_unique<TEvYdbCompute::TEvCreateDatabaseResponse>();
+ if (!status.Ok()) {
+ forwardResponse->Issues.AddIssue("GrpcCode: " + ToString(status.GRpcStatusCode));
+ forwardResponse->Issues.AddIssue("Message: " + status.Msg);
+ forwardResponse->Issues.AddIssue("Details: " + status.Details);
+ Send(request->Sender, forwardResponse.release(), 0, request->Cookie);
+ return;
+ }
+
+ const auto& operation = ev->Get()->Response.operation();
+ if (operation.status() != Ydb::StatusIds::SUCCESS) {
+ forwardResponse->Issues.AddIssue(TStringBuilder() << "YDB operation status: " << operation.status());
+
+ NYql::TIssues operationIssues;
+ NYql::IssuesFromMessage(operation.issues(), operationIssues);
+ forwardResponse->Issues.AddIssues(std::move(operationIssues));
+ Send(request->Sender, forwardResponse.release(), 0, request->Cookie);
+ return;
+ }
+
+ FillCreateDatabaseResponse(*forwardResponse, request);
Send(request->Sender, forwardResponse.release(), 0, request->Cookie);
}
@@ -150,7 +196,7 @@ public:
auto forwardRequest = std::make_unique<TEvPrivate::TEvListDatabasesRequest>();
SetYdbRequestToken(*forwardRequest, CredentialsProvider->GetAuthInfo());
TEvPrivate::TEvListDatabasesRequest::TPtr forwardEvent = (NActors::TEventHandle<TEvPrivate::TEvListDatabasesRequest>*)new IEventHandle(SelfId(), SelfId(), forwardRequest.release(), 0, Cookie);
- MakeCall<TListDatabasesGrpcRequest>(std::move(forwardEvent));
+ TCmsGrpcClient::MakeCall<TListDatabasesGrpcRequest>(std::move(forwardEvent));
Requests[Cookie++] = ev;
}
@@ -188,18 +234,52 @@ public:
}
private:
- TString GetSharedDatabaseId(const TString& basePath) const {
- size_t dbIdInd = basePath.find_last_of("/");
- if (dbIdInd == TString::npos || dbIdInd >= basePath.size() - 1) {
+ TString GetPathLastComponent(const TString& path) const {
+ size_t dbIdInd = path.find_last_of("/");
+ if (dbIdInd == TString::npos) {
+ return path;
+ }
+ if (dbIdInd >= path.size() - 1) {
return "";
}
dbIdInd++;
- return basePath.substr(dbIdInd, basePath.size() - dbIdInd);
+ return path.substr(dbIdInd, path.size() - dbIdInd);
+ }
+
+ void ModifyDatabasePermissions(TEvYdbCompute::TEvCreateDatabaseRequest::TPtr request) {
+ const TString databaseId = GetPathLastComponent(request->Get()->Path);
+ if (databaseId.empty()) {
+ auto forwardResponse = std::make_unique<TEvYdbCompute::TEvCreateDatabaseResponse>();
+ forwardResponse->Issues.AddIssue(TStringBuilder() << "Cannot get database_id from path: " << request->Get()->Path);
+ Send(request->Sender, forwardResponse.release(), 0, request->Cookie);
+ return;
+ }
+
+ auto forwardRequest = std::make_unique<TEvPrivate::TEvModifyPermissionsRequest>();
+ forwardRequest->Request.mutable_operation_params()->set_operation_mode(Ydb::Operations::OperationParams::SYNC);
+ forwardRequest->Request.set_path(request->Get()->Path);
+
+ auto* grant = forwardRequest->Request.add_actions()->mutable_grant();
+ grant->set_subject(TStringBuilder() << "ydb.databases.connect-" << databaseId << "@as");
+ grant->add_permission_names("ydb.generic.connect");
+
+ SetYdbRequestToken(*forwardRequest, CredentialsProvider->GetAuthInfo());
+ TEvPrivate::TEvModifyPermissionsRequest::TPtr forwardEvent = (NActors::TEventHandle<TEvPrivate::TEvModifyPermissionsRequest>*)new IEventHandle(SelfId(), SelfId(), forwardRequest.release(), 0, Cookie);
+ TSchemeGrpcClient::MakeCall<TModifyPermissionsGrpcRequest>(std::move(forwardEvent));
+ ModifyPermissionsRequests[Cookie++] = request;
+ }
+
+ void FillCreateDatabaseResponse(TEvYdbCompute::TEvCreateDatabaseResponse& response, const TEvYdbCompute::TEvCreateDatabaseRequest::TPtr& request) const {
+ response.Result.set_id(request.Get()->Get()->Path);
+ response.Result.mutable_connection()->set_endpoint(request->Get()->ExecutionConnection.GetEndpoint());
+ response.Result.mutable_connection()->set_database(request.Get()->Get()->Path);
+ response.Result.mutable_connection()->set_usessl(request->Get()->ExecutionConnection.GetUseSsl());
}
NGrpcActorClient::TGrpcClientSettings Settings;
TMap<uint64_t, std::variant<TEvYdbCompute::TEvCreateDatabaseRequest::TPtr, TEvYdbCompute::TEvListDatabasesRequest::TPtr>> Requests;
+ TMap<uint64_t, TEvYdbCompute::TEvCreateDatabaseRequest::TPtr> ModifyPermissionsRequests;
NYdb::TCredentialsProviderPtr CredentialsProvider;
int64_t Cookie = 0;
};
diff --git a/ydb/core/fq/libs/compute/ydb/control_plane/compute_database_control_plane_service.cpp b/ydb/core/fq/libs/compute/ydb/control_plane/compute_database_control_plane_service.cpp
index 26d4fa476bb..143633ad876 100644
--- a/ydb/core/fq/libs/compute/ydb/control_plane/compute_database_control_plane_service.cpp
+++ b/ydb/core/fq/libs/compute/ydb/control_plane/compute_database_control_plane_service.cpp
@@ -194,7 +194,7 @@ public:
return;
}
FillRequest(Request, client->Config);
- Send(client->ActorId, new TEvYdbCompute::TEvCreateDatabaseRequest{Request->Get()->CloudId, Scope, Request->Get()->BasePath, Request->Get()->Path, client->Config.GetExecutionConnection()}, 0, ev->Cookie);
+ Send(client->ActorId, new TEvYdbCompute::TEvCreateDatabaseRequest{Request->Get()->CloudId, Scope, Request->Get()->BasePath, Request->Get()->Path, client->Config.GetExecutionConnection(), client->Config.GetFolderId()}, 0, ev->Cookie);
}
void Handle(TEvYdbCompute::TEvAddDatabaseResponse::TPtr& ev) {
diff --git a/ydb/core/fq/libs/compute/ydb/events/events.h b/ydb/core/fq/libs/compute/ydb/events/events.h
index d177a019bb9..903965be42b 100644
--- a/ydb/core/fq/libs/compute/ydb/events/events.h
+++ b/ydb/core/fq/libs/compute/ydb/events/events.h
@@ -227,12 +227,14 @@ struct TEvYdbCompute {
const TString& scope,
const TString& basePath,
const TString& path,
- const NFq::NConfig::TYdbStorageConfig& executionConnection)
+ const NFq::NConfig::TYdbStorageConfig& executionConnection,
+ const TString& sharedFolderId = {})
: CloudId(cloudId)
, Scope(scope)
, BasePath(basePath)
, Path(path)
, ExecutionConnection(executionConnection)
+ , SharedFolderId(sharedFolderId)
{}
TString CloudId;
@@ -240,6 +242,7 @@ struct TEvYdbCompute {
TString BasePath;
TString Path;
NFq::NConfig::TYdbStorageConfig ExecutionConnection;
+ TString SharedFolderId;
};
struct TEvCreateDatabaseResponse : public NActors::TEventLocal<TEvCreateDatabaseResponse, EvCreateDatabaseResponse> {
diff --git a/ydb/core/fq/libs/config/protos/compute.proto b/ydb/core/fq/libs/config/protos/compute.proto
index 97af67febcd..1789bb2bb4b 100644
--- a/ydb/core/fq/libs/config/protos/compute.proto
+++ b/ydb/core/fq/libs/config/protos/compute.proto
@@ -56,6 +56,7 @@ message TComputeDatabaseConfig {
TLoadControlConfig LoadControlConfig = 4;
TWorkloadManagerConfig WorkloadManagerConfig = 5;
TAccessConfig AccessConfig = 8;
+ string FolderId = 9;
}
message TDatabaseMapping {