diff options
| author | Ivan Sukhov <[email protected]> | 2026-06-24 14:36:22 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-06-24 14:36:22 +0300 |
| commit | d9d835a0fc89ce514b88eb18ef5cbdce51a1f2b2 (patch) | |
| tree | 941415b4f2b629f4153d3488033c98d597758c85 | |
| parent | 788ed869f7d0886f60d5909de5e7c3a495797a8a (diff) | |
Updated yq cp cms grpc actor to provide required permissions to created sls-dbs (#42506)
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 { |
