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/07/22 09:43:25 UTC

[1/6] mesos git commit: Separated AuthN for readonly and readwrite endpoints in Mesos.

Repository: mesos
Updated Branches:
  refs/heads/1.0.x 6cd20e9f3 -> d15e684cb


Separated AuthN for readonly and readwrite endpoints in Mesos.

Changes included:
- separate flags for readonly and readwrite endpoints;
- helper function for registering http authenticator;
- fixing existing tests.

Review: https://reviews.apache.org/r/50223/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/67369c01
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/67369c01
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/67369c01

Branch: refs/heads/1.0.x
Commit: 67369c01ce3eac2ff9aab4f776c0815cec3b883c
Parents: a76800c
Author: Zhitao Li <zh...@gmail.com>
Authored: Thu Jul 21 23:43:34 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Jul 22 02:02:24 2016 -0700

----------------------------------------------------------------------
 src/local/local.cpp                             |   2 +-
 src/master/constants.hpp                        |   9 +-
 src/master/flags.cpp                            |  20 +-
 src/master/flags.hpp                            |   3 +-
 src/master/main.cpp                             |   9 +-
 src/master/master.cpp                           | 275 ++++++++-----------
 src/master/master.hpp                           |   7 +
 src/slave/constants.hpp                         |   7 +-
 src/slave/flags.cpp                             |  17 +-
 src/slave/flags.hpp                             |   3 +-
 src/slave/main.cpp                              |   7 +-
 src/slave/slave.cpp                             | 209 +++++++-------
 src/slave/slave.hpp                             |   7 +
 src/tests/cluster.cpp                           |  11 +-
 src/tests/cluster.hpp                           |   4 +-
 src/tests/dynamic_weights_tests.cpp             |   2 +-
 src/tests/logging_tests.cpp                     |   8 +-
 src/tests/main.cpp                              |   5 +-
 src/tests/master_quota_tests.cpp                |  12 +-
 src/tests/master_tests.cpp                      |  58 +++-
 src/tests/mesos.cpp                             |   8 +-
 src/tests/mesos.hpp                             |   3 +-
 src/tests/metrics_tests.cpp                     |  16 +-
 src/tests/persistent_volume_endpoints_tests.cpp |   2 +-
 src/tests/reservation_endpoints_tests.cpp       |   2 +-
 src/tests/slave_tests.cpp                       |  38 +++
 26 files changed, 417 insertions(+), 327 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/local/local.cpp
----------------------------------------------------------------------
diff --git a/src/local/local.cpp b/src/local/local.cpp
index a543aef..a1a9a6b 100644
--- a/src/local/local.cpp
+++ b/src/local/local.cpp
@@ -226,7 +226,7 @@ PID<Master> launch(const Flags& flags, Allocator* _allocator)
 
     state = new mesos::state::protobuf::State(storage);
     registrar =
-      new Registrar(flags, state, master::DEFAULT_HTTP_AUTHENTICATION_REALM);
+      new Registrar(flags, state, master::READONLY_HTTP_AUTHENTICATION_REALM);
 
     contender = new StandaloneMasterContender();
     detector = new StandaloneMasterDetector();

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/master/constants.hpp
----------------------------------------------------------------------
diff --git a/src/master/constants.hpp b/src/master/constants.hpp
index 410c388..e353b63 100644
--- a/src/master/constants.hpp
+++ b/src/master/constants.hpp
@@ -124,8 +124,13 @@ constexpr char DEFAULT_AUTHORIZER[] = "local";
 // Name of the default, basic authenticator.
 constexpr char DEFAULT_HTTP_AUTHENTICATOR[] = "basic";
 
-// Name of the default master HTTP authentication realm.
-constexpr char DEFAULT_HTTP_AUTHENTICATION_REALM[] = "mesos-master";
+// Name of the master HTTP authentication realm for read-only endpoints.
+constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] =
+  "mesos-master-readonly";
+
+// Name of the master HTTP authentication realm for read-write endpoints.
+constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] =
+  "mesos-master-readwrite";
 
 // Name of the default authentication realm for HTTP frameworks.
 constexpr char DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM[] =

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/master/flags.cpp
----------------------------------------------------------------------
diff --git a/src/master/flags.cpp b/src/master/flags.cpp
index ca3e80b..93ddf6b 100644
--- a/src/master/flags.cpp
+++ b/src/master/flags.cpp
@@ -222,11 +222,21 @@ mesos::internal::master::Flags::Flags()
       "If `false`, unauthenticated agents are also allowed to register.",
       false);
 
-  add(&Flags::authenticate_http,
-      "authenticate_http",
-      "If `true`, only authenticated requests for HTTP endpoints supporting\n"
-      "authentication are allowed. If `false`, unauthenticated requests to\n"
-      "HTTP endpoints are also allowed.\n",
+  // TODO(zhitao): Remove deprecated `--authenticate_http` flag name after
+  // the deprecation cycle which started with Mesos 1.0.
+  add(&Flags::authenticate_http_readwrite,
+      "authenticate_http_readwrite",
+      flags::DeprecatedName("authenticate_http"),
+      "If `true`, only authenticated requests for read-write HTTP endpoints\n"
+      "supporting authentication are allowed. If `false`, unauthenticated\n"
+      "requests to such HTTP endpoints are also allowed.",
+      false);
+
+  add(&Flags::authenticate_http_readonly,
+      "authenticate_http_readonly",
+      "If `true`, only authenticated requests for read-only HTTP endpoints\n"
+      "supporting authentication are allowed. If `false`, unauthenticated\n"
+      "requests to such HTTP endpoints are also allowed.",
       false);
 
   add(&Flags::authenticate_http_frameworks,

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/master/flags.hpp
----------------------------------------------------------------------
diff --git a/src/master/flags.hpp b/src/master/flags.hpp
index a5dd11b..c6e8530 100644
--- a/src/master/flags.hpp
+++ b/src/master/flags.hpp
@@ -66,7 +66,8 @@ public:
   Option<std::string> weights;
   bool authenticate_frameworks;
   bool authenticate_agents;
-  bool authenticate_http;
+  bool authenticate_http_readonly;
+  bool authenticate_http_readwrite;
   bool authenticate_http_frameworks;
   Option<Path> credentials;
   Option<ACLs> acls;

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index 9775b8a..6146c31 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -275,7 +275,10 @@ int main(int argc, char** argv)
   // `false`, then it has already been called, which means that the
   // authentication realm for libprocess-level HTTP endpoints was not set to the
   // correct value for the master.
-  if (!process::initialize("master", DEFAULT_HTTP_AUTHENTICATION_REALM)) {
+  if (!process::initialize(
+          "master",
+          READWRITE_HTTP_AUTHENTICATION_REALM,
+          READONLY_HTTP_AUTHENTICATION_REALM)) {
     EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the master's "
                        << "`main()` was not the function's first invocation";
   }
@@ -435,7 +438,7 @@ int main(int argc, char** argv)
   mesos::state::protobuf::State* state =
     new mesos::state::protobuf::State(storage);
   Registrar* registrar =
-    new Registrar(flags, state, DEFAULT_HTTP_AUTHENTICATION_REALM);
+    new Registrar(flags, state, READONLY_HTTP_AUTHENTICATION_REALM);
 
   MasterContender* contender;
   MasterDetector* detector;
@@ -504,7 +507,7 @@ int main(int argc, char** argv)
         createAuthorizationCallbacks(authorizer_.get()));
   }
 
-  Files files(DEFAULT_HTTP_AUTHENTICATION_REALM, authorizer_);
+  Files files(READONLY_HTTP_AUTHENTICATION_REALM, authorizer_);
 
   Option<shared_ptr<RateLimiter>> slaveRemovalLimiter = None();
   if (flags.agent_removal_rate_limit.isSome()) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 79e3d78..219e850 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -377,6 +377,78 @@ struct BoundedRateLimiter
 };
 
 
+void Master::registerHttpAuthenticator(
+    const string& realm,
+    const Option<Credentials>& credentials,
+    const vector<string>& httpAuthenticatorNames)
+{
+  // At least the default authenticator is always specified.
+  // Passing an empty string into the `http_authenticators`
+  // flag is considered an error.
+  if (httpAuthenticatorNames.empty()) {
+    EXIT(EXIT_FAILURE)
+      << "No HTTP authenticator specified for realm '" << realm << "'";
+  }
+
+  if (httpAuthenticatorNames.size() > 1) {
+    EXIT(EXIT_FAILURE) << "Multiple HTTP authenticators not supported";
+  }
+
+  if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
+      !modules::ModuleManager::contains<authentication::Authenticator>(
+          httpAuthenticatorNames[0])) {
+    EXIT(EXIT_FAILURE)
+      << "HTTP authenticator '" << httpAuthenticatorNames[0] << "' not"
+      << " found. Check the spelling (compare to '"
+      << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
+      << " authenticator was loaded successfully (see --modules)";
+  }
+
+  Option<authentication::Authenticator*> httpAuthenticator;
+  if (httpAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
+    if (credentials.isNone()) {
+      EXIT(EXIT_FAILURE)
+        << "No credentials provided for the default '"
+        << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP authenticator for realm '"
+        << realm << "'";
+    }
+
+    LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
+              << "' HTTP authenticator for realm '" << realm << "'";
+
+    Try<authentication::Authenticator*> authenticator =
+      BasicAuthenticatorFactory::create(realm, credentials.get());
+    if (authenticator.isError()) {
+      EXIT(EXIT_FAILURE)
+        << "Could not create HTTP authenticator module '"
+        << httpAuthenticatorNames[0] << "': " << authenticator.error();
+    }
+
+    httpAuthenticator = authenticator.get();
+  } else {
+    Try<authentication::Authenticator*> module =
+      modules::ModuleManager::create<authentication::Authenticator>(
+          httpAuthenticatorNames[0]);
+    if (module.isError()) {
+      EXIT(EXIT_FAILURE)
+        << "Could not create HTTP authenticator module '"
+        << httpAuthenticatorNames[0] << "': " << module.error();
+    }
+    LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
+              << "' HTTP authenticator for realm '" << realm << "'";
+    httpAuthenticator = module.get();
+  }
+
+  if (httpAuthenticator.isSome() && httpAuthenticator.get() != nullptr) {
+    // Ownership of the `httpAuthenticator` is passed to libprocess.
+    process::http::authentication::setAuthenticator(
+        realm,
+        Owned<authentication::Authenticator>(httpAuthenticator.get()));
+    httpAuthenticator = None();
+  }
+}
+
+
 void Master::initialize()
 {
   LOG(INFO) << "Master " << info_.id() << " (" << info_.hostname() << ")"
@@ -541,75 +613,18 @@ void Master::initialize()
   }
 #endif // HAS_AUTHENTICATION
 
-  // TODO(arojas): Consider creating a factory function for the instantiation
-  // of the HTTP authenticator the same way the allocator does.
-  vector<string> httpAuthenticatorNames =
-    strings::split(flags.http_authenticators, ",");
-
-  // At least the default authenticator is always specified.
-  // Passing an empty string into the `http_authenticators`
-  // flag is considered an error.
-  if (httpAuthenticatorNames.empty()) {
-    EXIT(EXIT_FAILURE) << "No HTTP authenticator specified";
-  }
-  if (httpAuthenticatorNames.size() > 1) {
-    EXIT(EXIT_FAILURE) << "Multiple HTTP authenticators not supported";
-  }
-  if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
-      !modules::ModuleManager::contains<authentication::Authenticator>(
-          httpAuthenticatorNames[0])) {
-    EXIT(EXIT_FAILURE)
-      << "HTTP authenticator '" << httpAuthenticatorNames[0] << "' not"
-      << " found. Check the spelling (compare to '"
-      << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
-      << " authenticator was loaded successfully (see --modules)";
-  }
-
-  Option<authentication::Authenticator*> httpAuthenticator;
-
-  if (flags.authenticate_http) {
-    if (httpAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
-      if (credentials.isNone()) {
-        EXIT(EXIT_FAILURE)
-          << "No credentials provided for the default '"
-          << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP authenticator";
-      }
-
-      LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
-                << "' HTTP authenticator";
-
-      Try<authentication::Authenticator*> authenticator =
-        BasicAuthenticatorFactory::create(
-            DEFAULT_HTTP_AUTHENTICATION_REALM,
-            credentials.get());
-      if (authenticator.isError()) {
-        EXIT(EXIT_FAILURE)
-          << "Could not create HTTP authenticator module '"
-          << httpAuthenticatorNames[0] << "': " << authenticator.error();
-      }
-
-      httpAuthenticator = authenticator.get();
-    } else {
-      Try<authentication::Authenticator*> module =
-        modules::ModuleManager::create<authentication::Authenticator>(
-            httpAuthenticatorNames[0]);
-      if (module.isError()) {
-        EXIT(EXIT_FAILURE)
-          << "Could not create HTTP authenticator module '"
-          << httpAuthenticatorNames[0] << "': " << module.error();
-      }
-      LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
-                << "' HTTP authenticator";
-      httpAuthenticator = module.get();
-    }
+  if (flags.authenticate_http_readonly) {
+    registerHttpAuthenticator(
+      READONLY_HTTP_AUTHENTICATION_REALM,
+      credentials,
+      strings::split(flags.http_authenticators, ","));
   }
 
-  if (httpAuthenticator.isSome() && httpAuthenticator.get() != nullptr) {
-    // Ownership of the `httpAuthenticator` is passed to libprocess.
-    process::http::authentication::setAuthenticator(
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
-        Owned<authentication::Authenticator>(httpAuthenticator.get()));
-    httpAuthenticator = None();
+  if (flags.authenticate_http_readwrite) {
+    registerHttpAuthenticator(
+      READWRITE_HTTP_AUTHENTICATION_REALM,
+      credentials,
+      strings::split(flags.http_authenticators, ","));
   }
 
   if (flags.authenticate_http_frameworks) {
@@ -621,84 +636,10 @@ void Master::initialize()
         << "in conjunction with `--authenticate_http_frameworks`";
     }
 
-    vector<string> httpFrameworkAuthenticatorNames =
-      strings::split(flags.http_framework_authenticators.get(), ",");
-
-    // Passing an empty string into the `http_framework_authenticators`
-    // flag is considered an error.
-    if (httpFrameworkAuthenticatorNames.empty()) {
-      EXIT(EXIT_FAILURE) << "No HTTP framework authenticator specified";
-    }
-
-    if (httpFrameworkAuthenticatorNames.size() > 1) {
-      EXIT(EXIT_FAILURE) << "Multiple HTTP framework authenticators not "
-                         << "supported";
-    }
-
-    if (httpFrameworkAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
-        !modules::ModuleManager::contains<authentication::Authenticator>(
-            httpFrameworkAuthenticatorNames[0])) {
-      EXIT(EXIT_FAILURE)
-        << "HTTP framework authenticator '"
-        << httpFrameworkAuthenticatorNames[0]
-        << "' not found. Check the spelling (compare to '"
-        << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
-        << " authenticator was loaded successfully (see --modules)";
-    }
-
-    Option<authentication::Authenticator*> httpFrameworkAuthenticator;
-
-    if (httpFrameworkAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
-      if (credentials.isNone()) {
-        EXIT(EXIT_FAILURE)
-          << "No credentials provided for the default '"
-          << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP framework authenticator";
-      }
-
-      LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
-                << "' HTTP framework authenticator";
-
-      Try<authentication::Authenticator*> authenticator =
-        BasicAuthenticatorFactory::create(
-            DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
-            credentials.get());
-
-      if (authenticator.isError()) {
-        EXIT(EXIT_FAILURE)
-          << "Could not create HTTP framework authenticator module '"
-          << httpFrameworkAuthenticatorNames[0] << "': "
-          << authenticator.error();
-      }
-
-      httpFrameworkAuthenticator = authenticator.get();
-    } else {
-      Try<authentication::Authenticator*> module =
-        modules::ModuleManager::create<authentication::Authenticator>(
-            httpFrameworkAuthenticatorNames[0]);
-
-      if (module.isError()) {
-        EXIT(EXIT_FAILURE)
-          << "Could not create HTTP framework authenticator module '"
-          << httpFrameworkAuthenticatorNames[0] << "': " << module.error();
-      }
-
-      LOG(INFO) << "Using '" << httpFrameworkAuthenticatorNames[0]
-                << "' HTTP framework authenticator";
-
-      httpFrameworkAuthenticator = module.get();
-    }
-
-    CHECK_SOME(httpFrameworkAuthenticator);
-
-    if (httpFrameworkAuthenticator.get() != nullptr) {
-      // Ownership of the `httpFrameworkAuthenticator` is passed to libprocess.
-      process::http::authentication::setAuthenticator(
-          DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
-          Owned<authentication::Authenticator>(
-              httpFrameworkAuthenticator.get()));
-    }
-
-    httpFrameworkAuthenticator = None();
+    registerHttpAuthenticator(
+      DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
+      credentials,
+      strings::split(flags.http_framework_authenticators.get(), ","));
   }
 
   if (authorizer.isSome()) {
@@ -968,7 +909,7 @@ void Master::initialize()
         // TODO(benh): Is this authentication realm sufficient or do
         // we need some kind of hybrid if we expect both schedulers
         // and operators/tooling to use this endpoint?
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::API_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -984,7 +925,7 @@ void Master::initialize()
           return http.scheduler(request, principal);
         });
   route("/create-volumes",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::CREATE_VOLUMES_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -992,7 +933,7 @@ void Master::initialize()
           return http.createVolumes(request, principal);
         });
   route("/destroy-volumes",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::DESTROY_VOLUMES_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1000,7 +941,7 @@ void Master::initialize()
           return http.destroyVolumes(request, principal);
         });
   route("/frameworks",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::FRAMEWORKS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1008,7 +949,7 @@ void Master::initialize()
           return http.frameworks(request, principal);
         });
   route("/flags",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::FLAGS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1026,7 +967,7 @@ void Master::initialize()
           return http.redirect(request);
         });
   route("/reserve",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::RESERVE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1036,7 +977,7 @@ void Master::initialize()
   // TODO(ijimenez): Remove this endpoint at the end of the
   // deprecation cycle on 0.26.
   route("/roles.json",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::ROLES_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1044,7 +985,7 @@ void Master::initialize()
           return http.roles(request, principal);
         });
   route("/roles",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::ROLES_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1052,7 +993,7 @@ void Master::initialize()
           return http.roles(request, principal);
         });
   route("/teardown",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::TEARDOWN_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1060,7 +1001,7 @@ void Master::initialize()
           return http.teardown(request, principal);
         });
   route("/slaves",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::SLAVES_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1070,7 +1011,7 @@ void Master::initialize()
   // TODO(ijimenez): Remove this endpoint at the end of the
   // deprecation cycle on 0.26.
   route("/state.json",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1078,7 +1019,7 @@ void Master::initialize()
           return http.state(request, principal);
         });
   route("/state",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1086,7 +1027,7 @@ void Master::initialize()
           return http.state(request, principal);
         });
   route("/state-summary",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATESUMMARY_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1096,7 +1037,7 @@ void Master::initialize()
   // TODO(ijimenez): Remove this endpoint at the end of the
   // deprecation cycle.
   route("/tasks.json",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::TASKS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1104,7 +1045,7 @@ void Master::initialize()
           return http.tasks(request, principal);
         });
   route("/tasks",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::TASKS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1112,7 +1053,7 @@ void Master::initialize()
           return http.tasks(request, principal);
         });
   route("/maintenance/schedule",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::MAINTENANCE_SCHEDULE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1120,7 +1061,7 @@ void Master::initialize()
           return http.maintenanceSchedule(request, principal);
         });
   route("/maintenance/status",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::MAINTENANCE_STATUS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1128,7 +1069,7 @@ void Master::initialize()
           return http.maintenanceStatus(request, principal);
         });
   route("/machine/down",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::MACHINE_DOWN_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1136,7 +1077,7 @@ void Master::initialize()
           return http.machineDown(request, principal);
         });
   route("/machine/up",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::MACHINE_UP_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1144,7 +1085,7 @@ void Master::initialize()
           return http.machineUp(request, principal);
         });
   route("/unreserve",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::UNRESERVE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1152,7 +1093,7 @@ void Master::initialize()
           return http.unreserve(request, principal);
         });
   route("/quota",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::QUOTA_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -1160,7 +1101,7 @@ void Master::initialize()
           return http.quota(request, principal);
         });
   route("/weights",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::WEIGHTS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 46621b8..bed6b8a 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1870,6 +1870,13 @@ private:
   process::Future<Option<Error>> validate(
       const FrameworkInfo& frameworkInfo,
       const process::UPID& from);
+
+  // Helper function to create HTTP authenticator
+  // for a given realm and register in libprocess.
+  void registerHttpAuthenticator(
+      const std::string& realm,
+      const Option<Credentials>& credentials,
+      const std::vector<std::string>& authenticatorNames);
 };
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/slave/constants.hpp
----------------------------------------------------------------------
diff --git a/src/slave/constants.hpp b/src/slave/constants.hpp
index 1031939..46ef54e 100644
--- a/src/slave/constants.hpp
+++ b/src/slave/constants.hpp
@@ -127,8 +127,11 @@ constexpr char DEFAULT_AUTHORIZER[] = "local";
 // Name of the default HTTP authenticator.
 constexpr char DEFAULT_HTTP_AUTHENTICATOR[] = "basic";
 
-// Name of the default agent HTTP authentication realm.
-constexpr char DEFAULT_HTTP_AUTHENTICATION_REALM[] = "mesos-agent";
+// Name of the agent HTTP authentication realm for read-only endpoints.
+constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readonly";
+
+// Name of the agent HTTP authentication realm for read-write endpoints.
+constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readwrite";
 
 // Default maximum storage space to be used by the fetcher cache.
 constexpr Bytes DEFAULT_FETCHER_CACHE_SIZE = Gigabytes(2);

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index 84dbb2d..d7714de 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -786,11 +786,18 @@ mesos::internal::slave::Flags::Flags()
       "Currently there is no support for multiple HTTP authenticators.",
       DEFAULT_HTTP_AUTHENTICATOR);
 
-  add(&Flags::authenticate_http,
-      "authenticate_http",
-      "If `true`, only authenticated requests for HTTP endpoints supporting\n"
-      "authentication are allowed. If `false`, unauthenticated requests to\n"
-      "HTTP endpoints are also allowed.",
+  add(&Flags::authenticate_http_readwrite,
+      "authenticate_http_readwrite",
+      "If `true`, only authenticated requests for read-write HTTP endpoints\n"
+      "supporting authentication are allowed. If `false`, unauthenticated\n"
+      "requests to such HTTP endpoints are also allowed.",
+      false);
+
+  add(&Flags::authenticate_http_readonly,
+      "authenticate_http_readonly",
+      "If `true`, only authenticated requests for read-only HTTP endpoints\n"
+      "supporting authentication are allowed. If `false`, unauthenticated\n"
+      "requests to such HTTP endpoints are also allowed.",
       false);
 
   add(&Flags::http_credentials,

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index e798dbf..58fba4a 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -139,7 +139,8 @@ public:
   std::string authenticatee;
   std::string authorizer;
   std::string http_authenticators;
-  bool authenticate_http;
+  bool authenticate_http_readonly;
+  bool authenticate_http_readwrite;
   Option<Path> http_credentials;
   Option<std::string> hooks;
   Option<std::string> resource_estimator;

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/slave/main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index 4624392..a4d971a 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -256,7 +256,10 @@ int main(int argc, char** argv)
   // If `process::initialize()` returns `false`, then it was called before this
   // invocation, meaning the authentication realm for libprocess-level HTTP
   // endpoints was set incorrectly. This should be the first invocation.
-  if (!process::initialize(id, DEFAULT_HTTP_AUTHENTICATION_REALM)) {
+  if (!process::initialize(
+          id,
+          READWRITE_HTTP_AUTHENTICATION_REALM,
+          READONLY_HTTP_AUTHENTICATION_REALM)) {
     EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the agent's "
                        << "`main()` was not the function's first invocation";
   }
@@ -405,7 +408,7 @@ int main(int argc, char** argv)
         createAuthorizationCallbacks(authorizer_.get()));
   }
 
-  Files files(DEFAULT_HTTP_AUTHENTICATION_REALM, authorizer_);
+  Files files(READONLY_HTTP_AUTHENTICATION_REALM, authorizer_);
   GarbageCollector gc;
   StatusUpdateManager statusUpdateManager(flags);
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 02982d5..0a0bc70 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -345,109 +345,33 @@ void Slave::initialize()
     }
   }
 
-  vector<string> httpAuthenticatorNames =
-    strings::split(flags.http_authenticators, ",");
-
-  // If the `http_authenticators` flag is not specified, the default value will
-  // be filled in. Passing an empty string into the `http_authenticators` flag
-  // is considered an error.
-  if (httpAuthenticatorNames.empty()) {
-    EXIT(EXIT_FAILURE) << "No HTTP authenticator specified";
-  }
-  if (httpAuthenticatorNames.size() > 1) {
-    EXIT(EXIT_FAILURE) << "Multiple HTTP authenticators not supported";
-  }
-  if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
-      !modules::ModuleManager::contains<authentication::Authenticator>(
-          httpAuthenticatorNames[0])) {
-    EXIT(EXIT_FAILURE)
-      << "HTTP authenticator '" << httpAuthenticatorNames[0] << "'"
-      << " not found. Check the spelling (compare to '"
-      << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
-      << " authenticator was loaded successfully (see --modules)";
-  }
-
-  if (flags.authenticate_http) {
-    authentication::Authenticator* httpAuthenticator = nullptr;
-
-    if (httpAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
-      // Load credentials for HTTP authentication.
-      Credentials httpCredentials;
-      if (flags.http_credentials.isSome()) {
-        Result<Credentials> credentials =
-          credentials::read(flags.http_credentials.get());
-        if (credentials.isError()) {
-          EXIT(EXIT_FAILURE)
-            << credentials.error() << " (see --http_credentials flag)";
-        } else if (credentials.isNone()) {
-          EXIT(EXIT_FAILURE)
-            << "Credentials file must contain at least one credential"
-            << " (see --http_credentials flag)";
-        }
-
-        httpCredentials = credentials.get();
-      } else {
-        EXIT(EXIT_FAILURE)
-          << "No credentials provided for the default '"
-          << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP authenticator";
-      }
-
-      LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
-                << "' HTTP authenticator";
-
-      Try<authentication::Authenticator*> authenticator =
-        BasicAuthenticatorFactory::create(
-            DEFAULT_HTTP_AUTHENTICATION_REALM,
-            httpCredentials);
-      if (authenticator.isError()) {
-        EXIT(EXIT_FAILURE)
-          << "Could not create HTTP authenticator module '"
-          << httpAuthenticatorNames[0] << "': " << authenticator.error();
-      }
-
-      httpAuthenticator = authenticator.get();
-    } else {
-      if (flags.http_credentials.isSome()) {
-        EXIT(EXIT_FAILURE)
-          << "The '--http_credentials' flag is only used by the default"
-          << " basic HTTP authenticator, but a custom authenticator"
-          << " module was specified via '--http_authenticators'";
-      }
-
-      Try<authentication::Authenticator*> module =
-        modules::ModuleManager::create<authentication::Authenticator>(
-            httpAuthenticatorNames[0]);
-      if (module.isError()) {
-        EXIT(EXIT_FAILURE)
-          << "Could not create HTTP authenticator module '"
-          << httpAuthenticatorNames[0] << "': " << module.error();
-      }
-
-      LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
-                << "' HTTP authenticator";
-
-      httpAuthenticator = module.get();
+  Option<Credentials> httpCredentials;
+  if (flags.http_credentials.isSome()) {
+    Result<Credentials> credentials =
+      credentials::read(flags.http_credentials.get());
+    if (credentials.isError()) {
+       EXIT(EXIT_FAILURE)
+         << credentials.error() << " (see --http_credentials flag)";
+    } else if (credentials.isNone()) {
+       EXIT(EXIT_FAILURE)
+         << "Credentials file must contain at least one credential"
+         << " (see --http_credentials flag)";
     }
+    httpCredentials = credentials.get();
+  }
 
-    if (httpAuthenticator == nullptr) {
-      EXIT(EXIT_FAILURE)
-        << "An error occurred while initializing the '"
-        << httpAuthenticatorNames[0] << "' HTTP authenticator";
-    }
+  if (flags.authenticate_http_readonly) {
+    registerHttpAuthenticator(
+      READONLY_HTTP_AUTHENTICATION_REALM,
+      httpCredentials,
+      strings::split(flags.http_authenticators, ","));
+  }
 
-    // Ownership of the `httpAuthenticator` is passed to libprocess.
-    process::http::authentication::setAuthenticator(
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
-        Owned<authentication::Authenticator>(httpAuthenticator));
-  } else if (flags.http_credentials.isSome()) {
-    EXIT(EXIT_FAILURE)
-      << "The '--http_credentials' flag was provided, but HTTP"
-      << " authentication was not enabled via '--authenticate_http'";
-  } else if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR) {
-    EXIT(EXIT_FAILURE)
-      << "A custom HTTP authenticator was specified with the"
-      << " '--http_authenticators' flag, but HTTP authentication was not"
-      << " enabled via '--authenticate_http'";
+  if (flags.authenticate_http_readwrite) {
+    registerHttpAuthenticator(
+      READWRITE_HTTP_AUTHENTICATION_REALM,
+      httpCredentials,
+      strings::split(flags.http_authenticators, ","));
   }
 
   if ((flags.gc_disk_headroom < 0) || (flags.gc_disk_headroom > 1)) {
@@ -708,7 +632,7 @@ void Slave::initialize()
         // TODO(benh): Is this authentication realm sufficient or do
         // we need some kind of hybrid if we expect both executors
         // and operators/tooling to use this endpoint?
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READWRITE_HTTP_AUTHENTICATION_REALM,
         Http::API_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -726,7 +650,7 @@ void Slave::initialize()
   // TODO(ijimenez): Remove this endpoint at the end of the
   // deprecation cycle on 0.26.
   route("/state.json",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -734,7 +658,7 @@ void Slave::initialize()
           return http.state(request, principal);
         });
   route("/state",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATE_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -742,7 +666,7 @@ void Slave::initialize()
           return http.state(request, principal);
         });
   route("/flags",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::FLAGS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -755,7 +679,7 @@ void Slave::initialize()
           return http.health(request);
         });
   route("/monitor/statistics",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATISTICS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -764,14 +688,14 @@ void Slave::initialize()
   // TODO(ijimenez): Remove this endpoint at the end of the
   // deprecation cycle on 0.26.
   route("/monitor/statistics.json",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::STATISTICS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
           return http.statistics(request, principal);
         });
   route("/containers",
-        DEFAULT_HTTP_AUTHENTICATION_REALM,
+        READONLY_HTTP_AUTHENTICATION_REALM,
         Http::CONTAINERS_HELP(),
         [this](const process::http::Request& request,
                const Option<string>& principal) {
@@ -836,6 +760,77 @@ void Slave::initialize()
     .onAny(defer(self(), &Slave::__recover, lambda::_1));
 }
 
+
+void Slave::registerHttpAuthenticator(
+    const string& realm,
+    const Option<Credentials>& credentials,
+    const vector<string>& httpAuthenticatorNames)
+{
+  // At least the default authenticator is always specified.
+  // Passing an empty string into the `http_authenticators`
+  // flag is considered an error.
+  if (httpAuthenticatorNames.empty()) {
+    EXIT(EXIT_FAILURE)
+      << "No HTTP authenticator specified for realm '" << realm << "'";
+  }
+  if (httpAuthenticatorNames.size() > 1) {
+    EXIT(EXIT_FAILURE) << "Multiple HTTP authenticators not supported";
+  }
+  if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
+      !modules::ModuleManager::contains<authentication::Authenticator>(
+          httpAuthenticatorNames[0])) {
+    EXIT(EXIT_FAILURE)
+      << "HTTP authenticator '" << httpAuthenticatorNames[0] << "' not"
+      << " found. Check the spelling (compare to '"
+      << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
+      << " authenticator was loaded successfully (see --modules)";
+  }
+
+  Option<authentication::Authenticator*> httpAuthenticator;
+  if (httpAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
+    if (credentials.isNone()) {
+      EXIT(EXIT_FAILURE)
+        << "No credentials provided for the default '"
+        << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP authenticator for realm '"
+        << realm << "'";
+    }
+
+    LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
+              << "' HTTP authenticator for realm '" << realm << "'";
+
+    Try<authentication::Authenticator*> authenticator =
+      BasicAuthenticatorFactory::create(realm, credentials.get());
+    if (authenticator.isError()) {
+      EXIT(EXIT_FAILURE)
+        << "Could not create HTTP authenticator module '"
+        << httpAuthenticatorNames[0] << "': " << authenticator.error();
+    }
+
+    httpAuthenticator = authenticator.get();
+  } else {
+    Try<authentication::Authenticator*> module =
+      modules::ModuleManager::create<authentication::Authenticator>(
+          httpAuthenticatorNames[0]);
+    if (module.isError()) {
+      EXIT(EXIT_FAILURE)
+        << "Could not create HTTP authenticator module '"
+        << httpAuthenticatorNames[0] << "': " << module.error();
+    }
+    LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
+              << "' HTTP authenticator for realm '" << realm << "'";
+    httpAuthenticator = module.get();
+  }
+
+  if (httpAuthenticator.isSome() && httpAuthenticator.get() != nullptr) {
+    // Ownership of the `httpAuthenticator` is passed to libprocess.
+    process::http::authentication::setAuthenticator(
+        realm,
+        Owned<authentication::Authenticator>(httpAuthenticator.get()));
+    httpAuthenticator = None();
+  }
+}
+
+
 void Slave::finalize()
 {
   LOG(INFO) << "Agent terminating";

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index a8952f0..f9f725b 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -411,6 +411,13 @@ public:
       const ContainerID& containerId);
 
 private:
+  // Helper function to create HTTP authenticator
+  // for a given realm and register in libprocess.
+  void registerHttpAuthenticator(
+      const std::string& realm,
+      const Option<Credentials>& credentials,
+      const std::vector<std::string>& authenticatorNames);
+
   void _authenticate();
   void authenticationTimeout(process::Future<bool> future);
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/cluster.cpp
----------------------------------------------------------------------
diff --git a/src/tests/cluster.cpp b/src/tests/cluster.cpp
index e1be275..dd41544 100644
--- a/src/tests/cluster.cpp
+++ b/src/tests/cluster.cpp
@@ -242,7 +242,7 @@ Try<process::Owned<Master>> Master::start(
   // Instantiate some other master dependencies.
   master->state.reset(new mesos::state::protobuf::State(master->storage.get()));
   master->registrar.reset(new master::Registrar(
-      flags, master->state.get(), master::DEFAULT_HTTP_AUTHENTICATION_REALM));
+      flags, master->state.get(), master::READONLY_HTTP_AUTHENTICATION_REALM));
 
   if (slaveRemovalLimiter.isNone() && flags.agent_removal_rate_limit.isSome()) {
     // Parse the flag value.
@@ -341,7 +341,9 @@ Master::~Master()
   // NOTE: Authenticators' lifetimes are tied to libprocess's lifetime.
   // This means that multiple masters in tests are not supported.
   process::http::authentication::unsetAuthenticator(
-      master::DEFAULT_HTTP_AUTHENTICATION_REALM);
+      master::READONLY_HTTP_AUTHENTICATION_REALM);
+  process::http::authentication::unsetAuthenticator(
+      master::READWRITE_HTTP_AUTHENTICATION_REALM);
 
   process::terminate(pid);
   process::wait(pid);
@@ -518,6 +520,11 @@ Slave::~Slave()
     process::http::authorization::unsetCallbacks();
   }
 
+  process::http::authentication::unsetAuthenticator(
+      slave::READONLY_HTTP_AUTHENTICATION_REALM);
+  process::http::authentication::unsetAuthenticator(
+      slave::READWRITE_HTTP_AUTHENTICATION_REALM);
+
   // 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.

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/cluster.hpp
----------------------------------------------------------------------
diff --git a/src/tests/cluster.hpp b/src/tests/cluster.hpp
index 55dbaae..c6fbbf2 100644
--- a/src/tests/cluster.hpp
+++ b/src/tests/cluster.hpp
@@ -102,7 +102,7 @@ public:
   void setAuthorizationCallbacks(Authorizer* authorizer);
 
 private:
-  Master() : files(master::DEFAULT_HTTP_AUTHENTICATION_REALM) {};
+  Master() : files(master::READONLY_HTTP_AUTHENTICATION_REALM) {};
 
   // Not copyable, not assignable.
   Master(const Master&) = delete;
@@ -175,7 +175,7 @@ public:
   void setAuthorizationCallbacks(Authorizer* authorizer);
 
 private:
-  Slave() : files(slave::DEFAULT_HTTP_AUTHENTICATION_REALM) {};
+  Slave() : files(slave::READONLY_HTTP_AUTHENTICATION_REALM) {};
 
   // Not copyable, not assignable.
   Slave(const Slave&) = delete;

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/dynamic_weights_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/dynamic_weights_tests.cpp b/src/tests/dynamic_weights_tests.cpp
index 6aa0102..88565d1 100644
--- a/src/tests/dynamic_weights_tests.cpp
+++ b/src/tests/dynamic_weights_tests.cpp
@@ -556,7 +556,7 @@ TEST_F(DynamicWeightsTest, AuthorizedUpdateWeightRequestWithoutPrincipal)
 
   // Disable authentication and set acls.
   master::Flags masterFlags = CreateMasterFlags();
-  masterFlags.authenticate_http = false;
+  masterFlags.authenticate_http_readwrite = false;
   masterFlags.acls = acls;
 
   Try<Owned<cluster::Master>> master = StartMaster(masterFlags);

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/logging_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/logging_tests.cpp b/src/tests/logging_tests.cpp
index 8712d33..886dcd0 100644
--- a/src/tests/logging_tests.cpp
+++ b/src/tests/logging_tests.cpp
@@ -144,8 +144,8 @@ TEST_F(LoggingTest, ToggleAuthenticationEnabled)
   credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
 
   // Create a basic HTTP authenticator with the specified credentials and set it
-  // as the authenticator for `DEFAULT_HTTP_AUTHENTICATION_REALM`.
-  setBasicHttpAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, credentials);
+  // as the authenticator for `READWRITE_HTTP_AUTHENTICATION_REALM`.
+  setBasicHttpAuthenticator(READWRITE_HTTP_AUTHENTICATION_REALM, credentials);
 
   process::PID<> pid;
   pid.id = "logging";
@@ -165,8 +165,8 @@ TEST_F(LoggingTest, ToggleAuthorizationEnabled)
   credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
 
   // Create a basic HTTP authenticator with the specified credentials and set it
-  // as the authenticator for `DEFAULT_HTTP_AUTHENTICATION_REALM`.
-  setBasicHttpAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, credentials);
+  // as the authenticator for `READWRITE_HTTP_AUTHENTICATION_REALM`.
+  setBasicHttpAuthenticator(READWRITE_HTTP_AUTHENTICATION_REALM, credentials);
 
   ACLs acls;
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index 1425a04..e1507ba 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -93,7 +93,10 @@ int main(int argc, char** argv)
   // If `process::initialize()` returns `false`, then it was called before this
   // invocation, meaning the authentication realm for libprocess-level HTTP
   // endpoints was set incorrectly. This should be the first invocation.
-  if (!process::initialize(None(), DEFAULT_HTTP_AUTHENTICATION_REALM)) {
+  if (!process::initialize(
+          None(),
+          READWRITE_HTTP_AUTHENTICATION_REALM,
+          READONLY_HTTP_AUTHENTICATION_REALM)) {
     EXIT(EXIT_FAILURE) << "The call to `process::initialize()` in the tests' "
                        << "`main()` was not the function's first invocation";
   }

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/master_quota_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_quota_tests.cpp b/src/tests/master_quota_tests.cpp
index 639f4c4..48be740 100644
--- a/src/tests/master_quota_tests.cpp
+++ b/src/tests/master_quota_tests.cpp
@@ -1043,15 +1043,13 @@ TEST_F(MasterQuotaTest, NoAuthenticationNoAuthorization)
   TestAllocator<> allocator;
   EXPECT_CALL(allocator, initialize(_, _, _, _, _));
 
-  // Disable authentication and authorization.
+  // Disable http_readwrite authentication and authorization.
   // TODO(alexr): Setting master `--acls` flag to `ACLs()` or `None()` seems
   // to be semantically equal, however, the test harness currently does not
   // allow `None()`. Once MESOS-4196 is resolved, use `None()` for clarity.
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.acls = ACLs();
-  masterFlags.authenticate_http = false;
-  masterFlags.authenticate_http_frameworks = false;
-  masterFlags.credentials = None();
+  masterFlags.authenticate_http_readwrite = false;
 
   Try<Owned<cluster::Master>> master = StartMaster(&allocator, masterFlags);
   ASSERT_SOME(master);
@@ -1538,7 +1536,8 @@ TEST_F(MasterQuotaTest, AuthorizeGetUpdateQuotaRequestsWithoutPrincipal)
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.acls = acls;
-  masterFlags.authenticate_http = false;
+  masterFlags.authenticate_http_readonly = false;
+  masterFlags.authenticate_http_readwrite = false;
   masterFlags.authenticate_http_frameworks = false;
   masterFlags.credentials = None();
 
@@ -1632,7 +1631,8 @@ TEST_F(MasterQuotaTest, AuthorizeSetRemoveQuotaRequestsWithoutPrincipal)
 
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.acls = acls;
-  masterFlags.authenticate_http = false;
+  masterFlags.authenticate_http_readonly = false;
+  masterFlags.authenticate_http_readwrite = false;
   masterFlags.authenticate_http_frameworks = false;
   masterFlags.credentials = None();
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index 252b8f9..6709818 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -4451,7 +4451,7 @@ TEST_F(MasterTest, MaxCompletedTasksPerFrameworkFlag)
 }
 
 
-// Test get requests on various endpoints without authentication and
+// Test GET requests on various endpoints without authentication and
 // with bad credentials.
 // Note that we have similar checks for the maintenance, roles, quota, teardown,
 // reserve, unreserve, create-volumes, destroy-volumes, observe endpoints in the
@@ -4576,6 +4576,62 @@ TEST_F(MasterTest, EndpointsBadAuthentication)
 }
 
 
+// Test unauthenticated GET requests on various endpoints
+// when authentication is disabled for read-only endpoints.
+TEST_F(MasterTest, ReadonlyEndpointsNoAuthentication)
+{
+  // Set up a master with authentication disabled for read-only endpoints.
+  master::Flags masterFlags = CreateMasterFlags();
+  masterFlags.authenticate_http_readonly = false;
+
+  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
+  ASSERT_SOME(master);
+
+  // `state` endpoint from master should be allowed without authentication.
+  {
+    Future<Response> response = process::http::get(master.get()->pid, "state");
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+  }
+
+  // `quota` endpoint from master is controlled by `authenticate_http_readwrite`
+  // flag which is set to true, so an unauthenticated request will be rejected.
+  {
+    Future<Response> response = process::http::get(master.get()->pid, "quota");
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response);
+  }
+}
+
+
+// Test GET requests on various endpoints without authentication
+// when authentication for read-write endpoints is disabled.
+TEST_F(MasterTest, ReadwriteEndpointsNoAuthentication)
+{
+  // Set up a master with authentication disabled for read-write endpoints.
+  master::Flags masterFlags = CreateMasterFlags();
+  masterFlags.authenticate_http_readwrite = false;
+
+  Try<Owned<cluster::Master>> master = StartMaster(masterFlags);
+  ASSERT_SOME(master);
+
+  // `quota` endpoint from master should be allowed without authentication.
+  {
+    Future<Response> response = process::http::get(master.get()->pid, "quota");
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+  }
+
+  // `state` endpoint from master is controlled by `authenticate_http_readonly`
+  // flag which is set to true, so an unauthenticated request will be rejected.
+  {
+    Future<Response> response = process::http::get(master.get()->pid, "state");
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(Unauthorized({}).status, response);
+  }
+}
+
+
 TEST_F(MasterTest, RejectFrameworkWithInvalidFailoverTimeout)
 {
   Try<Owned<cluster::Master>> master = StartMaster();

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.cpp b/src/tests/mesos.cpp
index d073d79..30492d7 100644
--- a/src/tests/mesos.cpp
+++ b/src/tests/mesos.cpp
@@ -107,7 +107,8 @@ master::Flags MesosTest::CreateMasterFlags()
 
   CHECK_SOME(os::mkdir(flags.work_dir.get()));
 
-  flags.authenticate_http = true;
+  flags.authenticate_http_readonly = true;
+  flags.authenticate_http_readwrite = true;
   flags.authenticate_frameworks = true;
   flags.authenticate_agents = true;
 
@@ -196,7 +197,8 @@ slave::Flags MesosTest::CreateSlaveFlags()
     flags.acls = ACLs();
   }
 
-  flags.authenticate_http = true;
+  flags.authenticate_http_readonly = true;
+  flags.authenticate_http_readwrite = true;
 
   {
     // Create a default HTTP credentials file.
@@ -529,7 +531,7 @@ MockSlave::MockSlave(
         &resourceEstimator,
         _qosController.isSome() ? _qosController.get() : &qosController,
         authorizer),
-    files(slave::DEFAULT_HTTP_AUTHENTICATION_REALM)
+    files(slave::READONLY_HTTP_AUTHENTICATION_REALM)
 {
   // Set up default behaviors, calling the original methods.
   EXPECT_CALL(*this, runTask(_, _, _, _, _))

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/mesos.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.hpp b/src/tests/mesos.hpp
index e4eccfc..51c66f1 100644
--- a/src/tests/mesos.hpp
+++ b/src/tests/mesos.hpp
@@ -98,7 +98,8 @@ namespace mesos {
 namespace internal {
 namespace tests {
 
-constexpr char DEFAULT_HTTP_AUTHENTICATION_REALM[] = "test-realm";
+constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "test-readonly-realm";
+constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "test-readwrite-realm";
 
 // Forward declarations.
 class MockExecutor;

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/metrics_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/metrics_tests.cpp b/src/tests/metrics_tests.cpp
index e470e75..27fc35f 100644
--- a/src/tests/metrics_tests.cpp
+++ b/src/tests/metrics_tests.cpp
@@ -276,8 +276,8 @@ TEST_F(MetricsTest, MasterAuthenticationEnabled)
   credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
 
   // Create a basic HTTP authenticator with the specified credentials and set it
-  // as the authenticator for `DEFAULT_HTTP_AUTHENTICATION_REALM`.
-  setBasicHttpAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, credentials);
+  // as the authenticator for `READONLY_HTTP_AUTHENTICATION_REALM`.
+  setBasicHttpAuthenticator(READONLY_HTTP_AUTHENTICATION_REALM, credentials);
 
   Try<Owned<cluster::Master>> master = StartMaster();
   ASSERT_SOME(master);
@@ -301,8 +301,8 @@ TEST_F(MetricsTest, AgentAuthenticationEnabled)
   credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
 
   // Create a basic HTTP authenticator with the specified credentials and set it
-  // as the authenticator for `DEFAULT_HTTP_AUTHENTICATION_REALM`.
-  setBasicHttpAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, credentials);
+  // as the authenticator for `READONLY_HTTP_AUTHENTICATION_REALM`.
+  setBasicHttpAuthenticator(READONLY_HTTP_AUTHENTICATION_REALM, credentials);
 
   Try<Owned<cluster::Master>> master = StartMaster();
   ASSERT_SOME(master);
@@ -330,8 +330,8 @@ TEST_F(MetricsTest, MasterAuthorizationEnabled)
   credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
 
   // Create a basic HTTP authenticator with the specified credentials and set it
-  // as the authenticator for `DEFAULT_HTTP_AUTHENTICATION_REALM`.
-  setBasicHttpAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, credentials);
+  // as the authenticator for `READONLY_HTTP_AUTHENTICATION_REALM`.
+  setBasicHttpAuthenticator(READONLY_HTTP_AUTHENTICATION_REALM, credentials);
 
   ACLs acls;
 
@@ -370,8 +370,8 @@ TEST_F(MetricsTest, AgentAuthorizationEnabled)
   credentials.add_credentials()->CopyFrom(DEFAULT_CREDENTIAL);
 
   // Create a basic HTTP authenticator with the specified credentials and set it
-  // as the authenticator for `DEFAULT_HTTP_AUTHENTICATION_REALM`.
-  setBasicHttpAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, credentials);
+  // as the authenticator for `READONLY_HTTP_AUTHENTICATION_REALM`.
+  setBasicHttpAuthenticator(READONLY_HTTP_AUTHENTICATION_REALM, credentials);
 
   ACLs acls;
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/persistent_volume_endpoints_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/persistent_volume_endpoints_tests.cpp b/src/tests/persistent_volume_endpoints_tests.cpp
index 2a22f3b..2348f13 100644
--- a/src/tests/persistent_volume_endpoints_tests.cpp
+++ b/src/tests/persistent_volume_endpoints_tests.cpp
@@ -1353,7 +1353,7 @@ TEST_F(PersistentVolumeEndpointsTest, NoAuthentication)
 
   // Create master flags that will disable authentication.
   master::Flags masterFlags = CreateMasterFlags();
-  masterFlags.authenticate_http = false;
+  masterFlags.authenticate_http_readwrite = false;
 
   EXPECT_CALL(allocator, initialize(_, _, _, _, _));
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/reservation_endpoints_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/reservation_endpoints_tests.cpp b/src/tests/reservation_endpoints_tests.cpp
index 48c002d..bee5ea6 100644
--- a/src/tests/reservation_endpoints_tests.cpp
+++ b/src/tests/reservation_endpoints_tests.cpp
@@ -1450,7 +1450,7 @@ TEST_F(ReservationEndpointsTest, ReserveAndUnreserveNoAuthentication)
   // Create a master.
   master::Flags masterFlags = CreateMasterFlags();
   masterFlags.authenticate_frameworks = false;
-  masterFlags.authenticate_http = false;
+  masterFlags.authenticate_http_readwrite = false;
 
   EXPECT_CALL(allocator, initialize(_, _, _, _, _));
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/67369c01/src/tests/slave_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_tests.cpp b/src/tests/slave_tests.cpp
index 60f9e16..b9fa85d 100644
--- a/src/tests/slave_tests.cpp
+++ b/src/tests/slave_tests.cpp
@@ -1504,6 +1504,44 @@ TEST_F(SlaveTest, HTTPEndpointsBadAuthentication)
 }
 
 
+// Tests that a client can talk to read-only endpoints when read-only
+// authentication is disabled.
+TEST_F(SlaveTest, ReadonlyHTTPEndpointsNoAuthentication)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  // Capture the start time deterministically.
+  Clock::pause();
+
+  Future<Nothing> recover = FUTURE_DISPATCH(_, &Slave::__recover);
+
+  Owned<MasterDetector> detector = master.get()->createDetector();
+
+  slave::Flags flags = CreateSlaveFlags();
+  flags.authenticate_http_readonly = false;
+
+  Try<Owned<cluster::Slave>> slave = StartSlave(detector.get(), flags);
+  ASSERT_SOME(slave);
+
+  // Ensure slave has finished recovery.
+  AWAIT_READY(recover);
+  Clock::settle();
+
+  // Requests containing no authentication headers.
+  {
+    Future<Response> response = process::http::get(slave.get()->pid, "state");
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+
+    response = process::http::get(slave.get()->pid, "flags");
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+
+    response = process::http::get(slave.get()->pid, "containers");
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+  }
+}
+
+
 // This test verifies correct handling of statistics endpoint when
 // there is no exeuctor running.
 TEST_F(SlaveTest, StatisticsEndpointNoExecutor)


[6/6] mesos git commit: Refactored common HTTP authenticator initialize into helper function.

Posted by me...@apache.org.
Refactored common HTTP authenticator initialize into helper function.

Review: https://reviews.apache.org/r/50320/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/71f8bc38
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/71f8bc38
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/71f8bc38

Branch: refs/heads/1.0.x
Commit: 71f8bc38c198b539fe9a0dd3fa2cb3990664c002
Parents: 67369c0
Author: Zhitao Li <zh...@gmail.com>
Authored: Fri Jul 22 01:19:51 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Jul 22 02:02:25 2016 -0700

----------------------------------------------------------------------
 src/common/http.cpp      |  74 +++++++++++++++++++++++++++
 src/common/http.hpp      |  20 ++++++++
 src/master/constants.hpp |   3 --
 src/master/flags.cpp     |   1 +
 src/master/master.cpp    | 115 +++++++++---------------------------------
 src/master/master.hpp    |   7 ---
 src/slave/constants.hpp  |   3 --
 src/slave/flags.cpp      |   1 +
 src/slave/slave.cpp      | 101 ++++++-------------------------------
 src/slave/slave.hpp      |   7 ---
 10 files changed, 136 insertions(+), 196 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/common/http.cpp
----------------------------------------------------------------------
diff --git a/src/common/http.cpp b/src/common/http.cpp
index d73170d..65e7323 100644
--- a/src/common/http.cpp
+++ b/src/common/http.cpp
@@ -25,7 +25,9 @@
 #include <mesos/http.hpp>
 #include <mesos/resources.hpp>
 
+#include <mesos/authentication/http/basic_authenticator_factory.hpp>
 #include <mesos/authorizer/authorizer.hpp>
+#include <mesos/module/http_authenticator.hpp>
 
 #include <process/dispatch.hpp>
 #include <process/future.hpp>
@@ -43,6 +45,7 @@
 #include "common/http.hpp"
 
 #include "messages/messages.hpp"
+#include "module/manager.hpp"
 
 using std::map;
 using std::ostream;
@@ -53,8 +56,11 @@ using std::vector;
 using process::Failure;
 using process::Owned;
 
+using process::http::authentication::Authenticator;
 using process::http::authorization::AuthorizationCallbacks;
 
+using mesos::http::authentication::BasicAuthenticatorFactory;
+
 namespace mesos {
 
 ostream& operator<<(ostream& stream, ContentType contentType)
@@ -851,4 +857,72 @@ bool approveViewRole(
   return approved.get();
 }
 
+
+Try<Nothing> initializeHttpAuthenticators(
+    const string& realm,
+    const vector<string>& httpAuthenticatorNames,
+    const Option<Credentials>& credentials)
+{
+  if (httpAuthenticatorNames.empty()) {
+    return Error("No HTTP authenticator specified for realm '" + realm + "'");
+  }
+
+  if (httpAuthenticatorNames.size() > 1) {
+    return Error("Multiple HTTP authenticators not supported");
+  }
+
+  Option<Authenticator*> httpAuthenticator;
+  if (httpAuthenticatorNames[0] == internal::DEFAULT_HTTP_AUTHENTICATOR) {
+    if (credentials.isNone()) {
+      return Error(
+          "No credentials provided for the default '" +
+          string(internal::DEFAULT_HTTP_AUTHENTICATOR) +
+          "' HTTP authenticator for realm '" + realm + "'");
+    }
+
+    LOG(INFO) << "Using default '" << internal::DEFAULT_HTTP_AUTHENTICATOR
+              << "' HTTP authenticator for realm '" << realm << "'";
+
+    Try<Authenticator*> authenticator =
+      BasicAuthenticatorFactory::create(realm, credentials.get());
+    if (authenticator.isError()) {
+      return Error(
+          "Could not create HTTP authenticator module '" +
+          httpAuthenticatorNames[0] + "': " + authenticator.error());
+    }
+
+    httpAuthenticator = authenticator.get();
+  } else {
+    if (!modules::ModuleManager::contains<Authenticator>(
+          httpAuthenticatorNames[0])) {
+      return Error(
+          "HTTP authenticator '" + httpAuthenticatorNames[0] +
+          "' not found. Check the spelling (compare to '" +
+          string(internal::DEFAULT_HTTP_AUTHENTICATOR) +
+          "') or verify that the authenticator was loaded "
+          "successfully (see --modules)");
+    }
+
+    Try<Authenticator*> module =
+      modules::ModuleManager::create<Authenticator>(httpAuthenticatorNames[0]);
+    if (module.isError()) {
+      return Error(
+          "Could not create HTTP authenticator module '" +
+          httpAuthenticatorNames[0] + "': " + module.error());
+    }
+    LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
+              << "' HTTP authenticator for realm '" << realm << "'";
+    httpAuthenticator = module.get();
+  }
+
+  CHECK(httpAuthenticator.isSome());
+
+  // Ownership of the `httpAuthenticator` is passed to libprocess.
+  process::http::authentication::setAuthenticator(
+    realm, Owned<Authenticator>(httpAuthenticator.get()));
+
+  return Nothing();
+}
+
+
 }  // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/common/http.hpp
----------------------------------------------------------------------
diff --git a/src/common/http.hpp b/src/common/http.hpp
index 2dfa789..145f64b 100644
--- a/src/common/http.hpp
+++ b/src/common/http.hpp
@@ -42,6 +42,9 @@ class Task;
 
 namespace internal {
 
+// Name of the default, basic authenticator.
+constexpr char DEFAULT_HTTP_AUTHENTICATOR[] = "basic";
+
 extern hashset<std::string> AUTHORIZABLE_ENDPOINTS;
 
 // Serializes a protobuf message for transmission
@@ -162,6 +165,23 @@ bool approveViewRole(
     const process::Owned<ObjectApprover>& rolesApprover,
     const std::string& role);
 
+
+/**
+ * Helper function to create HTTP authenticators
+ * for a given realm and register in libprocess.
+ *
+ * @param realm name of the realm.
+ * @param authenticatorNames a vector of authenticator names.
+ * @param credentials optional credentials for BasicAuthenticator only.
+ * @return nothing if authenticators are initialized and registered to
+ *         libprocess successfully, or error if authenticators cannot
+ *         be initialized.
+ */
+Try<Nothing> initializeHttpAuthenticators(
+    const std::string& realm,
+    const std::vector<std::string>& authenticatorNames,
+    const Option<Credentials>& credentials);
+
 } // namespace mesos {
 
 #endif // __COMMON_HTTP_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/master/constants.hpp
----------------------------------------------------------------------
diff --git a/src/master/constants.hpp b/src/master/constants.hpp
index e353b63..cd80dac 100644
--- a/src/master/constants.hpp
+++ b/src/master/constants.hpp
@@ -121,9 +121,6 @@ constexpr Duration DEFAULT_ALLOCATION_INTERVAL = Seconds(1);
 // Name of the default, local authorizer.
 constexpr char DEFAULT_AUTHORIZER[] = "local";
 
-// Name of the default, basic authenticator.
-constexpr char DEFAULT_HTTP_AUTHENTICATOR[] = "basic";
-
 // Name of the master HTTP authentication realm for read-only endpoints.
 constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] =
   "mesos-master-readonly";

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/master/flags.cpp
----------------------------------------------------------------------
diff --git a/src/master/flags.cpp b/src/master/flags.cpp
index 93ddf6b..176133f 100644
--- a/src/master/flags.cpp
+++ b/src/master/flags.cpp
@@ -19,6 +19,7 @@
 
 #include <stout/flags.hpp>
 
+#include "common/http.hpp"
 #include "common/parse.hpp"
 #include "master/constants.hpp"
 #include "master/flags.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 219e850..cf2cb58 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -29,8 +29,6 @@
 
 #include <mesos/authentication/authenticator.hpp>
 
-#include <mesos/authentication/http/basic_authenticator_factory.hpp>
-
 #include <mesos/authorizer/authorizer.hpp>
 
 #include <mesos/allocator/allocator.hpp>
@@ -38,7 +36,6 @@
 #include <mesos/master/detector.hpp>
 
 #include <mesos/module/authenticator.hpp>
-#include <mesos/module/http_authenticator.hpp>
 
 #include <mesos/scheduler/scheduler.hpp>
 
@@ -122,16 +119,12 @@ namespace mesos {
 namespace internal {
 namespace master {
 
-namespace authentication = process::http::authentication;
-
 using mesos::allocator::Allocator;
 
 using mesos::master::contender::MasterContender;
 
 using mesos::master::detector::MasterDetector;
 
-using mesos::http::authentication::BasicAuthenticatorFactory;
-
 static bool isValidFailoverTimeout(const FrameworkInfo& frameworkinfo);
 
 class SlaveObserver : public ProtobufProcess<SlaveObserver>
@@ -377,78 +370,6 @@ struct BoundedRateLimiter
 };
 
 
-void Master::registerHttpAuthenticator(
-    const string& realm,
-    const Option<Credentials>& credentials,
-    const vector<string>& httpAuthenticatorNames)
-{
-  // At least the default authenticator is always specified.
-  // Passing an empty string into the `http_authenticators`
-  // flag is considered an error.
-  if (httpAuthenticatorNames.empty()) {
-    EXIT(EXIT_FAILURE)
-      << "No HTTP authenticator specified for realm '" << realm << "'";
-  }
-
-  if (httpAuthenticatorNames.size() > 1) {
-    EXIT(EXIT_FAILURE) << "Multiple HTTP authenticators not supported";
-  }
-
-  if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
-      !modules::ModuleManager::contains<authentication::Authenticator>(
-          httpAuthenticatorNames[0])) {
-    EXIT(EXIT_FAILURE)
-      << "HTTP authenticator '" << httpAuthenticatorNames[0] << "' not"
-      << " found. Check the spelling (compare to '"
-      << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
-      << " authenticator was loaded successfully (see --modules)";
-  }
-
-  Option<authentication::Authenticator*> httpAuthenticator;
-  if (httpAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
-    if (credentials.isNone()) {
-      EXIT(EXIT_FAILURE)
-        << "No credentials provided for the default '"
-        << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP authenticator for realm '"
-        << realm << "'";
-    }
-
-    LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
-              << "' HTTP authenticator for realm '" << realm << "'";
-
-    Try<authentication::Authenticator*> authenticator =
-      BasicAuthenticatorFactory::create(realm, credentials.get());
-    if (authenticator.isError()) {
-      EXIT(EXIT_FAILURE)
-        << "Could not create HTTP authenticator module '"
-        << httpAuthenticatorNames[0] << "': " << authenticator.error();
-    }
-
-    httpAuthenticator = authenticator.get();
-  } else {
-    Try<authentication::Authenticator*> module =
-      modules::ModuleManager::create<authentication::Authenticator>(
-          httpAuthenticatorNames[0]);
-    if (module.isError()) {
-      EXIT(EXIT_FAILURE)
-        << "Could not create HTTP authenticator module '"
-        << httpAuthenticatorNames[0] << "': " << module.error();
-    }
-    LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
-              << "' HTTP authenticator for realm '" << realm << "'";
-    httpAuthenticator = module.get();
-  }
-
-  if (httpAuthenticator.isSome() && httpAuthenticator.get() != nullptr) {
-    // Ownership of the `httpAuthenticator` is passed to libprocess.
-    process::http::authentication::setAuthenticator(
-        realm,
-        Owned<authentication::Authenticator>(httpAuthenticator.get()));
-    httpAuthenticator = None();
-  }
-}
-
-
 void Master::initialize()
 {
   LOG(INFO) << "Master " << info_.id() << " (" << info_.hostname() << ")"
@@ -614,17 +535,25 @@ void Master::initialize()
 #endif // HAS_AUTHENTICATION
 
   if (flags.authenticate_http_readonly) {
-    registerHttpAuthenticator(
-      READONLY_HTTP_AUTHENTICATION_REALM,
-      credentials,
-      strings::split(flags.http_authenticators, ","));
+    Try<Nothing> result = initializeHttpAuthenticators(
+        READONLY_HTTP_AUTHENTICATION_REALM,
+        strings::split(flags.http_authenticators, ","),
+        credentials);
+
+    if (result.isError()) {
+      EXIT(EXIT_FAILURE) << result.error();
+    }
   }
 
   if (flags.authenticate_http_readwrite) {
-    registerHttpAuthenticator(
-      READWRITE_HTTP_AUTHENTICATION_REALM,
-      credentials,
-      strings::split(flags.http_authenticators, ","));
+    Try<Nothing> result = initializeHttpAuthenticators(
+        READWRITE_HTTP_AUTHENTICATION_REALM,
+        strings::split(flags.http_authenticators, ","),
+        credentials);
+
+    if (result.isError()) {
+      EXIT(EXIT_FAILURE) << result.error();
+    }
   }
 
   if (flags.authenticate_http_frameworks) {
@@ -636,10 +565,14 @@ void Master::initialize()
         << "in conjunction with `--authenticate_http_frameworks`";
     }
 
-    registerHttpAuthenticator(
-      DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
-      credentials,
-      strings::split(flags.http_framework_authenticators.get(), ","));
+    Try<Nothing> result = initializeHttpAuthenticators(
+        DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
+        strings::split(flags.http_framework_authenticators.get(), ","),
+        credentials);
+
+    if (result.isError()) {
+      EXIT(EXIT_FAILURE) << result.error();
+    }
   }
 
   if (authorizer.isSome()) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index bed6b8a..46621b8 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1870,13 +1870,6 @@ private:
   process::Future<Option<Error>> validate(
       const FrameworkInfo& frameworkInfo,
       const process::UPID& from);
-
-  // Helper function to create HTTP authenticator
-  // for a given realm and register in libprocess.
-  void registerHttpAuthenticator(
-      const std::string& realm,
-      const Option<Credentials>& credentials,
-      const std::vector<std::string>& authenticatorNames);
 };
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/slave/constants.hpp
----------------------------------------------------------------------
diff --git a/src/slave/constants.hpp b/src/slave/constants.hpp
index 46ef54e..360dd05 100644
--- a/src/slave/constants.hpp
+++ b/src/slave/constants.hpp
@@ -124,9 +124,6 @@ constexpr char DEFAULT_AUTHENTICATEE[] = "crammd5";
 // Name of the default, local authorizer.
 constexpr char DEFAULT_AUTHORIZER[] = "local";
 
-// Name of the default HTTP authenticator.
-constexpr char DEFAULT_HTTP_AUTHENTICATOR[] = "basic";
-
 // Name of the agent HTTP authentication realm for read-only endpoints.
 constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "mesos-agent-readonly";
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index d7714de..b0c02ae 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -25,6 +25,7 @@
 
 #include <mesos/type_utils.hpp>
 
+#include "common/http.hpp"
 #include "common/parse.hpp"
 
 #include "slave/constants.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 0a0bc70..708f945 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -30,10 +30,7 @@
 
 #include <mesos/type_utils.hpp>
 
-#include <mesos/authentication/http/basic_authenticator_factory.hpp>
-
 #include <mesos/module/authenticatee.hpp>
-#include <mesos/module/http_authenticator.hpp>
 
 #include <process/async.hpp>
 #include <process/check.hpp>
@@ -133,10 +130,6 @@ namespace slave {
 
 using namespace state;
 
-namespace authentication = process::http::authentication;
-
-using mesos::http::authentication::BasicAuthenticatorFactory;
-
 Slave::Slave(const std::string& id,
              const slave::Flags& _flags,
              MasterDetector* _detector,
@@ -361,17 +354,25 @@ void Slave::initialize()
   }
 
   if (flags.authenticate_http_readonly) {
-    registerHttpAuthenticator(
-      READONLY_HTTP_AUTHENTICATION_REALM,
-      httpCredentials,
-      strings::split(flags.http_authenticators, ","));
+    Try<Nothing> result = initializeHttpAuthenticators(
+        READONLY_HTTP_AUTHENTICATION_REALM,
+        strings::split(flags.http_authenticators, ","),
+        httpCredentials);
+
+    if (result.isError()) {
+      EXIT(EXIT_FAILURE) << result.error();
+    }
   }
 
   if (flags.authenticate_http_readwrite) {
-    registerHttpAuthenticator(
-      READWRITE_HTTP_AUTHENTICATION_REALM,
-      httpCredentials,
-      strings::split(flags.http_authenticators, ","));
+    Try<Nothing> result = initializeHttpAuthenticators(
+        READWRITE_HTTP_AUTHENTICATION_REALM,
+        strings::split(flags.http_authenticators, ","),
+        httpCredentials);
+
+    if (result.isError()) {
+      EXIT(EXIT_FAILURE) << result.error();
+    }
   }
 
   if ((flags.gc_disk_headroom < 0) || (flags.gc_disk_headroom > 1)) {
@@ -761,76 +762,6 @@ void Slave::initialize()
 }
 
 
-void Slave::registerHttpAuthenticator(
-    const string& realm,
-    const Option<Credentials>& credentials,
-    const vector<string>& httpAuthenticatorNames)
-{
-  // At least the default authenticator is always specified.
-  // Passing an empty string into the `http_authenticators`
-  // flag is considered an error.
-  if (httpAuthenticatorNames.empty()) {
-    EXIT(EXIT_FAILURE)
-      << "No HTTP authenticator specified for realm '" << realm << "'";
-  }
-  if (httpAuthenticatorNames.size() > 1) {
-    EXIT(EXIT_FAILURE) << "Multiple HTTP authenticators not supported";
-  }
-  if (httpAuthenticatorNames[0] != DEFAULT_HTTP_AUTHENTICATOR &&
-      !modules::ModuleManager::contains<authentication::Authenticator>(
-          httpAuthenticatorNames[0])) {
-    EXIT(EXIT_FAILURE)
-      << "HTTP authenticator '" << httpAuthenticatorNames[0] << "' not"
-      << " found. Check the spelling (compare to '"
-      << DEFAULT_HTTP_AUTHENTICATOR << "') or verify that the"
-      << " authenticator was loaded successfully (see --modules)";
-  }
-
-  Option<authentication::Authenticator*> httpAuthenticator;
-  if (httpAuthenticatorNames[0] == DEFAULT_HTTP_AUTHENTICATOR) {
-    if (credentials.isNone()) {
-      EXIT(EXIT_FAILURE)
-        << "No credentials provided for the default '"
-        << DEFAULT_HTTP_AUTHENTICATOR << "' HTTP authenticator for realm '"
-        << realm << "'";
-    }
-
-    LOG(INFO) << "Using default '" << DEFAULT_HTTP_AUTHENTICATOR
-              << "' HTTP authenticator for realm '" << realm << "'";
-
-    Try<authentication::Authenticator*> authenticator =
-      BasicAuthenticatorFactory::create(realm, credentials.get());
-    if (authenticator.isError()) {
-      EXIT(EXIT_FAILURE)
-        << "Could not create HTTP authenticator module '"
-        << httpAuthenticatorNames[0] << "': " << authenticator.error();
-    }
-
-    httpAuthenticator = authenticator.get();
-  } else {
-    Try<authentication::Authenticator*> module =
-      modules::ModuleManager::create<authentication::Authenticator>(
-          httpAuthenticatorNames[0]);
-    if (module.isError()) {
-      EXIT(EXIT_FAILURE)
-        << "Could not create HTTP authenticator module '"
-        << httpAuthenticatorNames[0] << "': " << module.error();
-    }
-    LOG(INFO) << "Using '" << httpAuthenticatorNames[0]
-              << "' HTTP authenticator for realm '" << realm << "'";
-    httpAuthenticator = module.get();
-  }
-
-  if (httpAuthenticator.isSome() && httpAuthenticator.get() != nullptr) {
-    // Ownership of the `httpAuthenticator` is passed to libprocess.
-    process::http::authentication::setAuthenticator(
-        realm,
-        Owned<authentication::Authenticator>(httpAuthenticator.get()));
-    httpAuthenticator = None();
-  }
-}
-
-
 void Slave::finalize()
 {
   LOG(INFO) << "Agent terminating";

http://git-wip-us.apache.org/repos/asf/mesos/blob/71f8bc38/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index f9f725b..a8952f0 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -411,13 +411,6 @@ public:
       const ContainerID& containerId);
 
 private:
-  // Helper function to create HTTP authenticator
-  // for a given realm and register in libprocess.
-  void registerHttpAuthenticator(
-      const std::string& realm,
-      const Option<Credentials>& credentials,
-      const std::vector<std::string>& authenticatorNames);
-
   void _authenticate();
   void authenticationTimeout(process::Future<bool> future);
 


[2/6] mesos git commit: Separated readonly and readwrite realms in libprocess.

Posted by me...@apache.org.
Separated readonly and readwrite realms in libprocess.

Review: https://reviews.apache.org/r/50277/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a76800c7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a76800c7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a76800c7

Branch: refs/heads/1.0.x
Commit: a76800c78e18b3c27ab4476d90035123d49c0951
Parents: 6cd20e9
Author: Zhitao Li <zh...@gmail.com>
Authored: Thu Jul 21 22:39:02 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Jul 22 02:02:24 2016 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/include/process/gtest.hpp    |  3 ++-
 3rdparty/libprocess/include/process/process.hpp  | 14 ++++++++++----
 3rdparty/libprocess/src/process.cpp              |  9 +++++----
 3rdparty/libprocess/src/tests/main.cpp           |  5 ++++-
 3rdparty/libprocess/src/tests/metrics_tests.cpp  |  6 +++---
 3rdparty/libprocess/src/tests/profiler_tests.cpp |  6 +++---
 6 files changed, 27 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/a76800c7/3rdparty/libprocess/include/process/gtest.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/gtest.hpp b/3rdparty/libprocess/include/process/gtest.hpp
index 21f66ed..80d26db 100644
--- a/3rdparty/libprocess/include/process/gtest.hpp
+++ b/3rdparty/libprocess/include/process/gtest.hpp
@@ -28,7 +28,8 @@
 
 namespace process {
 
-constexpr char DEFAULT_HTTP_AUTHENTICATION_REALM[] = "libprocess-realm";
+constexpr char READONLY_HTTP_AUTHENTICATION_REALM[] = "libprocess-readonly";
+constexpr char READWRITE_HTTP_AUTHENTICATION_REALM[] = "libprocess-readwrite";
 
 // A simple test event listener that makes sure to resume the clock
 // after each test even if the previous test had a partial result

http://git-wip-us.apache.org/repos/asf/mesos/blob/a76800c7/3rdparty/libprocess/include/process/process.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/process.hpp b/3rdparty/libprocess/include/process/process.hpp
index 2e85d31..54c7d2e 100644
--- a/3rdparty/libprocess/include/process/process.hpp
+++ b/3rdparty/libprocess/include/process/process.hpp
@@ -483,9 +483,14 @@ protected:
  * for it (e.g., a logging directory) via environment variables.
  *
  * @param delegate Process to receive root HTTP requests.
- * @param authenticationRealm The authentication realm that libprocess-level
- *     HTTP endpoints will be installed under, if any. If this realm is not
- *     specified, endpoints will be installed without authentication.
+ * @param readwriteAuthenticationRealm The authentication realm that read-write
+ *     libprocess-level HTTP endpoints will be installed under, if any.
+ *     If this realm is not specified, read-write endpoints will be installed
+ *     without authentication.
+ * @param readonlyAuthenticationRealm The authentication realm that read-only
+ *     libprocess-level HTTP endpoints will be installed under, if any.
+ *     If this realm is not specified, read-only endpoints will be installed
+ *     without authentication.
  * @return `true` if this was the first invocation of `process::initialize()`,
  *     or `false` if it was not the first invocation.
  *
@@ -493,7 +498,8 @@ protected:
  */
 bool initialize(
     const Option<std::string>& delegate = None(),
-    const Option<std::string>& authenticationRealm = None());
+    const Option<std::string>& readwriteAuthenticationRealm = None(),
+    const Option<std::string>& readonlyAuthenticationRealm = None());
 
 
 /**

http://git-wip-us.apache.org/repos/asf/mesos/blob/a76800c7/3rdparty/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/process.cpp b/3rdparty/libprocess/src/process.cpp
index 7e8bebe..d0a7a40 100644
--- a/3rdparty/libprocess/src/process.cpp
+++ b/3rdparty/libprocess/src/process.cpp
@@ -814,7 +814,8 @@ void install(vector<Owned<FirewallRule>>&& rules)
 
 bool initialize(
     const Option<string>& delegate,
-    const Option<string>& authenticationRealm)
+    const Option<string>& readwriteAuthenticationRealm,
+    const Option<string>& readonlyAuthenticationRealm)
 {
   // TODO(benh): Return an error if attempting to initialize again
   // with a different delegate than originally specified.
@@ -1040,13 +1041,13 @@ bool initialize(
   help = spawn(new Help(delegate), true);
 
   // Initialize the global metrics process.
-  metrics::initialize(authenticationRealm);
+  metrics::initialize(readonlyAuthenticationRealm);
 
   // Create the global logging process.
-  _logging = spawn(new Logging(authenticationRealm), true);
+  _logging = spawn(new Logging(readwriteAuthenticationRealm), true);
 
   // Create the global profiler process.
-  spawn(new Profiler(authenticationRealm), true);
+  spawn(new Profiler(readwriteAuthenticationRealm), true);
 
   // Create the global system statistics process.
   spawn(new System(), true);

http://git-wip-us.apache.org/repos/asf/mesos/blob/a76800c7/3rdparty/libprocess/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/main.cpp b/3rdparty/libprocess/src/tests/main.cpp
index a03dbc4..023b4fe 100644
--- a/3rdparty/libprocess/src/tests/main.cpp
+++ b/3rdparty/libprocess/src/tests/main.cpp
@@ -51,7 +51,10 @@ int main(int argc, char** argv)
   testing::InitGoogleMock(&argc, argv);
 
   // Initialize libprocess.
-  process::initialize(None(), process::DEFAULT_HTTP_AUTHENTICATION_REALM);
+  process::initialize(
+      None(),
+      process::READWRITE_HTTP_AUTHENTICATION_REALM,
+      process::READONLY_HTTP_AUTHENTICATION_REALM);
 
   // NOTE: Windows does not support signal semantics required for these
   // handlers to be useful.

http://git-wip-us.apache.org/repos/asf/mesos/blob/a76800c7/3rdparty/libprocess/src/tests/metrics_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/metrics_tests.cpp b/3rdparty/libprocess/src/tests/metrics_tests.cpp
index 5a82f4f..7c74b89 100644
--- a/3rdparty/libprocess/src/tests/metrics_tests.cpp
+++ b/3rdparty/libprocess/src/tests/metrics_tests.cpp
@@ -50,11 +50,11 @@ using metrics::Gauge;
 using metrics::Timer;
 
 using process::Clock;
-using process::DEFAULT_HTTP_AUTHENTICATION_REALM;
 using process::Failure;
 using process::Future;
 using process::PID;
 using process::Process;
+using process::READONLY_HTTP_AUTHENTICATION_REALM;
 using process::Statistics;
 using process::UPID;
 
@@ -509,10 +509,10 @@ TEST_F(MetricsTest, SnapshotAuthenticationEnabled)
 
   process::Owned<Authenticator> authenticator(
     new BasicAuthenticator(
-        DEFAULT_HTTP_AUTHENTICATION_REALM, {{"foo", "bar"}}));
+        READONLY_HTTP_AUTHENTICATION_REALM, {{"foo", "bar"}}));
 
   AWAIT_READY(
-      setAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, authenticator));
+      setAuthenticator(READONLY_HTTP_AUTHENTICATION_REALM, authenticator));
 
   UPID upid("metrics", process::address());
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/a76800c7/3rdparty/libprocess/src/tests/profiler_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/profiler_tests.cpp b/3rdparty/libprocess/src/tests/profiler_tests.cpp
index bf7a375..995bd02 100644
--- a/3rdparty/libprocess/src/tests/profiler_tests.cpp
+++ b/3rdparty/libprocess/src/tests/profiler_tests.cpp
@@ -35,8 +35,8 @@ using http::OK;
 using http::Response;
 using http::Unauthorized;
 
-using process::DEFAULT_HTTP_AUTHENTICATION_REALM;
 using process::Future;
+using process::READWRITE_HTTP_AUTHENTICATION_REALM;
 using process::UPID;
 
 using std::string;
@@ -121,10 +121,10 @@ TEST_F(ProfilerTest, StartAndStopAuthenticationEnabled)
 {
   process::Owned<Authenticator> authenticator(
     new BasicAuthenticator(
-        DEFAULT_HTTP_AUTHENTICATION_REALM, {{"foo", "bar"}}));
+        READWRITE_HTTP_AUTHENTICATION_REALM, {{"foo", "bar"}}));
 
   AWAIT_READY(
-      setAuthenticator(DEFAULT_HTTP_AUTHENTICATION_REALM, authenticator));
+      setAuthenticator(READWRITE_HTTP_AUTHENTICATION_REALM, authenticator));
 
   UPID upid("profiler", process::address());
 


[3/6] mesos git commit: Added readonly/readwrite auth flags to the docs.

Posted by me...@apache.org.
Added readonly/readwrite auth flags to the docs.

Review: https://reviews.apache.org/r/50322/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/be1b2491
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/be1b2491
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/be1b2491

Branch: refs/heads/1.0.x
Commit: be1b24912b6f94453bd4ccb8ea02a76dcc6a2c54
Parents: 71f8bc3
Author: Greg Mann <gr...@mesosphere.io>
Authored: Fri Jul 22 01:42:38 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Jul 22 02:02:25 2016 -0700

----------------------------------------------------------------------
 docs/authentication.md | 28 ++++++++++++++++++++++------
 docs/configuration.md  | 18 ++++++++++++++----
 2 files changed, 36 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/be1b2491/docs/authentication.md
----------------------------------------------------------------------
diff --git a/docs/authentication.md b/docs/authentication.md
index 06d5961..1574db9 100644
--- a/docs/authentication.md
+++ b/docs/authentication.md
@@ -48,9 +48,17 @@ Mesos master and agent processes. For more information, refer to the
   to register. If `false` (the default), unauthenticated frameworks are also
   allowed to register.
 
-* `--[no-]authenticate_http` - If `true`, authentication is required to make
-  HTTP requests to the HTTP endpoints that support authentication. If `false`
-  (the default), all endpoints can be used without authentication.
+* `--[no-]authenticate_http_readonly` - If `true`, authentication is required to
+  make HTTP requests to the read-only HTTP endpoints that support
+  authentication. If `false` (the default), these endpoints can be used without
+  authentication. Read-only endpoints are those which cannot be used to modify
+  the state of the cluster.
+
+* `--[no-]authenticate_http_readwrite` - If `true`, authentication is required
+  to make HTTP requests to the read-write HTTP endpoints that support
+  authentication. If `false` (the default), these endpoints can be used without
+  authentication. Read-write endpoints are those which can be used to modify the
+  state of the cluster.
 
 * `--[no-]authenticate_agents` - If `true`, only authenticated agents are
   allowed to register. If `false` (the default), unauthenticated agents are also
@@ -76,9 +84,17 @@ Mesos master and agent processes. For more information, refer to the
   only one credential is allowed. This credential is used to identify the agent
   to the master.
 
-* `--[no-]authenticate_http` - If `true`, authentication is required to make
-  HTTP requests to the HTTP endpoints that support authentication. If `false`
-  (the default), all endpoints can be used without authentication.
+* `--[no-]authenticate_http_readonly` - If `true`, authentication is required to
+  make HTTP requests to the read-only HTTP endpoints that support
+  authentication. If `false` (the default), these endpoints can be used without
+  authentication. Read-only endpoints are those which cannot be used to modify
+  the state of the agent.
+
+* `--[no-]authenticate_http_readwrite` - If `true`, authentication is required
+  to make HTTP requests to the read-write HTTP endpoints that support
+  authentication. If `false` (the default), these endpoints can be used without
+  authentication. Read-write endpoints are those which can be used to modify the
+  state of the agent.
 
 * `--http_authenticators` - Specifies which HTTP authenticator module to use.
   The default is `basic`, but additional modules can be added using the

http://git-wip-us.apache.org/repos/asf/mesos/blob/be1b2491/docs/configuration.md
----------------------------------------------------------------------
diff --git a/docs/configuration.md b/docs/configuration.md
index 526308a..666fb87 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -69,12 +69,22 @@ access Mesos master/agent.
 </tr>
 <tr>
   <td>
-    --[no-]authenticate_http
+    --[no-]authenticate_http_readonly
   </td>
   <td>
-If <code>true</code>, only authenticated requests for HTTP endpoints supporting
-authentication are allowed. If <code>false</code>, unauthenticated requests to
-HTTP endpoints are also allowed. (default: false)
+If <code>true</code>, only authenticated requests for read-only HTTP endpoints
+supporting authentication are allowed. If <code>false</code>, unauthenticated
+requests to such HTTP endpoints are also allowed.
+  </td>
+</tr>
+<tr>
+  <td>
+    --[no-]authenticate_http_readwrite
+  </td>
+  <td>
+If <code>true</code>, only authenticated requests for read-write HTTP endpoints
+supporting authentication are allowed. If <code>false</code>, unauthenticated
+requests to such HTTP endpoints are also allowed.
   </td>
 </tr>
 <tr>


[4/6] mesos git commit: Updated upgrades.md for new HTTP authentication flags.

Posted by me...@apache.org.
Updated upgrades.md for new HTTP authentication flags.

Review: https://reviews.apache.org/r/50333/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6009b314
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6009b314
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6009b314

Branch: refs/heads/1.0.x
Commit: 6009b3143a47eefff717103f1c094dc914f26fce
Parents: be1b249
Author: Greg Mann <gr...@mesosphere.io>
Authored: Fri Jul 22 01:51:01 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Jul 22 02:02:25 2016 -0700

----------------------------------------------------------------------
 docs/upgrades.md | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/6009b314/docs/upgrades.md
----------------------------------------------------------------------
diff --git a/docs/upgrades.md b/docs/upgrades.md
index 80aa8f4..82b9e26 100644
--- a/docs/upgrades.md
+++ b/docs/upgrades.md
@@ -64,6 +64,7 @@ We categorize the changes as follows:
       <li>C <a href="#1-0-x-slave">Slave to Agent rename</a></li>
       <li>R <a href="#1-0-x-workdir">work_dir default value</a></li>
       <li>D <a href="#1-0-x-deprecated-ssl-env-variables">SSL environment variables</a></li>
+      <li>ACD <a href="#1-0-x-http-authentication-flags">HTTP authentication</a></li>
     </ul>
   </td>
   <td style="word-wrap: break-word; overflow-wrap: break-word;"><!--Framework API-->
@@ -277,6 +278,10 @@ We categorize the changes as follows:
 
 * When a task is run as a particular user, the fetcher now fetches files as that user also. Note, this means that filesystem permissions for that user will be enforced when fetching local files.
 
+<a name="1-0-x-http-authentication-flags"></a>
+
+* The `--authenticate_http` flag has been deprecated in favor of `--authenticate_http_readwrite`. Setting `--authenticate_http_readwrite` will now enable authentication for all endpoints which previously had authentication support. These happen to be the endpoints which allow modifiication of the cluster state, or "read-write" endpoints. Note that `/logging/toggle`, `/profiler/start`, `/profiler/stop`, `/maintenance/schedule`, `/machine/up`, and `/machine/down` previously did not have authentication support, but in 1.0 if either `--authenticate_http` or `--authenticate_http_readwrite` is set, those endpoints will now require authentication. A new flag has also been introduced, `--authenticate_http_readonly`, which enables authentication for endpoints which support authentication and do not allow modification of the state of the cluster, like `/state` or `/flags`.
+
 <a name="1-0-x-endpoint-authorization"></a>
 
 * Mesos 1.0 introduces authorization support for several HTTP endpoints. Note that some of these endpoints are used by the web UI, and thus using the web UI in a cluster with authorization enabled will require that ACLs be set appropriately. Please refer to the [authorization documentation](authorization.md) for details.


[5/6] mesos git commit: Updated CHANGELOG for new HTTP authentication flags.

Posted by me...@apache.org.
Updated CHANGELOG for new HTTP authentication flags.

Review: https://reviews.apache.org/r/50332/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d15e684c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d15e684c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d15e684c

Branch: refs/heads/1.0.x
Commit: d15e684cb8072308b990fc5df00e41eb3bfbbdb8
Parents: 6009b31
Author: Greg Mann <gr...@mesosphere.io>
Authored: Fri Jul 22 01:53:23 2016 -0700
Committer: Adam B <ad...@mesosphere.io>
Committed: Fri Jul 22 02:02:25 2016 -0700

----------------------------------------------------------------------
 CHANGELOG | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/d15e684c/CHANGELOG
----------------------------------------------------------------------
diff --git a/CHANGELOG b/CHANGELOG
index f947aa8..ccccc71 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -188,6 +188,13 @@ Additional API Changes:
   * [MESOS-5642] - Namespace and header file of `Allocator` has been moved to
     be consistent with other packages.
 
+  * [MESOS-5851] - The flag `--authenticate_http` has been deprecated in favor
+    of `--authenticate_http_readwrite`. This new flag enables authentication for
+    all HTTP endpoints which support authentication and allow modification of
+    the state of the cluster. A new flag has also been added,
+    `--authenticate_http_readonly`, which enables authentication for those
+    authenticatable endpoints that cannot be used to modify the cluster state.
+
 3rd Party Upgrades:
   * [MESOS-4805] - Upgraded vendored ry-http-parser-1c3624a to nodejs/http-parser 2.6.1.
   * [MESOS-4678] - Upgraded vendored protobuf 2.5.0 to 2.6.1.