You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by me...@apache.org on 2016/04/01 11:56:42 UTC
[2/2] mesos git commit: Added authentication to the '/registry'
endpoint.
Added authentication to the '/registry' endpoint.
Review: https://reviews.apache.org/r/45429/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5d2cec1f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5d2cec1f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5d2cec1f
Branch: refs/heads/master
Commit: 5d2cec1f3f94ecb0bd7faf44de1b9d2649cb42d5
Parents: ad072a1
Author: Jan Schlicht <ja...@mesosphere.io>
Authored: Fri Apr 1 01:19:02 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Apr 1 02:55:54 2016 -0700
----------------------------------------------------------------------
src/local/local.cpp | 3 +-
src/master/main.cpp | 3 +-
src/master/registrar.cpp | 46 ++++++++++++++++++++++-----
src/master/registrar.hpp | 9 +++++-
src/tests/cluster.cpp | 3 +-
src/tests/registrar_tests.cpp | 64 ++++++++++++++++++++++++++++++++++++++
6 files changed, 117 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/5d2cec1f/src/local/local.cpp
----------------------------------------------------------------------
diff --git a/src/local/local.cpp b/src/local/local.cpp
index e777ea2..06f6118 100644
--- a/src/local/local.cpp
+++ b/src/local/local.cpp
@@ -210,7 +210,8 @@ PID<Master> launch(const Flags& flags, Allocator* _allocator)
CHECK_NOTNULL(storage);
state = new state::protobuf::State(storage);
- registrar = new Registrar(flags, state);
+ registrar =
+ new Registrar(flags, state, master::DEFAULT_HTTP_AUTHENTICATION_REALM);
repairer = new Repairer();
contender = new StandaloneMasterContender();
http://git-wip-us.apache.org/repos/asf/mesos/blob/5d2cec1f/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index 58561cf..9dcdbda 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -326,7 +326,8 @@ int main(int argc, char** argv)
CHECK_NOTNULL(storage);
state::protobuf::State* state = new state::protobuf::State(storage);
- Registrar* registrar = new Registrar(flags, state);
+ Registrar* registrar =
+ new Registrar(flags, state, DEFAULT_HTTP_AUTHENTICATION_REALM);
Repairer* repairer = new Repairer();
Files files(DEFAULT_HTTP_AUTHENTICATION_REALM);
http://git-wip-us.apache.org/repos/asf/mesos/blob/5d2cec1f/src/master/registrar.cpp
----------------------------------------------------------------------
diff --git a/src/master/registrar.cpp b/src/master/registrar.cpp
index def40b9..9f298a1 100644
--- a/src/master/registrar.cpp
+++ b/src/master/registrar.cpp
@@ -57,6 +57,7 @@ using process::Failure;
using process::Future;
using process::HELP;
using process::Owned;
+using process::PID;
using process::Process;
using process::Promise;
using process::TLDR;
@@ -80,12 +81,16 @@ using process::http::Request;
class RegistrarProcess : public Process<RegistrarProcess>
{
public:
- RegistrarProcess(const Flags& _flags, State* _state)
+ RegistrarProcess(
+ const Flags& _flags,
+ State* _state,
+ const Option<string>& _authenticationRealm)
: ProcessBase(process::ID::generate("registrar")),
metrics(*this),
updating(false),
flags(_flags),
- state(_state) {}
+ state(_state),
+ authenticationRealm(_authenticationRealm) {}
virtual ~RegistrarProcess() {}
@@ -96,13 +101,26 @@ public:
protected:
virtual void initialize()
{
- route("/registry", registryHelp(), &RegistrarProcess::registry);
+ if (authenticationRealm.isSome()) {
+ route(
+ "/registry",
+ authenticationRealm.get(),
+ registryHelp(),
+ &RegistrarProcess::registry);
+ } else {
+ route(
+ "/registry",
+ registryHelp(),
+ lambda::bind(&RegistrarProcess::registry, this, lambda::_1, None()));
+ }
}
private:
// HTTP handlers.
// /registrar(N)/registry
- Future<Response> registry(const Request& request);
+ Future<Response> registry(
+ const Request& request,
+ const Option<string>& /* principal */);
static string registryHelp();
// The 'Recover' operation adds the latest MasterInfo.
@@ -208,6 +226,10 @@ private:
// When an error is encountered from abort(), we'll fail all
// subsequent operations.
Option<Error> error;
+
+ // The authentication realm, if any, into which this process'
+ // endpoints will be installed.
+ Option<string> authenticationRealm;
};
@@ -235,7 +257,9 @@ void fail(deque<Owned<Operation>>* operations, const string& message)
}
-Future<Response> RegistrarProcess::registry(const Request& request)
+Future<Response> RegistrarProcess::registry(
+ const Request& request,
+ const Option<string>& /* principal */)
{
JSON::Object result;
@@ -509,9 +533,12 @@ void RegistrarProcess::abort(const string& message)
}
-Registrar::Registrar(const Flags& flags, State* state)
+Registrar::Registrar(
+ const Flags& flags,
+ State* state,
+ const Option<string>& authenticationRealm)
{
- process = new RegistrarProcess(flags, state);
+ process = new RegistrarProcess(flags, state, authenticationRealm);
spawn(process);
}
@@ -535,6 +562,11 @@ Future<bool> Registrar::apply(Owned<Operation> operation)
return dispatch(process, &RegistrarProcess::apply, operation);
}
+PID<RegistrarProcess> Registrar::pid() const
+{
+ return process->self();
+}
+
} // namespace master {
} // namespace internal {
} // namespace mesos {
http://git-wip-us.apache.org/repos/asf/mesos/blob/5d2cec1f/src/master/registrar.hpp
----------------------------------------------------------------------
diff --git a/src/master/registrar.hpp b/src/master/registrar.hpp
index f087569..b28e306 100644
--- a/src/master/registrar.hpp
+++ b/src/master/registrar.hpp
@@ -23,6 +23,7 @@
#include <process/future.hpp>
#include <process/owned.hpp>
+#include <process/pid.hpp>
#include "master/flags.hpp"
#include "master/registry.hpp"
@@ -102,7 +103,9 @@ class Registrar
public:
// If flags.registry_strict is true, all operations will be
// permitted.
- Registrar(const Flags& flags, state::protobuf::State* state);
+ Registrar(const Flags& flags,
+ state::protobuf::State* state,
+ const Option<std::string>& authenticationRealm = None());
~Registrar();
// Recovers the Registry, persisting the new Master information.
@@ -122,6 +125,10 @@ public:
// or recovery failed.
process::Future<bool> apply(process::Owned<Operation> operation);
+ // Gets the pid of the underlying process.
+ // Used in tests.
+ process::PID<RegistrarProcess> pid() const;
+
private:
RegistrarProcess* process;
};
http://git-wip-us.apache.org/repos/asf/mesos/blob/5d2cec1f/src/tests/cluster.cpp
----------------------------------------------------------------------
diff --git a/src/tests/cluster.cpp b/src/tests/cluster.cpp
index 2da0bd7..14d0d34 100644
--- a/src/tests/cluster.cpp
+++ b/src/tests/cluster.cpp
@@ -213,7 +213,8 @@ Try<process::Owned<Master>> Master::start(
// Instantiate some other master dependencies.
master->state.reset(new state::protobuf::State(master->storage.get()));
- master->registrar.reset(new master::Registrar(flags, master->state.get()));
+ master->registrar.reset(new master::Registrar(
+ flags, master->state.get(), master::DEFAULT_HTTP_AUTHENTICATION_REALM));
master->repairer.reset(new master::Repairer());
if (slaveRemovalLimiter.isNone() && flags.slave_removal_rate_limit.isSome()) {
http://git-wip-us.apache.org/repos/asf/mesos/blob/5d2cec1f/src/tests/registrar_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/registrar_tests.cpp b/src/tests/registrar_tests.cpp
index 39caf9b..f8e141b 100644
--- a/src/tests/registrar_tests.cpp
+++ b/src/tests/registrar_tests.cpp
@@ -24,6 +24,8 @@
#include <mesos/attributes.hpp>
#include <mesos/type_utils.hpp>
+#include <mesos/authentication/http/basic_authenticator_factory.hpp>
+
#include <process/clock.hpp>
#include <process/gmock.hpp>
#include <process/gtest.hpp>
@@ -56,6 +58,8 @@
#include "state/protobuf.hpp"
#include "state/storage.hpp"
+#include "tests/mesos.hpp"
+
using namespace mesos::internal::master;
using namespace process;
@@ -71,6 +75,11 @@ using std::string;
using std::vector;
using process::Clock;
+using process::Owned;
+
+using process::http::OK;
+using process::http::Response;
+using process::http::Unauthorized;
using google::protobuf::RepeatedPtrField;
@@ -93,6 +102,8 @@ namespace tests {
namespace quota = mesos::internal::master::quota;
namespace weights = mesos::internal::master::weights;
+namespace authentication = process::http::authentication;
+
using namespace mesos::maintenance;
using namespace mesos::quota;
@@ -100,6 +111,8 @@ using namespace mesos::internal::master::maintenance;
using namespace mesos::internal::master::quota;
using namespace mesos::internal::master::weights;
+using mesos::http::authentication::BasicAuthenticatorFactory;
+
using state::Entry;
using state::LogStorage;
using state::Storage;
@@ -1093,6 +1106,57 @@ TEST_P(RegistrarTest, Abort)
}
+// Tests that requests to the '/registry' endpoint are authenticated when HTTP
+// authentication is enabled.
+TEST_P(RegistrarTest, Authentication)
+{
+ const string AUTHENTICATION_REALM = "realm";
+
+ Credentials credentials;
+ credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
+
+ Try<authentication::Authenticator*> authenticator =
+ BasicAuthenticatorFactory::create(AUTHENTICATION_REALM, credentials);
+
+ ASSERT_SOME(authenticator);
+
+ AWAIT_READY(authentication::setAuthenticator(
+ AUTHENTICATION_REALM,
+ Owned<authentication::Authenticator>(authenticator.get())));
+
+ Registrar registrar(flags, state, AUTHENTICATION_REALM);
+
+ // Requests without credentials should be rejected.
+ Future<Response> response = process::http::get(registrar.pid(), "registry");
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response)
+ << response.get().body;
+
+ Credential badCredential;
+ badCredential.set_principal("bad-principal");
+ badCredential.set_secret("bad-secret");
+
+ // Requests with bad credentials should be rejected.
+ response = process::http::get(
+ registrar.pid(),
+ "registry",
+ None(),
+ createBasicAuthHeaders(badCredential));
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response)
+ << response.get().body;
+
+ // Requests with good credentials should be permitted.
+ response = process::http::get(
+ registrar.pid(),
+ "registry",
+ None(),
+ createBasicAuthHeaders(DEFAULT_CREDENTIAL));
+ AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response)
+ << response.get().body;
+
+ AWAIT_READY(authentication::unsetAuthenticator(AUTHENTICATION_REALM));
+}
+
+
class Registrar_BENCHMARK_Test
: public RegistrarTestBase,
public WithParamInterface<size_t> {};