aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvovamelnikov <vovamelnikov@yandex-team.com>2023-09-05 19:08:38 +0300
committervovamelnikov <vovamelnikov@yandex-team.com>2023-09-05 20:29:26 +0300
commit7e762ee28ddf028e5e97d0d1873ddbb7800972ef (patch)
tree1e3e67eccae2ad1f706ace568af175e49d61a459
parent260e4396096e87d87dc7e95f9f6eb11854df0c2d (diff)
downloadydb-7e762ee28ddf028e5e97d0d1873ddbb7800972ef.tar.gz
YT-19222: Forbid irreversible changes to ACLs (unless they are forced)
-rw-r--r--yt/cpp/mapreduce/interface/client_method_options.h8
-rw-r--r--yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp3
-rw-r--r--yt/yt/client/api/cypress_client.h4
-rw-r--r--yt/yt/client/api/rpc_proxy/client_base.cpp1
-rw-r--r--yt/yt/client/driver/cypress_commands.cpp2
-rw-r--r--yt/yt/client/security_client/public.h1
-rw-r--r--yt/yt/core/ytree/system_attribute_provider.h2
-rw-r--r--yt/yt/core/ytree/virtual.cpp4
-rw-r--r--yt/yt/core/ytree/virtual.h4
-rw-r--r--yt/yt/core/ytree/ypath_detail.cpp20
-rw-r--r--yt/yt/core/ytree/ypath_detail.h4
-rw-r--r--yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto1
-rw-r--r--yt/yt_proto/yt/core/ytree/proto/ypath.proto2
13 files changed, 37 insertions, 19 deletions
diff --git a/yt/cpp/mapreduce/interface/client_method_options.h b/yt/cpp/mapreduce/interface/client_method_options.h
index 8074632353..1efbc732ef 100644
--- a/yt/cpp/mapreduce/interface/client_method_options.h
+++ b/yt/cpp/mapreduce/interface/client_method_options.h
@@ -154,7 +154,13 @@ struct TSetOptions
///
/// @see https://yt.yandex-team.ru/docs/api/commands.html#multiset_attributes
struct TMultisetAttributesOptions
-{ };
+{
+ /// @cond Doxygen_Suppress
+ using TSelf = TMultisetAttributesOptions;
+ /// @endcond
+
+ FLUENT_FIELD_OPTION(bool, Force);
+};
///
/// @brief Options for @ref NYT::ICypressClient::List
diff --git a/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp b/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp
index 30f0fb3b9d..7a3c3548c7 100644
--- a/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp
+++ b/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp
@@ -193,6 +193,9 @@ TNode SerializeParamsForMultisetAttributes(
TNode result;
SetTransactionIdParam(&result, transactionId);
SetPathParam(&result, pathPrefix, path);
+ if (options.Force_) {
+ result["force"] = *options.Force_;
+ }
return result;
}
diff --git a/yt/yt/client/api/cypress_client.h b/yt/yt/client/api/cypress_client.h
index 9b7c5b1435..52f1d3b953 100644
--- a/yt/yt/client/api/cypress_client.h
+++ b/yt/yt/client/api/cypress_client.h
@@ -38,7 +38,9 @@ struct TMultisetAttributesNodeOptions
, public TMutatingOptions
, public TSuppressableAccessTrackingOptions
, public TPrerequisiteOptions
-{ };
+{
+ bool Force = false;
+};
struct TRemoveNodeOptions
: public TTimeoutOptions
diff --git a/yt/yt/client/api/rpc_proxy/client_base.cpp b/yt/yt/client/api/rpc_proxy/client_base.cpp
index cbeb4a3c5e..0432530ca2 100644
--- a/yt/yt/client/api/rpc_proxy/client_base.cpp
+++ b/yt/yt/client/api/rpc_proxy/client_base.cpp
@@ -361,6 +361,7 @@ TFuture<void> TClientBase::MultisetAttributesNode(
SetTimeoutOptions(*req, options);
req->set_path(path);
+ req->set_force(options.Force);
auto children = attributes->GetChildren();
std::sort(children.begin(), children.end());
diff --git a/yt/yt/client/driver/cypress_commands.cpp b/yt/yt/client/driver/cypress_commands.cpp
index 03a2ca791d..562c0fd486 100644
--- a/yt/yt/client/driver/cypress_commands.cpp
+++ b/yt/yt/client/driver/cypress_commands.cpp
@@ -75,6 +75,8 @@ void TSetCommand::DoExecute(ICommandContextPtr context)
TMultisetAttributesCommand::TMultisetAttributesCommand()
{
RegisterParameter("path", Path);
+ RegisterParameter("force", Options.Force)
+ .Optional();
}
void TMultisetAttributesCommand::DoExecute(ICommandContextPtr context)
diff --git a/yt/yt/client/security_client/public.h b/yt/yt/client/security_client/public.h
index ffda3af757..13033e3e2e 100644
--- a/yt/yt/client/security_client/public.h
+++ b/yt/yt/client/security_client/public.h
@@ -71,6 +71,7 @@ YT_DEFINE_ERROR_ENUM(
((NoSuchSubject) (907))
((SafeModeEnabled) (906))
((AlreadyPresentInGroup) (908))
+ ((IrreversibleAclModification) (909))
);
// NB: Changing this list requires reign promotion.
diff --git a/yt/yt/core/ytree/system_attribute_provider.h b/yt/yt/core/ytree/system_attribute_provider.h
index ebd76caddd..2c98e4d292 100644
--- a/yt/yt/core/ytree/system_attribute_provider.h
+++ b/yt/yt/core/ytree/system_attribute_provider.h
@@ -122,7 +122,7 @@ struct ISystemAttributeProvider
/*!
* \returns |false| if there is no writable builtin attribute with the given key.
*/
- virtual bool SetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value) = 0;
+ virtual bool SetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value, bool force) = 0;
//! Removes the builtin attribute.
/*!
diff --git a/yt/yt/core/ytree/virtual.cpp b/yt/yt/core/ytree/virtual.cpp
index 675dbd6c9e..b56891cd9d 100644
--- a/yt/yt/core/ytree/virtual.cpp
+++ b/yt/yt/core/ytree/virtual.cpp
@@ -253,7 +253,7 @@ ISystemAttributeProvider* TVirtualMapBase::GetBuiltinAttributeProvider()
return this;
}
-bool TVirtualMapBase::SetBuiltinAttribute(TInternedAttributeKey /*key*/, const TYsonString& /*value*/)
+bool TVirtualMapBase::SetBuiltinAttribute(TInternedAttributeKey /*key*/, const TYsonString& /*value*/, bool /*force*/)
{
return false;
}
@@ -595,7 +595,7 @@ ISystemAttributeProvider* TVirtualListBase::GetBuiltinAttributeProvider()
return this;
}
-bool TVirtualListBase::SetBuiltinAttribute(TInternedAttributeKey /*key*/, const TYsonString& /*value*/)
+bool TVirtualListBase::SetBuiltinAttribute(TInternedAttributeKey /*key*/, const TYsonString& /*value*/, bool /*force*/)
{
return false;
}
diff --git a/yt/yt/core/ytree/virtual.h b/yt/yt/core/ytree/virtual.h
index 43cb08d228..be7638911a 100644
--- a/yt/yt/core/ytree/virtual.h
+++ b/yt/yt/core/ytree/virtual.h
@@ -44,7 +44,7 @@ protected:
const THashSet<TInternedAttributeKey>& GetBuiltinAttributeKeys() override;
bool GetBuiltinAttribute(TInternedAttributeKey key, NYson::IYsonConsumer* consumer) override;
TFuture<NYson::TYsonString> GetBuiltinAttributeAsync(TInternedAttributeKey key) override;
- bool SetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value) override;
+ bool SetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value, bool force) override;
bool RemoveBuiltinAttribute(TInternedAttributeKey key) override;
private:
@@ -109,7 +109,7 @@ protected:
const THashSet<TInternedAttributeKey>& GetBuiltinAttributeKeys() override;
bool GetBuiltinAttribute(TInternedAttributeKey key, NYson::IYsonConsumer* consumer) override;
TFuture<NYson::TYsonString> GetBuiltinAttributeAsync(TInternedAttributeKey key) override;
- bool SetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value) override;
+ bool SetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value, bool force) override;
bool RemoveBuiltinAttribute(TInternedAttributeKey key) override;
private:
diff --git a/yt/yt/core/ytree/ypath_detail.cpp b/yt/yt/core/ytree/ypath_detail.cpp
index 1daeced53e..4476381942 100644
--- a/yt/yt/core/ytree/ypath_detail.cpp
+++ b/yt/yt/core/ytree/ypath_detail.cpp
@@ -403,7 +403,7 @@ void TSupportsAttributes::TCombinedAttributeDictionary::SetYson(const TString& k
if (internedKey != InvalidInternedAttribute) {
const auto& builtinKeys = provider->GetBuiltinAttributeKeys();
if (builtinKeys.find(internedKey) != builtinKeys.end()) {
- if (!provider->SetBuiltinAttribute(internedKey, value)) {
+ if (!provider->SetBuiltinAttribute(internedKey, value, false)) {
ThrowCannotSetBuiltinAttribute(key);
}
return;
@@ -805,7 +805,7 @@ void TSupportsAttributes::ExistsAttribute(
}));
}
-void TSupportsAttributes::DoSetAttribute(const TYPath& path, const TYsonString& newYson)
+void TSupportsAttributes::DoSetAttribute(const TYPath& path, const TYsonString& newYson, bool force)
{
TCachingPermissionValidator permissionValidator(this, EPermissionCheckScope::This);
@@ -875,7 +875,7 @@ void TSupportsAttributes::DoSetAttribute(const TYPath& path, const TYsonString&
permissionValidator.Validate(descriptor.ModifyPermission);
- if (!GuardedSetBuiltinAttribute(internedKey, newAttributeYson)) {
+ if (!GuardedSetBuiltinAttribute(internedKey, newAttributeYson, force)) {
ThrowCannotSetBuiltinAttribute(key);
}
@@ -916,7 +916,7 @@ void TSupportsAttributes::DoSetAttribute(const TYPath& path, const TYsonString&
permissionValidator.Validate(descriptor->ModifyPermission);
if (tokenizer.Advance() == NYPath::ETokenType::EndOfStream) {
- if (!GuardedSetBuiltinAttribute(internedKey, newYson)) {
+ if (!GuardedSetBuiltinAttribute(internedKey, newYson, force)) {
ThrowCannotSetBuiltinAttribute(key);
}
} else {
@@ -929,7 +929,7 @@ void TSupportsAttributes::DoSetAttribute(const TYPath& path, const TYsonString&
SyncYPathSet(oldWholeNode, TYPath(tokenizer.GetInput()), newYson);
auto newWholeYson = ConvertToYsonString(oldWholeNode);
- if (!GuardedSetBuiltinAttribute(internedKey, newWholeYson)) {
+ if (!GuardedSetBuiltinAttribute(internedKey, newWholeYson, force)) {
ThrowCannotSetBuiltinAttribute(key);
}
}
@@ -981,7 +981,7 @@ void TSupportsAttributes::SetAttribute(
const auto& safeValue = requestValue.capacity() <= requestValue.length() * 5 / 4
? requestValue
: TString(TStringBuf(requestValue));
- DoSetAttribute(path, TYsonString(safeValue));
+ DoSetAttribute(path, TYsonString(safeValue), request->force());
context->Reply();
}
@@ -1093,7 +1093,7 @@ void TSupportsAttributes::DoRemoveAttribute(const TYPath& path, bool force)
SyncYPathRemove(builtinNode, TYPath(tokenizer.GetInput()));
auto updatedSystemYson = ConvertToYsonString(builtinNode);
- if (!GuardedSetBuiltinAttribute(internedKey, updatedSystemYson)) {
+ if (!GuardedSetBuiltinAttribute(internedKey, updatedSystemYson, force)) {
ThrowCannotSetBuiltinAttribute(key);
}
}
@@ -1140,7 +1140,7 @@ void TSupportsAttributes::SetAttributes(
attributePath = path + "/" + attribute;
}
- DoSetAttribute(attributePath, TYsonString(value));
+ DoSetAttribute(attributePath, TYsonString(value), request->force());
}
}
@@ -1172,12 +1172,12 @@ bool TSupportsAttributes::GuardedGetBuiltinAttribute(TInternedAttributeKey key,
}
}
-bool TSupportsAttributes::GuardedSetBuiltinAttribute(TInternedAttributeKey key, const TYsonString& yson)
+bool TSupportsAttributes::GuardedSetBuiltinAttribute(TInternedAttributeKey key, const TYsonString& yson, bool force)
{
auto* provider = GetBuiltinAttributeProvider();
try {
- return provider->SetBuiltinAttribute(key, yson);
+ return provider->SetBuiltinAttribute(key, yson, force);
} catch (const std::exception& ex) {
THROW_ERROR_EXCEPTION("Error setting builtin attribute %Qv",
ToYPathLiteral(key.Unintern()))
diff --git a/yt/yt/core/ytree/ypath_detail.h b/yt/yt/core/ytree/ypath_detail.h
index f89b791069..051347da16 100644
--- a/yt/yt/core/ytree/ypath_detail.h
+++ b/yt/yt/core/ytree/ypath_detail.h
@@ -310,11 +310,11 @@ private:
const NYson::TYsonString& wholeYson);
TFuture<NYson::TYsonString> DoListAttribute(const TYPath& path);
- void DoSetAttribute(const TYPath& path, const NYson::TYsonString& newYson);
+ void DoSetAttribute(const TYPath& path, const NYson::TYsonString& newYson, bool force = false);
void DoRemoveAttribute(const TYPath& path, bool force);
bool GuardedGetBuiltinAttribute(TInternedAttributeKey key, NYson::IYsonConsumer* consumer);
- bool GuardedSetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value);
+ bool GuardedSetBuiltinAttribute(TInternedAttributeKey key, const NYson::TYsonString& value, bool force);
bool GuardedRemoveBuiltinAttribute(TInternedAttributeKey key);
void ValidateAttributeKey(TStringBuf key) const;
diff --git a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
index 79615ae6a8..8a59b3a030 100644
--- a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
+++ b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
@@ -1341,6 +1341,7 @@ message TReqMultisetAttributesNode
required bytes value = 2; // YSON
}
repeated TSubrequest subrequests = 2;
+ optional bool force = 3;
optional TTransactionalOptions transactional_options = 100;
optional TPrerequisiteOptions prerequisite_options = 101;
diff --git a/yt/yt_proto/yt/core/ytree/proto/ypath.proto b/yt/yt_proto/yt/core/ytree/proto/ypath.proto
index fd50b28a7f..20e1192ec7 100644
--- a/yt/yt_proto/yt/core/ytree/proto/ypath.proto
+++ b/yt/yt_proto/yt/core/ytree/proto/ypath.proto
@@ -134,6 +134,7 @@ message TReqMultiset
}
repeated TSubrequest subrequests = 1;
+ optional bool force = 2 [default = false];
}
message TRspMultiset
@@ -150,6 +151,7 @@ message TReqMultisetAttributes
}
repeated TSubrequest subrequests = 1;
+ optional bool force = 2 [default = false];
}
message TRspMultisetAttributes