You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2016/04/15 23:00:02 UTC
[6/9] mesos git commit: Added AuthN for HTTP based frameworks.
Added AuthN for HTTP based frameworks.
This change adds AuthN support for HTTP based frameworks.
We allow AuthZ without AuthN for `/scheduler` endpoint. Also,
we ensure that `FrameworkInfo.principal` (if present) equals
the authenticated principal. We also allow a framework to
omit specifying the `FrameworkInfo.principal` in case
it is not interested in authorization or if it is disabled.
We do log a warning for this cases similar to what driver
based frameworks already do.
Review: https://reviews.apache.org/r/46115/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a080650a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a080650a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a080650a
Branch: refs/heads/master
Commit: a080650aa0833b380ec86239360145688da9a4c1
Parents: 792b08d
Author: Anand Mazumdar <ma...@gmail.com>
Authored: Fri Apr 15 15:59:26 2016 -0500
Committer: Vinod Kone <vi...@gmail.com>
Committed: Fri Apr 15 15:59:26 2016 -0500
----------------------------------------------------------------------
src/master/http.cpp | 36 +++++++++++++++++++++++++++++-------
src/master/master.cpp | 6 ++++--
src/master/master.hpp | 3 ++-
src/master/validation.cpp | 17 +++++++++++++++--
src/master/validation.hpp | 4 +++-
5 files changed, 53 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a080650a/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index b8a83b5..d83ccd3 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -334,7 +334,9 @@ string Master::Http::SCHEDULER_HELP()
}
-Future<Response> Master::Http::scheduler(const Request& request) const
+Future<Response> Master::Http::scheduler(
+ const Request& request,
+ const Option<string>& principal) const
{
// TODO(vinod): Add metrics for rejected requests.
@@ -356,11 +358,6 @@ Future<Response> Master::Http::scheduler(const Request& request) const
return ServiceUnavailable("Master has not finished recovery");
}
- if (master->flags.authenticate_frameworks) {
- return Forbidden(
- "HTTP schedulers are not supported when authentication is required");
- }
-
if (request.method != "POST") {
return MethodNotAllowed(
{"POST"}, "Expecting 'POST', received '" + request.method + "'");
@@ -403,7 +400,7 @@ Future<Response> Master::Http::scheduler(const Request& request) const
scheduler::Call call = devolve(v1Call);
- Option<Error> error = validation::scheduler::call::validate(call);
+ Option<Error> error = validation::scheduler::call::validate(call, principal);
if (error.isSome()) {
return BadRequest("Failed to validate Scheduler::Call: " +
@@ -431,6 +428,24 @@ Future<Response> Master::Http::scheduler(const Request& request) const
"Subscribe calls should not include the 'Mesos-Stream-Id' header");
}
+ const FrameworkInfo& frameworkInfo = call.subscribe().framework_info();
+
+ if (principal.isSome() && !frameworkInfo.has_principal()) {
+ // We allow an authenticated framework to not specify a principal
+ // in `FrameworkInfo` but we'd prefer to log a WARNING here. We also
+ // set `FrameworkInfo.principal` to the value of authenticated principal
+ // and use it for authorization later when it happens.
+ if (!frameworkInfo.has_principal()) {
+ LOG(WARNING)
+ << "Setting 'principal' in FrameworkInfo to '" << principal.get()
+ << "' because the framework authenticated with that principal but "
+ << "did not set it in FrameworkInfo";
+
+ call.mutable_subscribe()->mutable_framework_info()->set_principal(
+ principal.get());
+ }
+ }
+
Pipe pipe;
OK ok;
ok.headers["Content-Type"] = stringify(responseContentType);
@@ -456,6 +471,13 @@ Future<Response> Master::Http::scheduler(const Request& request) const
return BadRequest("Framework cannot be found");
}
+ if (principal.isSome() && principal != framework->info.principal()) {
+ return BadRequest(
+ "Authenticated principal '" + principal.get() + "' does not "
+ "match principal '" + framework->info.principal() + "' set in "
+ "`FrameworkInfo`");
+ }
+
if (!framework->connected) {
return Forbidden("Framework is not subscribed");
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/a080650a/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 20101ee..210934b 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -945,10 +945,12 @@ void Master::initialize()
// Setup HTTP routes.
route("/api/v1/scheduler",
+ DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
Http::SCHEDULER_HELP(),
- [this](const process::http::Request& request) {
+ [this](const process::http::Request& request,
+ const Option<string>& principal) {
Http::log(request);
- return http.scheduler(request);
+ return http.scheduler(request, principal);
});
route("/create-volumes",
DEFAULT_HTTP_AUTHENTICATION_REALM,
http://git-wip-us.apache.org/repos/asf/mesos/blob/a080650a/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index e7cb751..2dd0971 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1071,7 +1071,8 @@ private:
// /api/v1/scheduler
process::Future<process::http::Response> scheduler(
- const process::http::Request& request) const;
+ const process::http::Request& request,
+ const Option<std::string>& principal) const;
// /master/create-volumes
process::Future<process::http::Response> createVolumes(
http://git-wip-us.apache.org/repos/asf/mesos/blob/a080650a/src/master/validation.cpp
----------------------------------------------------------------------
diff --git a/src/master/validation.cpp b/src/master/validation.cpp
index 0f7b9b9..2b91446 100644
--- a/src/master/validation.cpp
+++ b/src/master/validation.cpp
@@ -53,7 +53,9 @@ static bool invalidCharacter(char c)
namespace scheduler {
namespace call {
-Option<Error> validate(const mesos::scheduler::Call& call)
+Option<Error> validate(
+ const mesos::scheduler::Call& call,
+ const Option<string>& principal)
{
if (!call.IsInitialized()) {
return Error("Not initialized: " + call.InitializationErrorString());
@@ -68,10 +70,21 @@ Option<Error> validate(const mesos::scheduler::Call& call)
return Error("Expecting 'subscribe' to be present");
}
- if (call.subscribe().framework_info().id() != call.framework_id()) {
+ const FrameworkInfo& frameworkInfo = call.subscribe().framework_info();
+
+ if (frameworkInfo.id() != call.framework_id()) {
return Error("'framework_id' differs from 'subscribe.framework_info.id'");
}
+ if (principal.isSome() &&
+ frameworkInfo.has_principal() &&
+ principal != frameworkInfo.principal()) {
+ return Error(
+ "Authenticated principal '" + principal.get() + "' does not "
+ "match principal '" + frameworkInfo.principal() + "' set in "
+ "`FrameworkInfo`");
+ }
+
return None();
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/a080650a/src/master/validation.hpp
----------------------------------------------------------------------
diff --git a/src/master/validation.hpp b/src/master/validation.hpp
index d1f2323..7fa1b89 100644
--- a/src/master/validation.hpp
+++ b/src/master/validation.hpp
@@ -42,7 +42,9 @@ namespace call {
// Validates that a scheduler call is well-formed.
// TODO(bmahler): Add unit tests.
-Option<Error> validate(const mesos::scheduler::Call& call);
+Option<Error> validate(
+ const mesos::scheduler::Call& call,
+ const Option<std::string>& principal = None());
} // namespace call {
} // namespace scheduler {