Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sds api split #4231

Merged
merged 5 commits into from
Aug 24, 2018
Merged

Sds api split #4231

merged 5 commits into from
Aug 24, 2018

Conversation

JimmyCYJ
Copy link
Member

Description: Implement SDS API and dummy socket, and they are not in use. This is split from PR #4176.
Risk Level: Low
Testing: Unit tests
Docs Changes: None

Fixes #1194

Signed-off-by: Jimmy Chen [email protected]

@JimmyCYJ
Copy link
Member Author

cc: @htuch @lizan @qiwzhang @PiotrSikora

@JimmyCYJ JimmyCYJ mentioned this pull request Aug 22, 2018
@@ -17,6 +17,35 @@ using Envoy::Network::PostIoAction;
namespace Envoy {
namespace Ssl {

namespace {
// This SslSocket will be used when SSL secret is not fetched from SDS server.
class NotReadySslSocket : public Network::TransportSocket, public Connection {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need this to be a Ssl::Connection. just inherit TransportSocket is enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks.

: local_info_(local_info), dispatcher_(dispatcher), random_(random), stats_(stats),
cluster_manager_(cluster_manager), sds_config_(sds_config), sds_config_name_(sds_config_name),
secret_hash_(0), unregister_secret_provider_cb_(unregister_secret_provider) {
// TODO(JimmyCYJ): Implement chained_init_manager, so that multiple init_manager
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once this is resolved, do we still need NotReadySslSocket?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need NotReadySslSocket. Chained init manager guarantees that If two listeners point to the same secret, both listeners would wait for secrets and then listen on port. A better explanation is here. NotReadySslSocket is to solve the issue that if a listener gets secret and listens on a port, but the secret is bad, we should not use the secret to handle connection, and close the connection right away.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is much clearer. Looks good, just some RAII ideas to improve interfaces.

* @param callback callback that is executed by secret provider.
*/
virtual void addUpdateCallback(SecretCallbacks& callback) PURE;
/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: blank line between declaration and comment belonging to next block.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added blank line.

* Remove secret callback from secret provider.
* @param callback callback that is executed by secret provider.
*/
virtual void removeUpdateCallback(SecretCallbacks& callback) PURE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A general pattern in Envoy is to use RAII for managing removal of callbacks; it's a robust design pattern. We actually have a callback manager that models this today, see https://github.com/envoyproxy/envoy/blob/master/source/common/common/callback_impl.h

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you looking at this one as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am working on this one. I will push my update as soon I finish it. Thanks for asking.

Copy link
Member Author

@JimmyCYJ JimmyCYJ Aug 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added CallbackManager into SdsApi and removed removeUpdateCallback().

In PR #4176, I am going to add Common::CallbackHandle* secret_update_callback_handle_ into ContextConfigImpl as a private member, and modify ContextConfigImpl::setSecretUpdateCallback() like this.

void setSecretUpdateCallback(std::function<()> callback) override {
	if (secret_update_callback_handle_) {
  		secret_update_callback_handle_->remove();
	}
	secret_update_callback_handle_ = tls_certficate_provider_->addUpdateCallback(callback);
}

I will also modify ~ContextConfigImpl() like this.

ContextConfigImpl::~ContextConfigImpl() {
  if (secret_update_callback_handle_) {
	secret_update_callback_handle_->remove();
  }
}

@@ -8,10 +8,16 @@ load(

envoy_package()

envoy_cc_library(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for splitting this PR out, this is very helpful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad that it helps. Will keep PR in good size.

std::function<void()> unregister_secret_provider)
: local_info_(local_info), dispatcher_(dispatcher), random_(random), stats_(stats),
cluster_manager_(cluster_manager), sds_config_(sds_config), sds_config_name_(sds_config_name),
secret_hash_(0), unregister_secret_provider_cb_(unregister_secret_provider) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit uncomfortable with the naming (and maybe even presence) of unregister_secret_provider_cb. It should at least be a generic destructor_cb_, but I would go further. This could be refactored to have SdsApi completely oblivious to this callback. Instead, the places that have the SdsApi instances, e.g. in the listener manager, have an object that wraps both SdsApi and includes a RAII cleanup, e.g. something like https://github.com/envoyproxy/envoy/blob/master/source/common/common/cleanup.h.

I'm not sure exactly how to make this super clean in your use case, but I feel that right now, this is not the right interface. Can you try out some of the above ideas to try and get SdsApi out of the business of dealing with object lifetimes of its owner?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a Cleanup member into SdsApi that holds the destructor_cb, which will be invoked by ~SdsApi(). Thanks for the advice!

"Unexpected SDS secrets length: 2");
}

TEST_F(SdsApiTest, SecretUpdateWrongSecretName) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add one liner // above each test case explaining in simple terms what's happening?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments are added above each test case. Thanks.

* Remove secret callback from secret provider.
* @param callback callback that is executed by secret provider.
*/
virtual void removeUpdateCallback(SecretCallbacks& callback) PURE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you looking at this one as well?

Runtime::RandomGenerator& random, Stats::Store& stats,
Upstream::ClusterManager& cluster_manager, Init::Manager& init_manager,
const envoy::api::v2::core::ConfigSource& sds_config, std::string sds_config_name,
std::function<void()> destructor_cb)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better than before, thanks. I still think it can be cleaner if instead of having SdsApi owning the destructor CB, we have the owner of SdsApi own that object. It's pretty weird threading a destructor CB into an object when the lifetime issues are really those of the owning object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out. My concern is that SdsApi is held by a shared_ptr (ContextConfigImpland::tls_certficate_provider_) and could be owned by multiple objects (e.g. multiple listeners or clusters). The last owner needs to destroy SdsApi and ~SdsApi() invokes this cleanup function. I am not clear if there is a better place to own the Cleanup object other than SdsApi.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@htuch SdsApi is a shared pointer that could be owned by multiple objects as @JimmyCYJ pointed out, the structure here is similar to what we have in RDS (RdsRouteConfigSubscription). With the destructor_cb it doesn't need to be a friend class between SecretManagerImpl and SdsApi.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, OK, I still think you could wrap SdsApi in a SdsApiWithManagedLifetime object to get the same effect and separate concerns here, but I guess we have precedent for doing it this way.

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

}

Common::CallbackHandle* addUpdateCallback(std::function<void()> callback) override {
return update_callback_manager_.add(callback);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-actionable; for some reason I thought this was RAII, but it's just a callback removal handle. We can make that more robust independent of this PR.

Runtime::RandomGenerator& random, Stats::Store& stats,
Upstream::ClusterManager& cluster_manager, Init::Manager& init_manager,
const envoy::api::v2::core::ConfigSource& sds_config, std::string sds_config_name,
std::function<void()> destructor_cb)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, OK, I still think you could wrap SdsApi in a SdsApiWithManagedLifetime object to get the same effect and separate concerns here, but I guess we have precedent for doing it this way.

@htuch htuch merged commit 99df2e2 into envoyproxy:master Aug 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants