diff options
author | vovamelnikov <vovamelnikov@yandex-team.com> | 2023-09-05 19:08:38 +0300 |
---|---|---|
committer | vovamelnikov <vovamelnikov@yandex-team.com> | 2023-09-05 20:29:26 +0300 |
commit | 7e762ee28ddf028e5e97d0d1873ddbb7800972ef (patch) | |
tree | 1e3e67eccae2ad1f706ace568af175e49d61a459 | |
parent | 260e4396096e87d87dc7e95f9f6eb11854df0c2d (diff) | |
download | ydb-7e762ee28ddf028e5e97d0d1873ddbb7800972ef.tar.gz |
YT-19222: Forbid irreversible changes to ACLs (unless they are forced)
-rw-r--r-- | yt/cpp/mapreduce/interface/client_method_options.h | 8 | ||||
-rw-r--r-- | yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp | 3 | ||||
-rw-r--r-- | yt/yt/client/api/cypress_client.h | 4 | ||||
-rw-r--r-- | yt/yt/client/api/rpc_proxy/client_base.cpp | 1 | ||||
-rw-r--r-- | yt/yt/client/driver/cypress_commands.cpp | 2 | ||||
-rw-r--r-- | yt/yt/client/security_client/public.h | 1 | ||||
-rw-r--r-- | yt/yt/core/ytree/system_attribute_provider.h | 2 | ||||
-rw-r--r-- | yt/yt/core/ytree/virtual.cpp | 4 | ||||
-rw-r--r-- | yt/yt/core/ytree/virtual.h | 4 | ||||
-rw-r--r-- | yt/yt/core/ytree/ypath_detail.cpp | 20 | ||||
-rw-r--r-- | yt/yt/core/ytree/ypath_detail.h | 4 | ||||
-rw-r--r-- | yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto | 1 | ||||
-rw-r--r-- | yt/yt_proto/yt/core/ytree/proto/ypath.proto | 2 |
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 |