config: logging a warning on use of deprecated proto fields#5760
config: logging a warning on use of deprecated proto fields#5760alyssawilk merged 8 commits intoenvoyproxy:masterfrom
Conversation
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
Some discussion points. I'd prefer this to be a critical log but I think the forced-flush could work very badly if it were present in a large (order tens of thousands of repeated messages) config, so I'm erring on the side of perf-caution I think we should probably un-deprecate 2 of the 3 remaining deprecated_v1 fields to avoid user-confusion that they will be removed soon. I believe the removal of bind_to_port and the cds tcp proxy filter are blocked on code, so should probably be undeprecated until code is complete and then de-deprecated following normal Envoy process. |
ggreenway
left a comment
There was a problem hiding this comment.
This is great!
Do we consistently call validate() on all messages, and specifically on the bits that get passed as a Struct and re-proto-ified in filters?
source/common/protobuf/utility.h
Outdated
| const auto* desc = message.GetDescriptor(); | ||
| const auto* refl = message.GetReflection(); | ||
| for (int i = 0; i < desc->field_count(); ++i) { | ||
| const auto* fd = desc->field(i); |
There was a problem hiding this comment.
nit: fd means file descriptor in my brain. Rename to field?
test/common/protobuf/utility_test.cc
Outdated
| envoy::test::deprecation_test::Base base; | ||
| base.set_is_deprecated("foo"); | ||
| // Non-fatal checks for a deprecated field shouldn't throw an exception. | ||
| MessageUtil::checkForDeprecation(base, false); |
source/common/protobuf/utility.h
Outdated
| static void loadFromYaml(const std::string& yaml, Protobuf::Message& message); | ||
| static void loadFromFile(const std::string& path, Protobuf::Message& message); | ||
|
|
||
| template <class MessageType> |
There was a problem hiding this comment.
I don't think this need to be templatized, using Protobuf::Message should be just enough.
source/common/protobuf/utility.h
Outdated
| static void checkForDeprecation(const MessageType& message, bool fatal) { | ||
| const auto* desc = message.GetDescriptor(); | ||
| const auto* refl = message.GetReflection(); | ||
| for (int i = 0; i < desc->field_count(); ++i) { |
There was a problem hiding this comment.
This only checks top level field and not about inner fields such as here, Validate does recursive validation internally but MessageUtil::validate isn't called at every level.
There was a problem hiding this comment.
Ah my bad, I didn't realize Validate was doing the recursion - will fix and regression test
Struct and re-proto-ified ones are validated via downcastAndValidate so it will be checked by this method. |
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
Noting for the record I'm now officially out of my depth w.r.t proto reflection so please to encourage more tests if you see any gaps. And uploaded without testing beyond the unit test - living dangerously today! :-P |
source/common/protobuf/utility.h
Outdated
| static void loadFromYaml(const std::string& yaml, Protobuf::Message& message); | ||
| static void loadFromFile(const std::string& path, Protobuf::Message& message); | ||
|
|
||
| static void checkForDeprecation(const Protobuf::Message& message, bool fatal) { |
source/common/protobuf/utility.h
Outdated
| "Using deprecated option '{}'. This configuration will be removed from Envoy soon. " | ||
| "Please see https://github.com/envoyproxy/envoy/blob/master/DEPRECATED.md for " | ||
| "details.", | ||
| field->name()); |
There was a problem hiding this comment.
full_name() instead of name should be more helpful.
There was a problem hiding this comment.
Thanks for the tip - this is going to be even more useful!
source/common/protobuf/utility.h
Outdated
| if (fatal) { | ||
| throw ProtoValidationException(err, message); | ||
| } else { | ||
| ENVOY_LOG_MISC(warn, "{}", err); |
There was a problem hiding this comment.
Which logger? The only other log macro in the util.cc used MISC so I didn't think any of the other log macros were suitable.
There was a problem hiding this comment.
We could wrap in a class to provide access to the config logger (or maybe there is a more direct way?).
There was a problem hiding this comment.
Just make MessageUtil inherit Loggable and it should be good (it only provides static method)
There was a problem hiding this comment.
Ah, so you want it to inherit from Logger::LoggableLogger::Id::config
Done, though I think ENVOY_LOG_MISC might make more sense, given that someone could put non-config related proto utilities in source/common/protobuf/utility.h
That said the main uses of proto are config and gRPC which has its own directories, so it's fine for now.
source/common/protobuf/utility.h
Outdated
| } | ||
|
|
||
| // If this is a message, recurse to check for deprecated fields in the sub-message. | ||
| switch (field->cpp_type()) { |
There was a problem hiding this comment.
just if (field->cpp_type == Protobuf::FieldDescriptor::CPPTYPE_MESSAGE)?
|
I think for things like |
htuch
left a comment
There was a problem hiding this comment.
LGTM modulo comments, nice to see that there is first-class support for the deprecated annotation in reflection.
test/common/protobuf/utility_test.cc
Outdated
| "Using deprecated option 'inner_deprecated'."); | ||
| } | ||
|
|
||
| // Check that repeated sub-messages get validated. |
There was a problem hiding this comment.
Nit: preference for making these all separate TEST_F, since they don't share state and it's more self-documenting.
source/common/protobuf/utility.h
Outdated
| static void loadFromYaml(const std::string& yaml, Protobuf::Message& message); | ||
| static void loadFromFile(const std::string& path, Protobuf::Message& message); | ||
|
|
||
| static void checkForDeprecation(const Protobuf::Message& message, bool fatal) { |
There was a problem hiding this comment.
Nit: prefer warn_only vs. fatal, since it's not fatal, it's raising an exception which could be handled in other ways at a call-site (even though you probably only plan on using it for fatal..).
|
@htuch my only concern there is potentially causing confusion for folks who get the warning that they should migrate but can't migrate yet. That said on both the deprecated_v1 fields I'm dubious about, I think the only folks who can't move are Istio, so as long as they know the logged warning doesn't change our deprecation plans I guess we're good? Tagging @PiotrSikora for Istio comms to avoid any confusion on their part and I'll add a release note as well. |
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
Also @costinm for Istio viz. |
test/common/protobuf/utility_test.cc
Outdated
| EXPECT_THROW_WITH_REGEX( | ||
| MessageUtil::checkForDeprecation(base, false), ProtoValidationException, | ||
| "Using deprecated option 'envoy.test.deprecation_test.Base.is_deprecated'."); | ||
| } |
There was a problem hiding this comment.
Nit: no need for the inner braces in all these TESTs..
test/common/protobuf/utility_test.cc
Outdated
| } | ||
|
|
||
| TEST(DeprecatedFields, SubMessageDeprecated) { | ||
| // Check that repeated sub-messages get validated. |
There was a problem hiding this comment.
Nit: move these comments about the TEST.
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
source/common/protobuf/utility.h
Outdated
| enum class ProtoUnknownFieldsMode { Strict, Allow }; | ||
|
|
||
| class MessageUtil { | ||
| class MessageUtil : public Logger::Loggable<Logger::Id::config> { |
There was a problem hiding this comment.
I agree with @alyssawilk, this is not in a config related file/directory, so would prefer not to log with this. Can we pass logger as a parameter, or maybe subclass MessageUtil in config/ with a logger mixin?
There was a problem hiding this comment.
Or go back to MISC_LOG and claim there's precedent :-D
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
|
Had to sync for merge conflict - I'd appreciate one last LGTM! |
…xy#5760) Risk Level: Low (logging only) Testing: new unit tests Docs Changes: n/a Release Notes: not included Part of envoyproxy#5559 Signed-off-by: Alyssa Wilk <alyssar@chromium.org> Signed-off-by: Fred Douglas <fredlas@google.com>
Risk Level: Low (logging only)
Testing: new unit tests
Docs Changes: n/a
Release Notes: not included
Part of #5559