Skip to content

Commit fc48f41

Browse files
authored
Add permissions to ydb tools dump (#6833)
1 parent 893f325 commit fc48f41

File tree

4 files changed

+64
-18
lines changed

4 files changed

+64
-18
lines changed

ydb/library/backup/backup.cpp

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace NYdb::NBackup {
3030

3131

3232
static constexpr const char *SCHEME_FILE_NAME = "scheme.pb";
33+
static constexpr const char *PERMISSIONS_FILE_NAME = "permissions.pb";
3334
static constexpr const char *INCOMPLETE_DATA_FILE_NAME = "incomplete.csv";
3435
static constexpr const char *INCOMPLETE_FILE_NAME = "incomplete";
3536
static constexpr const char *EMPTY_FILE_NAME = "empty_dir";
@@ -429,6 +430,16 @@ Ydb::Table::CreateTableRequest ProtoFromTableDescription(const NTable::TTableDes
429430
return proto;
430431
}
431432

433+
NScheme::TSchemeEntry DescribePath(TDriver driver, const TString& fullPath) {
434+
NScheme::TSchemeClient client(driver);
435+
436+
auto status = client.DescribePath(fullPath).GetValueSync();
437+
VerifyStatus(status);
438+
LOG_DEBUG("Path is described, fullPath: " << fullPath);
439+
440+
return status.GetEntry();
441+
}
442+
432443
TAsyncStatus CopyTableAsyncStart(TDriver driver, const TString& src, const TString& dst) {
433444
NTable::TTableClient client(driver);
434445

@@ -480,6 +491,19 @@ void DropTable(TDriver driver, const TString& path) {
480491
LOG_DEBUG("Table is dropped, path: " << path.Quote());
481492
}
482493

494+
void BackupPermissions(TDriver driver, const TString& dbPrefix, const TString& path, const TFsPath& folderPath) {
495+
auto entry = DescribePath(driver, JoinDatabasePath(dbPrefix, path));
496+
Ydb::Scheme::ModifyPermissionsRequest proto;
497+
entry.SerializeTo(proto);
498+
499+
TString permissionsStr;
500+
google::protobuf::TextFormat::PrintToString(proto, &permissionsStr);
501+
LOG_DEBUG("ModifyPermissionsRequest.proto: " << permissionsStr);
502+
503+
TFile outFile(folderPath.Child(PERMISSIONS_FILE_NAME), CreateAlways | WrOnly);
504+
outFile.Write(permissionsStr.data(), permissionsStr.size());
505+
}
506+
483507
void BackupTable(TDriver driver, const TString& dbPrefix, const TString& backupPrefix, const TString& path,
484508
const TFsPath& folderPath, bool schemaOnly, bool preservePoolKinds, bool ordered) {
485509
Y_ENSURE(!path.empty());
@@ -497,6 +521,8 @@ void BackupTable(TDriver driver, const TString& dbPrefix, const TString& backupP
497521
TFile outFile(folderPath.Child(SCHEME_FILE_NAME), CreateAlways | WrOnly);
498522
outFile.Write(schemaStr.data(), schemaStr.size());
499523

524+
BackupPermissions(driver, dbPrefix, path, folderPath);
525+
500526
if (!schemaOnly) {
501527
const TString pathToTemporal = JoinDatabasePath(backupPrefix, path);
502528
ReadTable(driver, desc, pathToTemporal, folderPath, ordered);
@@ -535,6 +561,14 @@ static bool IsExcluded(const TString& path, const TVector<TRegExMatch>& exclusio
535561
return false;
536562
}
537563

564+
static void MaybeCreateEmptyFile(const TFsPath& folderPath) {
565+
TVector<TString> children;
566+
folderPath.ListNames(children);
567+
if (children.empty() || (children.size() == 1 && children[0] == INCOMPLETE_FILE_NAME)) {
568+
TFile(folderPath.Child(EMPTY_FILE_NAME), CreateAlways);
569+
}
570+
}
571+
538572
void BackupFolderImpl(TDriver driver, const TString& dbPrefix, const TString& backupPrefix, TString path,
539573
const TFsPath folderPath, const TVector<TRegExMatch>& exclusionPatterns,
540574
bool schemaOnly, bool useConsistentCopyTable, bool avoidCopy, bool preservePoolKinds, bool ordered) {
@@ -562,6 +596,9 @@ void BackupFolderImpl(TDriver driver, const TString& dbPrefix, const TString& ba
562596
BackupTable(driver, dbIt.GetTraverseRoot(), backupPrefix, dbIt.GetRelPath(),
563597
childFolderPath, schemaOnly, preservePoolKinds, ordered);
564598
childFolderPath.Child(INCOMPLETE_FILE_NAME).DeleteIfExists();
599+
} else if (dbIt.IsDir()) {
600+
BackupPermissions(driver, dbIt.GetTraverseRoot(), dbIt.GetRelPath(), childFolderPath);
601+
childFolderPath.Child(INCOMPLETE_FILE_NAME).DeleteIfExists();
565602
}
566603
} else if (!avoidCopy) {
567604
if (dbIt.IsTable()) {
@@ -594,13 +631,7 @@ void BackupFolderImpl(TDriver driver, const TString& dbPrefix, const TString& ba
594631
// so control flow can't reach this line. Check it just to be sure
595632
Y_ENSURE(!childFolderPath.Child(INCOMPLETE_FILE_NAME).Exists());
596633
} else if (dbIt.IsDir()) {
597-
childFolderPath.Child(INCOMPLETE_FILE_NAME).DeleteIfExists();
598-
599-
TVector<TString> children;
600-
childFolderPath.ListNames(children);
601-
if (children.empty()) {
602-
TFile(childFolderPath.Child(EMPTY_FILE_NAME), CreateAlways);
603-
}
634+
MaybeCreateEmptyFile(childFolderPath);
604635
}
605636

606637
childFolderPath.Child(INCOMPLETE_FILE_NAME).DeleteIfExists();
@@ -639,14 +670,8 @@ void BackupFolderImpl(TDriver driver, const TString& dbPrefix, const TString& ba
639670
DropTable(driver, tmpTablePath);
640671
}
641672
} else if (dbIt.IsDir()) {
642-
childFolderPath.Child(INCOMPLETE_FILE_NAME).DeleteIfExists();
643-
644-
TVector<TString> children;
645-
childFolderPath.ListNames(children);
646-
if (children.empty()) {
647-
TFile(childFolderPath.Child(EMPTY_FILE_NAME), CreateAlways);
648-
}
649-
673+
BackupPermissions(driver, dbIt.GetTraverseRoot(), dbIt.GetRelPath(), childFolderPath);
674+
MaybeCreateEmptyFile(childFolderPath);
650675
if (!avoidCopy) {
651676
RemoveClusterDirectory(driver, tmpTablePath);
652677
}

ydb/public/sdk/cpp/client/ydb_scheme/scheme.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ namespace NScheme {
1717
using namespace NThreading;
1818
using namespace Ydb::Scheme;
1919

20+
void TPermissions::SerializeTo(::Ydb::Scheme::Permissions& proto) const {
21+
proto.set_subject(Subject);
22+
for (const auto& name : PermissionNames) {
23+
*proto.mutable_permission_names()->Add() = name;
24+
}
25+
}
26+
2027
TVirtualTimestamp::TVirtualTimestamp(ui64 planStep, ui64 txId)
2128
: PlanStep(planStep)
2229
, TxId(txId)
@@ -120,6 +127,13 @@ void TSchemeEntry::Out(IOutputStream& out) const {
120127
<< " }";
121128
}
122129

130+
void TSchemeEntry::SerializeTo(::Ydb::Scheme::ModifyPermissionsRequest& request) const {
131+
request.mutable_actions()->Add()->set_change_owner(Owner);
132+
for (const auto& permission : Permissions) {
133+
permission.SerializeTo(*request.mutable_actions()->Add()->mutable_set());
134+
}
135+
}
136+
123137
class TSchemeClient::TImpl : public TClientImplCommon<TSchemeClient::TImpl> {
124138
public:
125139
TImpl(std::shared_ptr<TGRpcConnectionsImpl>&& connections, const TCommonClientSettings& settings)

ydb/public/sdk/cpp/client/ydb_scheme/scheme.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace Ydb {
66
class VirtualTimestamp;
77
namespace Scheme {
88
class Entry;
9+
class ModifyPermissionsRequest;
10+
class Permissions;
911
}
1012
}
1113

@@ -24,6 +26,8 @@ struct TPermissions {
2426
{}
2527
TString Subject;
2628
TVector<TString> PermissionNames;
29+
30+
void SerializeTo(::Ydb::Scheme::Permissions& proto) const;
2731
};
2832

2933
enum class ESchemeEntryType : i32 {
@@ -77,6 +81,9 @@ struct TSchemeEntry {
7781
TSchemeEntry(const ::Ydb::Scheme::Entry& proto);
7882

7983
void Out(IOutputStream& out) const;
84+
85+
// Fills ModifyPermissionsRequest proto from this entry
86+
void SerializeTo(::Ydb::Scheme::ModifyPermissionsRequest& request) const;
8087
};
8188

8289
////////////////////////////////////////////////////////////////////////////////

ydb/tests/functional/ydb_cli/test_ydb_backup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from ydb.tests.library.harness.kikimr_cluster import kikimr_cluster_factory
55
from ydb.tests.oss.ydb_sdk_import import ydb
66

7-
from hamcrest import assert_that, is_, is_not, contains_inanyorder, has_item, has_items
7+
from hamcrest import assert_that, is_, is_not, contains_inanyorder, has_items
88
import os
99
import logging
1010
import pytest
@@ -192,12 +192,12 @@ def create_backup(cls, path, expected_dirs, check_data, additional_args=[]):
192192
if check_data:
193193
assert_that(
194194
os.listdir(backup_files_dir + "/" + _dir),
195-
contains_inanyorder("data_00.csv", "scheme.pb")
195+
contains_inanyorder("data_00.csv", "scheme.pb", "permissions.pb")
196196
)
197197
else:
198198
assert_that(
199199
os.listdir(backup_files_dir + "/" + _dir),
200-
has_item("scheme.pb")
200+
has_items("scheme.pb", "permissions.pb")
201201
)
202202

203203

0 commit comments

Comments
 (0)