Skip to content

Commit

Permalink
ydb(d) cli: add commands for setting interrupt-inheritance flag in acl (
Browse files Browse the repository at this point in the history
#3776)

Add `ydb scheme permissions {clear,set}-inheritance` commands.
Add `ydbd db schema access {clear,set}-inheritance` commands.

`InterruptInheritance` is a special flag that blocks permission inheritance for a target path. There are a variance of inheritance type modifiers which effect how inheritance works for an individual access control entry, but InterruptInheritance flag have a global effect for a path.
InterruptInheritance was a part of the public api for a while now (and it was used internally), but there was no cli commands to actually manipulate it.
  • Loading branch information
ijon authored Nov 27, 2024
1 parent bb312c5 commit e6457a7
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 0 deletions.
86 changes: 86 additions & 0 deletions ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,90 @@ class TClientCommandSchemaAccessRemove : public TClientCommand {
}
};

class TClientCommandSchemaAccessInheritanceBase : public TClientCommand {
public:
TClientCommandSchemaAccessInheritanceBase(
const TString& name,
const std::initializer_list<TString>& aliases,
const TString& description,
bool interruptInheritance
)
: TClientCommand(name, aliases, description)
, InterruptInheritance(interruptInheritance)
{}

TAutoPtr<NKikimrClient::TSchemeOperation> Request;

virtual void Config(TConfig& config) override {
TClientCommand::Config(config);
config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<PATH>", "Full pathname of an object (e.g. /ru/home/user/mydb/test1/test2).\n"
" Or short pathname if profile path is set (e.g. test1/test2).");
}

TString Base;
TString Name;
bool InterruptInheritance = false;

virtual void Parse(TConfig& config) override {
TClientCommand::Parse(config);
TString pathname = config.ParseResult->GetFreeArgs()[0];
size_t pos = pathname.rfind('/');
if (config.Path) {
// Profile path is set
if (!pathname.StartsWith('/')) {
Base = config.Path;
Name = pathname;
} else {
WarnProfilePathSet();
Base = pathname.substr(0, pos);
Name = pathname.substr(pos + 1);
}
} else {
Base = pathname.substr(0, pos);
Name = pathname.substr(pos + 1);
}
}

virtual int Run(TConfig& config) override {
TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation());
NKikimrClient::TSchemeOperation& record(request->Record);
auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme();
modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL);
modifyScheme.SetWorkingDir(Base);
auto& modifyAcl = *modifyScheme.MutableModifyACL();
modifyAcl.SetName(Name);
NACLibProto::TDiffACL diffAcl;
{
diffAcl.SetInterruptInheritance(InterruptInheritance);
}
modifyAcl.SetDiffACL(diffAcl.SerializeAsString());
int result = MessageBusCall<NMsgBusProxy::TBusSchemeOperation, NMsgBusProxy::TBusResponse>(config, request,
[](const NMsgBusProxy::TBusResponse& response) -> int {
if (response.Record.GetStatus() != NMsgBusProxy::MSTATUS_OK) {
Cerr << ToCString(static_cast<NMsgBusProxy::EResponseStatus>(response.Record.GetStatus())) << " " << response.Record.GetErrorReason() << Endl;
return 1;
}
return 0;
});
return result;
}
};

class TClientCommandSchemaAccessSetInheritance : public TClientCommandSchemaAccessInheritanceBase {
public:
TClientCommandSchemaAccessSetInheritance()
: TClientCommandSchemaAccessInheritanceBase("set-inheritance", {}, "Enable permission inheritance from the parent", false)
{}
};

class TClientCommandSchemaAccessClearInheritance : public TClientCommandSchemaAccessInheritanceBase {
public:
TClientCommandSchemaAccessClearInheritance()
: TClientCommandSchemaAccessInheritanceBase("clear-inheritance", {}, "Disable permission inheritance from the parent", true)
{}
};

class TClientCommandSchemaAccess : public TClientCommandTree {
public:
TClientCommandSchemaAccess()
Expand All @@ -808,6 +892,8 @@ class TClientCommandSchemaAccess : public TClientCommandTree {
AddCommand(std::make_unique<TClientCommandSchemaAccessRemove>());
//AddCommand(std::make_unique<TClientCommandSchemaAccessGrant>());
//AddCommand(std::make_unique<TClientCommandSchemaAccessRevoke>());
AddCommand(std::make_unique<TClientCommandSchemaAccessSetInheritance>());
AddCommand(std::make_unique<TClientCommandSchemaAccessClearInheritance>());
}
};

Expand Down
2 changes: 2 additions & 0 deletions ydb/docs/en/core/reference/ydb-cli/_includes/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Any command can be run from the command line with the `--help` option to get hel
| scheme permissions remove | Removing a permission |
| scheme permissions revoke | Revoking a permission |
| scheme permissions set | Setting permissions |
| scheme permissions clear-inheritance | Disabling permissions inheritance |
| scheme permissions set-inheritance | Enabling permissions inheritance |
| [scheme rmdir](../commands/dir.md#rmdir) | Deleting a directory |
| [scripting yql](../scripting-yql.md) | Executing a YQL script |
| table attribute add | Adding a table attribute |
Expand Down
2 changes: 2 additions & 0 deletions ydb/docs/ru/core/reference/ydb-cli/_includes/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ scheme permissions grant | Предоставление разрешения
scheme permissions remove | Удаление разрешения
scheme permissions revoke | Удаление разрешения
scheme permissions set | Установка разрешений
scheme permissions clear-inheritance | Запрет наследования разрешений
scheme permissions set-inheritance | Установка наследования разрешений
[scheme rmdir](../commands/dir.md#rmdir) | Удаление директории
[scripting yql](../scripting-yql.md) | Выполнение YQL-скрипта
table attribute add | Добавление атрибута для строкой или колоночной таблицы
Expand Down
62 changes: 62 additions & 0 deletions ydb/public/lib/ydb_cli/commands/ydb_service_scheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,8 @@ TCommandPermissions::TCommandPermissions()
AddCommand(std::make_unique<TCommandPermissionSet>());
AddCommand(std::make_unique<TCommandChangeOwner>());
AddCommand(std::make_unique<TCommandPermissionClear>());
AddCommand(std::make_unique<TCommandPermissionSetInheritance>());
AddCommand(std::make_unique<TCommandPermissionClearInheritance>());
AddCommand(std::make_unique<TCommandPermissionList>());
}

Expand Down Expand Up @@ -1285,6 +1287,66 @@ int TCommandPermissionClear::Run(TConfig& config) {
return EXIT_SUCCESS;
}

TCommandPermissionSetInheritance::TCommandPermissionSetInheritance()
: TYdbOperationCommand("set-inheritance", std::initializer_list<TString>(), "Set to inherit permissions from the parent")
{}

void TCommandPermissionSetInheritance::Config(TConfig& config) {
TYdbOperationCommand::Config(config);

config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<path>", "Path to set interrupt-inheritance flag for");
}

void TCommandPermissionSetInheritance::Parse(TConfig& config) {
TClientCommand::Parse(config);
ParsePath(config, 0);
}

int TCommandPermissionSetInheritance::Run(TConfig& config) {
NScheme::TSchemeClient client(CreateDriver(config));
ThrowOnError(
client.ModifyPermissions(
Path,
FillSettings(
NScheme::TModifyPermissionsSettings()
.AddInterruptInheritance(false)
)
).GetValueSync()
);
return EXIT_SUCCESS;
}

TCommandPermissionClearInheritance::TCommandPermissionClearInheritance()
: TYdbOperationCommand("clear-inheritance", std::initializer_list<TString>(), "Set to do not inherit permissions from the parent")
{}

void TCommandPermissionClearInheritance::Config(TConfig& config) {
TYdbOperationCommand::Config(config);

config.SetFreeArgsNum(1);
SetFreeArgTitle(0, "<path>", "Path to set interrupt-inheritance flag for");
}

void TCommandPermissionClearInheritance::Parse(TConfig& config) {
TClientCommand::Parse(config);
ParsePath(config, 0);
}

int TCommandPermissionClearInheritance::Run(TConfig& config) {
NScheme::TSchemeClient client(CreateDriver(config));
ThrowOnError(
client.ModifyPermissions(
Path,
FillSettings(
NScheme::TModifyPermissionsSettings()
.AddInterruptInheritance(true)
)
).GetValueSync()
);
return EXIT_SUCCESS;
}

TCommandPermissionList::TCommandPermissionList()
: TYdbOperationCommand("list", std::initializer_list<TString>(), "List permissions")
{}
Expand Down
16 changes: 16 additions & 0 deletions ydb/public/lib/ydb_cli/commands/ydb_service_scheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,22 @@ class TCommandPermissionClear : public TYdbOperationCommand, public TCommandWith
virtual int Run(TConfig& config) override;
};

class TCommandPermissionSetInheritance : public TYdbOperationCommand, public TCommandWithPath {
public:
TCommandPermissionSetInheritance();
virtual void Config(TConfig& config) override;
virtual void Parse(TConfig& config) override;
virtual int Run(TConfig& config) override;
};

class TCommandPermissionClearInheritance : public TYdbOperationCommand, public TCommandWithPath {
public:
TCommandPermissionClearInheritance();
virtual void Config(TConfig& config) override;
virtual void Parse(TConfig& config) override;
virtual int Run(TConfig& config) override;
};

class TCommandPermissionList : public TYdbOperationCommand, public TCommandWithPath {
public:
TCommandPermissionList();
Expand Down
3 changes: 3 additions & 0 deletions ydb/public/sdk/cpp/client/ydb_scheme/scheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ class TSchemeClient::TImpl : public TClientImplCommon<TSchemeClient::TImpl> {
if (settings.ClearAcl_) {
request.set_clear_permissions(true);
}
if (settings.SetInterruptInheritance_) {
request.set_interrupt_inheritance(settings.InterruptInheritanceValue_);
}

for (const auto& action : settings.Actions_) {
auto protoAction = request.add_actions();
Expand Down
8 changes: 8 additions & 0 deletions ydb/public/sdk/cpp/client/ydb_scheme/scheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,16 @@ struct TModifyPermissionsSettings : public TOperationRequestSettings<TModifyPerm
return *this;
}

TModifyPermissionsSettings& AddInterruptInheritance(bool value) {
SetInterruptInheritance_ = true;
InterruptInheritanceValue_ = value;
return *this;
}

TVector<std::pair<EModifyPermissionsAction, TPermissions>> Actions_;
bool ClearAcl_ = false;
bool SetInterruptInheritance_ = false;
bool InterruptInheritanceValue_ = false;
void AddAction(EModifyPermissionsAction action, const TPermissions& permissions) {
Actions_.emplace_back(std::pair<EModifyPermissionsAction, TPermissions>{action, permissions});
}
Expand Down

0 comments on commit e6457a7

Please sign in to comment.