Allowed tests to authorize libprocess HTTP endpoints. The test cluster initialization code was altered to enable authorization of libprocess-level HTTP endpoints when a master or agent is launched with authorization enabled.
Review: https://reviews.apache.org/r/46869/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d5e1a47d Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d5e1a47d Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d5e1a47d Branch: refs/heads/master Commit: d5e1a47dbb5db4af372a079d8cd287392ebe30fa Parents: 12b05e8 Author: Greg Mann <[email protected]> Authored: Wed May 11 22:45:43 2016 -0400 Committer: Kapil Arya <[email protected]> Committed: Thu May 12 01:50:20 2016 -0400 ---------------------------------------------------------------------- src/tests/cluster.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++ src/tests/cluster.hpp | 14 +++++++++++ 2 files changed, 77 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/d5e1a47d/src/tests/cluster.cpp ---------------------------------------------------------------------- diff --git a/src/tests/cluster.cpp b/src/tests/cluster.cpp index db72628..c03e053 100644 --- a/src/tests/cluster.cpp +++ b/src/tests/cluster.cpp @@ -39,6 +39,7 @@ #include <process/future.hpp> #include <process/gmock.hpp> #include <process/gtest.hpp> +#include <process/http.hpp> #include <process/id.hpp> #include <process/limiter.hpp> #include <process/owned.hpp> @@ -61,6 +62,8 @@ #include "authorizer/local/authorizer.hpp" +#include "common/http.hpp" + #include "files/files.hpp" #include "master/constants.hpp" @@ -125,6 +128,10 @@ Try<process::Owned<Master>> Master::start( // If the authorizer is not provided, create a default one. if (authorizer.isNone()) { + // Indicates whether or not the caller explicitly specified the + // authorization configuration for this master. + bool authorizationSpecified = true; + std::vector<std::string> authorizerNames = strings::split(flags.authorizers, ","); @@ -149,6 +156,9 @@ Try<process::Owned<Master>> Master::start( LOG(INFO) << "Creating default '" << authorizerName << "' authorizer"; authorizer = Authorizer::create(flags.acls.get()); + CHECK_SOME(authorizer); + } else { + authorizationSpecified = false; } } @@ -158,7 +168,16 @@ Try<process::Owned<Master>> Master::start( authorizer.error()); } else if (authorizer.isSome()) { master->authorizer.reset(authorizer.get()); + + if (authorizationSpecified) { + // Authorization config was explicitly provided, so set authorization + // callbacks in libprocess. + master->setAuthorizationCallbacks(authorizer.get()); + } } + } else { + // An authorizer was provided, so set authorization callbacks in libprocess. + master->setAuthorizationCallbacks(authorizer.get()); } // Create the appropriate master contender/detector. @@ -317,6 +336,11 @@ Try<process::Owned<Master>> Master::start( Master::~Master() { + // Remove any libprocess authorization callbacks that were installed. + if (authorizationCallbacksSet) { + process::http::authorization::unsetCallbacks(); + } + // NOTE: Authenticators' lifetimes are tied to libprocess's lifetime. // This means that multiple masters in tests are not supported. process::http::authentication::unsetAuthenticator( @@ -344,6 +368,15 @@ MasterInfo Master::getMasterInfo() } +void Master::setAuthorizationCallbacks(Authorizer* authorizer) +{ + process::http::authorization::setCallbacks( + mesos::createAuthorizationCallbacks(authorizer)); + + authorizationCallbacksSet = true; +} + + Try<process::Owned<Slave>> Slave::start( MasterDetector* detector, const slave::Flags& flags, @@ -384,6 +417,10 @@ Try<process::Owned<Slave>> Slave::start( // If the authorizer is not provided, create a default one. if (providedAuthorizer.isNone()) { + // Indicates whether or not the caller explicitly specified the + // authorization configuration for this agent. + bool authorizationSpecified = true; + std::string authorizerName = flags.authorizer; Result<Authorizer*> createdAuthorizer((None())); @@ -398,6 +435,9 @@ Try<process::Owned<Slave>> Slave::start( LOG(INFO) << "Creating default '" << authorizerName << "' authorizer"; createdAuthorizer = Authorizer::create(flags.acls.get()); + } else { + // Neither a non-default authorizer nor a set of ACLs were specified. + authorizationSpecified = false; } } @@ -407,7 +447,16 @@ Try<process::Owned<Slave>> Slave::start( } else if (createdAuthorizer.isSome()) { slave->authorizer.reset(createdAuthorizer.get()); authorizer = createdAuthorizer.get(); + + if (authorizationSpecified) { + // Authorization config was explicitly provided, so set authorization + // callbacks in libprocess. + slave->setAuthorizationCallbacks(authorizer.get()); + } } + } else { + // An authorizer was provided, so set authorization callbacks in libprocess. + slave->setAuthorizationCallbacks(providedAuthorizer.get()); } // If the garbage collector is not provided, create a default one. @@ -467,6 +516,11 @@ Try<process::Owned<Slave>> Slave::start( Slave::~Slave() { + // Remove any libprocess authorization callbacks that were installed. + if (authorizationCallbacksSet) { + process::http::authorization::unsetCallbacks(); + } + // If either `shutdown()` or `terminate()` were called already, // skip the below container cleanup logic. Additionally, we can skip // termination, as the shutdown/terminate will do this too. @@ -511,6 +565,15 @@ Slave::~Slave() } +void Slave::setAuthorizationCallbacks(Authorizer* authorizer) +{ + process::http::authorization::setCallbacks( + mesos::createAuthorizationCallbacks(authorizer)); + + authorizationCallbacksSet = true; +} + + void Slave::shutdown() { cleanUpContainersInDestructor = false; http://git-wip-us.apache.org/repos/asf/mesos/blob/d5e1a47d/src/tests/cluster.hpp ---------------------------------------------------------------------- diff --git a/src/tests/cluster.hpp b/src/tests/cluster.hpp index 60ab3f7..c93f052 100644 --- a/src/tests/cluster.hpp +++ b/src/tests/cluster.hpp @@ -99,6 +99,9 @@ public: // The underlying master process. process::PID<master::Master> pid; + // Sets authorization callbacks in libprocess. + void setAuthorizationCallbacks(Authorizer* authorizer); + private: Master() : files(master::DEFAULT_HTTP_AUTHENTICATION_REALM) {}; @@ -122,6 +125,10 @@ private: Option<std::shared_ptr<process::RateLimiter>> slaveRemovalLimiter; + // Indicates whether or not authorization callbacks were set when this master + // was constructed. + bool authorizationCallbacksSet; + // The underlying master object. process::Owned<master::Master> master; }; @@ -166,6 +173,9 @@ public: // The underlying slave process. process::PID<slave::Slave> pid; + // Sets authorization callbacks in libprocess. + void setAuthorizationCallbacks(Authorizer* authorizer); + private: Slave() : files(slave::DEFAULT_HTTP_AUTHENTICATION_REALM) {}; @@ -203,6 +213,10 @@ private: process::Owned<mesos::slave::ResourceEstimator> resourceEstimator; process::Owned<slave::StatusUpdateManager> statusUpdateManager; + // Indicates whether or not authorization callbacks were set when this agent + // was constructed. + bool authorizationCallbacksSet; + // The underlying slave object. process::Owned<slave::Slave> slave; };
