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 2017/03/06 20:40:46 UTC
[10/14] mesos git commit: Updated master handlers to use the
'Principal' type.
Updated master handlers to use the 'Principal' type.
This patch updates the HTTP endpoint handlers in the
master process to accept the `Principal` type instead
of an `Option<string>& principal`.
Review: https://reviews.apache.org/r/56813/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/da47646e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/da47646e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/da47646e
Branch: refs/heads/master
Commit: da47646e22d5294ce48de57424bfa9b6562a6896
Parents: 8da4d6f
Author: Greg Mann <gr...@mesosphere.io>
Authored: Mon Mar 6 12:39:45 2017 -0800
Committer: Vinod Kone <vi...@gmail.com>
Committed: Mon Mar 6 12:39:45 2017 -0800
----------------------------------------------------------------------
src/master/http.cpp | 363 ++++++++++++++++++++++++------------
src/master/master.cpp | 155 +++++++--------
src/master/master.hpp | 192 +++++++++++--------
src/master/quota_handler.cpp | 56 +++---
src/master/registrar.cpp | 6 +-
src/master/weights_handler.cpp | 34 ++--
6 files changed, 497 insertions(+), 309 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/da47646e/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index b0b73e3..713ee0f 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -112,6 +112,8 @@ using process::http::TemporaryRedirect;
using process::http::UnsupportedMediaType;
using process::http::URL;
+using process::http::authentication::Principal;
+
using std::copy_if;
using std::list;
using std::map;
@@ -124,6 +126,8 @@ using std::vector;
namespace mesos {
+using mesos::authorization::createSubject;
+
static void json(
JSON::StringWriter* writer,
const FrameworkInfo::Capability& capability)
@@ -469,8 +473,17 @@ string Master::Http::API_HELP()
Future<Response> Master::Http::api(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// TODO(vinod): Add metrics for rejected requests.
// TODO(vinod): Add support for rate limiting.
@@ -652,7 +665,7 @@ Future<Response> Master::Http::api(
Future<Response> Master::Http::subscribe(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::SUBSCRIBE, call.type());
@@ -662,11 +675,7 @@ Future<Response> Master::Http::subscribe(
Future<Owned<ObjectApprover>> tasksApprover;
Future<Owned<ObjectApprover>> executorsApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -741,8 +750,17 @@ string Master::Http::SCHEDULER_HELP()
Future<Response> Master::Http::scheduler(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// TODO(vinod): Add metrics for rejected requests.
// TODO(vinod): Add support for rate limiting.
@@ -833,20 +851,24 @@ Future<Response> Master::Http::scheduler(
const FrameworkInfo& frameworkInfo = call.subscribe().framework_info();
+ // We allow an authenticated framework to not specify a principal in
+ // `FrameworkInfo`, but in that case we log a WARNING here. We also set
+ // `FrameworkInfo.principal` to the value of the authenticated principal
+ // and use it for authorization later.
+ //
+ // NOTE: Common validation code, called previously, verifies that the
+ // authenticated principal is the same as `FrameworkInfo.principal`,
+ // if present.
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());
- }
+ CHECK_SOME(principal->value);
+
+ LOG(WARNING)
+ << "Setting 'principal' in FrameworkInfo to '" << principal->value.get()
+ << "' because the framework authenticated with that principal but "
+ << "did not set it in FrameworkInfo";
+
+ call.mutable_subscribe()->mutable_framework_info()->set_principal(
+ principal->value.get());
}
Pipe pipe;
@@ -876,7 +898,7 @@ Future<Response> Master::Http::scheduler(
if (principal.isSome() && principal != framework->info.principal()) {
return BadRequest(
- "Authenticated principal '" + principal.get() + "' does not "
+ "Authenticated principal '" + stringify(principal.get()) + "' does not "
"match principal '" + framework->info.principal() + "' set in "
"`FrameworkInfo`");
}
@@ -1012,8 +1034,17 @@ string Master::Http::CREATE_VOLUMES_HELP()
Future<Response> Master::Http::createVolumes(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -1083,7 +1114,7 @@ Future<Response> Master::Http::createVolumes(
Future<Response> Master::Http::_createVolumes(
const SlaveID& slaveId,
const RepeatedPtrField<Resource>& volumes,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
Slave* slave = master->slaves.registered.get(slaveId);
if (slave == nullptr) {
@@ -1118,9 +1149,18 @@ Future<Response> Master::Http::_createVolumes(
Future<Response> Master::Http::createVolumes(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType /*contentType*/) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
CHECK_EQ(mesos::master::Call::CREATE_VOLUMES, call.type());
CHECK(call.has_create_volumes());
@@ -1161,8 +1201,17 @@ string Master::Http::DESTROY_VOLUMES_HELP()
Future<Response> Master::Http::destroyVolumes(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -1232,7 +1281,7 @@ Future<Response> Master::Http::destroyVolumes(
Future<Response> Master::Http::_destroyVolumes(
const SlaveID& slaveId,
const RepeatedPtrField<Resource>& volumes,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
Slave* slave = master->slaves.registered.get(slaveId);
if (slave == nullptr) {
@@ -1267,9 +1316,18 @@ Future<Response> Master::Http::_destroyVolumes(
Future<Response> Master::Http::destroyVolumes(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType /*contentType*/) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
CHECK_EQ(mesos::master::Call::DESTROY_VOLUMES, call.type());
CHECK(call.has_destroy_volumes());
@@ -1299,8 +1357,17 @@ string Master::Http::FRAMEWORKS_HELP()
Future<Response> Master::Http::frameworks(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -1313,11 +1380,7 @@ Future<Response> Master::Http::frameworks(
Future<Owned<ObjectApprover>> executorsApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -1469,7 +1532,7 @@ mesos::master::Response::GetFrameworks::Framework model(
Future<Response> Master::Http::getFrameworks(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_FRAMEWORKS, call.type());
@@ -1478,15 +1541,10 @@ Future<Response> Master::Http::getFrameworks(
Future<Owned<ObjectApprover>> frameworksApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
-
} else {
frameworksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
}
@@ -1536,7 +1594,7 @@ mesos::master::Response::GetFrameworks Master::Http::_getFrameworks(
Future<Response> Master::Http::getExecutors(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_EXECUTORS, call.type());
@@ -1545,11 +1603,7 @@ Future<Response> Master::Http::getExecutors(
Future<Owned<ObjectApprover>> frameworksApprover;
Future<Owned<ObjectApprover>> executorsApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -1667,7 +1721,7 @@ mesos::master::Response::GetExecutors Master::Http::_getExecutors(
Future<Response> Master::Http::getState(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_STATE, call.type());
@@ -1677,11 +1731,7 @@ Future<Response> Master::Http::getState(
Future<Owned<ObjectApprover>> tasksApprover;
Future<Owned<ObjectApprover>> executorsApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -1784,8 +1834,17 @@ string Master::Http::FLAGS_HELP()
Future<Response> Master::Http::flags(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// TODO(nfnt): Remove check for enabled
// authorization as part of MESOS-5346.
if (request.method != "GET" && master->authorizer.isSome()) {
@@ -1812,7 +1871,7 @@ Future<Response> Master::Http::flags(
Future<Try<JSON::Object, Master::Http::FlagsError>> Master::Http::_flags(
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
if (master->authorizer.isNone()) {
return __flags();
@@ -1821,8 +1880,9 @@ Future<Try<JSON::Object, Master::Http::FlagsError>> Master::Http::_flags(
authorization::Request authRequest;
authRequest.set_action(authorization::VIEW_FLAGS);
- if (principal.isSome()) {
- authRequest.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ authRequest.mutable_subject()->CopyFrom(subject.get());
}
return master->authorizer.get()->authorized(authRequest)
@@ -1859,7 +1919,7 @@ JSON::Object Master::Http::__flags() const
Future<Response> Master::Http::getFlags(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_FLAGS, call.type());
@@ -1904,7 +1964,7 @@ Future<Response> Master::Http::health(const Request& request) const
Future<Response> Master::Http::getHealth(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_HEALTH, call.type());
@@ -1920,7 +1980,7 @@ Future<Response> Master::Http::getHealth(
Future<Response> Master::Http::getVersion(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_VERSION, call.type());
@@ -1933,7 +1993,7 @@ Future<Response> Master::Http::getVersion(
Future<Response> Master::Http::getMetrics(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_METRICS, call.type());
@@ -1965,7 +2025,7 @@ Future<Response> Master::Http::getMetrics(
Future<Response> Master::Http::getLoggingLevel(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_LOGGING_LEVEL, call.type());
@@ -1981,7 +2041,7 @@ Future<Response> Master::Http::getLoggingLevel(
Future<Response> Master::Http::setLoggingLevel(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType /*contentType*/) const
{
CHECK_EQ(mesos::master::Call::SET_LOGGING_LEVEL, call.type());
@@ -2000,7 +2060,7 @@ Future<Response> Master::Http::setLoggingLevel(
Future<Response> Master::Http::getMaster(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_MASTER, call.type());
@@ -2125,8 +2185,17 @@ string Master::Http::RESERVE_HELP()
Future<Response> Master::Http::reserve(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -2197,7 +2266,7 @@ Future<Response> Master::Http::reserve(
Future<Response> Master::Http::_reserve(
const SlaveID& slaveId,
const Resources& resources,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
Slave* slave = master->slaves.registered.get(slaveId);
if (slave == nullptr) {
@@ -2233,7 +2302,7 @@ Future<Response> Master::Http::_reserve(
Future<Response> Master::Http::reserveResources(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::RESERVE_RESOURCES, call.type());
@@ -2265,7 +2334,7 @@ string Master::Http::SLAVES_HELP()
Future<Response> Master::Http::slaves(
const Request& request,
- const Option<string>& /*principal*/) const
+ const Option<Principal>&) const
{
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
@@ -2341,7 +2410,7 @@ Future<Response> Master::Http::slaves(
Future<process::http::Response> Master::Http::getAgents(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_AGENTS, call.type());
@@ -2404,8 +2473,17 @@ string Master::Http::QUOTA_HELP()
Future<Response> Master::Http::quota(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -2455,8 +2533,17 @@ string Master::Http::WEIGHTS_HELP()
Future<Response> Master::Http::weights(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -2571,8 +2658,17 @@ string Master::Http::STATE_HELP()
Future<Response> Master::Http::state(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -2585,11 +2681,7 @@ Future<Response> Master::Http::state(
Future<Owned<ObjectApprover>> flagsApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -2815,7 +2907,7 @@ Future<Response> Master::Http::state(
Future<Response> Master::Http::readFile(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::READ_FILE, call.type());
@@ -3065,8 +3157,17 @@ string Master::Http::STATESUMMARY_HELP()
Future<Response> Master::Http::stateSummary(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -3075,11 +3176,7 @@ Future<Response> Master::Http::stateSummary(
Future<Owned<ObjectApprover>> frameworksApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -3279,21 +3376,16 @@ string Master::Http::ROLES_HELP()
Future<vector<string>> Master::Http::_roles(
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
// Retrieve `ObjectApprover`s for authorizing roles.
Future<Owned<ObjectApprover>> rolesApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
rolesApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_ROLE);
-
} else {
rolesApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
}
@@ -3346,8 +3438,17 @@ Future<vector<string>> Master::Http::_roles(
Future<Response> Master::Http::roles(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -3386,7 +3487,7 @@ Future<Response> Master::Http::roles(
Future<Response> Master::Http::listFiles(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::LIST_FILES, call.type());
@@ -3438,7 +3539,7 @@ Future<Response> Master::Http::listFiles(
// convert back into a `Resource` object.
Future<Response> Master::Http::getRoles(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_ROLES, call.type());
@@ -3508,8 +3609,17 @@ string Master::Http::TEARDOWN_HELP()
Future<Response> Master::Http::teardown(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -3553,8 +3663,9 @@ Future<Response> Master::Http::teardown(
authorization::Request teardown;
teardown.set_action(authorization::TEARDOWN_FRAMEWORK);
- if (principal.isSome()) {
- teardown.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ teardown.mutable_subject()->CopyFrom(subject.get());
}
if (framework->info.has_principal()) {
@@ -3666,8 +3777,17 @@ string Master::Http::TASKS_HELP()
Future<Response> Master::Http::tasks(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -3687,11 +3807,7 @@ Future<Response> Master::Http::tasks(
Future<Owned<ObjectApprover>> frameworksApprover;
Future<Owned<ObjectApprover>> tasksApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -3793,7 +3909,7 @@ Future<Response> Master::Http::tasks(
Future<Response> Master::Http::getTasks(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_TASKS, call.type());
@@ -3802,11 +3918,7 @@ Future<Response> Master::Http::getTasks(
Future<Owned<ObjectApprover>> frameworksApprover;
Future<Owned<ObjectApprover>> tasksApprover;
if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject;
- if (principal.isSome()) {
- subject = authorization::Subject();
- subject->set_value(principal.get());
- }
+ Option<authorization::Subject> subject = createSubject(principal);
frameworksApprover = master->authorizer.get()->getObjectApprover(
subject, authorization::VIEW_FRAMEWORK);
@@ -3969,7 +4081,7 @@ string Master::Http::MAINTENANCE_SCHEDULE_HELP()
// /master/maintenance/schedule endpoint handler.
Future<Response> Master::Http::maintenanceSchedule(
const Request& request,
- const Option<string>& /*principal*/) const
+ const Option<Principal>&) const
{
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
@@ -4108,7 +4220,7 @@ Future<Response> Master::Http::_updateMaintenanceSchedule(
Future<Response> Master::Http::getMaintenanceSchedule(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_MAINTENANCE_SCHEDULE, call.type());
@@ -4125,7 +4237,7 @@ Future<Response> Master::Http::getMaintenanceSchedule(
Future<Response> Master::Http::updateMaintenanceSchedule(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType /*contentType*/) const
{
CHECK_EQ(mesos::master::Call::UPDATE_MAINTENANCE_SCHEDULE, call.type());
@@ -4160,7 +4272,7 @@ string Master::Http::MACHINE_DOWN_HELP()
// /master/machine/down endpoint handler.
Future<Response> Master::Http::machineDown(
const Request& request,
- const Option<string>& /*principal*/) const
+ const Option<Principal>&) const
{
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
@@ -4262,7 +4374,7 @@ Future<Response> Master::Http::_startMaintenance(
Future<Response> Master::Http::startMaintenance(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType /*contentType*/) const
{
CHECK_EQ(mesos::master::Call::START_MAINTENANCE, call.type());
@@ -4296,7 +4408,7 @@ string Master::Http::MACHINE_UP_HELP()
// /master/machine/up endpoint handler.
Future<Response> Master::Http::machineUp(
const Request& request,
- const Option<string>& /*principal*/) const
+ const Option<Principal>&) const
{
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
@@ -4397,7 +4509,7 @@ Future<Response> Master::Http::_stopMaintenance(
Future<Response> Master::Http::stopMaintenance(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType /*contentType*/) const
{
CHECK_EQ(mesos::master::Call::STOP_MAINTENANCE, call.type());
@@ -4434,7 +4546,7 @@ string Master::Http::MAINTENANCE_STATUS_HELP()
// /master/maintenance/status endpoint handler.
Future<Response> Master::Http::maintenanceStatus(
const Request& request,
- const Option<string>& /*principal*/) const
+ const Option<Principal>&) const
{
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
@@ -4511,7 +4623,7 @@ Future<mesos::maintenance::ClusterStatus>
Future<Response> Master::Http::getMaintenanceStatus(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_MAINTENANCE_STATUS, call.type());
@@ -4560,8 +4672,17 @@ string Master::Http::UNRESERVE_HELP()
Future<Response> Master::Http::unreserve(
const Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
+ // TODO(greggomann): Remove this check once the `Principal` type is used in
+ // `ReservationInfo`, `DiskInfo`, and within the master's `principals` map.
+ // See MESOS-7202.
+ if (principal.isSome() && principal->value.isNone()) {
+ return Forbidden(
+ "The request's authenticated principal contains claims, but no value "
+ "string. The master currently requires that principals have a value");
+ }
+
// When current master is not the leader, redirect to the leading master.
if (!master->elected()) {
return redirect(request);
@@ -4632,7 +4753,7 @@ Future<Response> Master::Http::unreserve(
Future<Response> Master::Http::_unreserve(
const SlaveID& slaveId,
const Resources& resources,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
Slave* slave = master->slaves.registered.get(slaveId);
if (slave == nullptr) {
@@ -4724,7 +4845,7 @@ Future<Response> Master::Http::_operation(
Future<Response> Master::Http::unreserveResources(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::UNRESERVE_RESOURCES, call.type());
http://git-wip-us.apache.org/repos/asf/mesos/blob/da47646e/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index a15c6d8..3fa5438 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -118,6 +118,8 @@ using process::UPID;
using process::http::Pipe;
+using process::http::authentication::Principal;
+
using process::metrics::Counter;
namespace mesos {
@@ -126,6 +128,8 @@ namespace master {
using mesos::allocator::Allocator;
+using mesos::authorization::createSubject;
+
using mesos::master::contender::MasterContender;
using mesos::master::detector::MasterDetector;
@@ -856,7 +860,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::API_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.api(request, principal);
});
@@ -864,7 +868,7 @@ void Master::initialize()
DEFAULT_HTTP_FRAMEWORK_AUTHENTICATION_REALM,
Http::SCHEDULER_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.scheduler(request, principal);
});
@@ -872,7 +876,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::CREATE_VOLUMES_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.createVolumes(request, principal);
});
@@ -880,7 +884,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::DESTROY_VOLUMES_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.destroyVolumes(request, principal);
});
@@ -888,7 +892,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::FRAMEWORKS_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.frameworks(request, principal);
});
@@ -896,7 +900,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::FLAGS_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.flags(request, principal);
});
@@ -914,7 +918,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::RESERVE_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.reserve(request, principal);
});
@@ -924,7 +928,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::ROLES_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.roles(request, principal);
});
@@ -932,7 +936,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::ROLES_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.roles(request, principal);
});
@@ -940,7 +944,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::TEARDOWN_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.teardown(request, principal);
});
@@ -948,7 +952,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::SLAVES_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.slaves(request, principal);
});
@@ -958,7 +962,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::STATE_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.state(request, principal);
});
@@ -966,7 +970,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::STATE_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.state(request, principal);
});
@@ -974,7 +978,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::STATESUMMARY_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.stateSummary(request, principal);
});
@@ -984,7 +988,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::TASKS_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.tasks(request, principal);
});
@@ -992,7 +996,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::TASKS_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.tasks(request, principal);
});
@@ -1000,7 +1004,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::MAINTENANCE_SCHEDULE_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.maintenanceSchedule(request, principal);
});
@@ -1008,7 +1012,7 @@ void Master::initialize()
READONLY_HTTP_AUTHENTICATION_REALM,
Http::MAINTENANCE_STATUS_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.maintenanceStatus(request, principal);
});
@@ -1016,7 +1020,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::MACHINE_DOWN_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.machineDown(request, principal);
});
@@ -1024,7 +1028,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::MACHINE_UP_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.machineUp(request, principal);
});
@@ -1032,7 +1036,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::UNRESERVE_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.unreserve(request, principal);
});
@@ -1040,7 +1044,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::QUOTA_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.quota(request, principal);
});
@@ -1048,7 +1052,7 @@ void Master::initialize()
READWRITE_HTTP_AUTHENTICATION_REALM,
Http::WEIGHTS_HELP(),
[this](const process::http::Request& request,
- const Option<string>& principal) {
+ const Option<Principal>& principal) {
Http::log(request);
return http.weights(request, principal);
});
@@ -1063,7 +1067,7 @@ void Master::initialize()
const PID<Master> masterPid = self();
- auto authorize = [masterPid](const Option<string>& principal) {
+ auto authorize = [masterPid](const Option<Principal>& principal) {
return dispatch(masterPid, &Master::authorizeLogAccess, principal);
};
@@ -1405,7 +1409,7 @@ void Master::_exited(Framework* framework)
}
-Future<bool> Master::authorizeLogAccess(const Option<string>& principal)
+Future<bool> Master::authorizeLogAccess(const Option<Principal>& principal)
{
if (authorizer.isNone()) {
return true;
@@ -1414,8 +1418,9 @@ Future<bool> Master::authorizeLogAccess(const Option<string>& principal)
authorization::Request request;
request.set_action(authorization::ACCESS_MESOS_LOG);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
return authorizer.get()->authorized(request);
@@ -1558,6 +1563,8 @@ void Master::visit(const ExitedEvent& event)
}
+// TODO(greggomann): Change this to accept an `Option<Principal>`
+// when MESOS-7202 is resolved.
void Master::throttled(
const MessageEvent& event,
const Option<string>& principal)
@@ -1600,6 +1607,8 @@ void Master::_visit(const MessageEvent& event)
}
+// TODO(greggomann): Change this to accept an `Option<Principal>`
+// when MESOS-7202 is resolved.
void Master::exceededCapacity(
const MessageEvent& event,
const Option<string>& principal,
@@ -3411,7 +3420,7 @@ Future<bool> Master::authorizeTask(
Future<bool> Master::authorizeReserveResources(
const Offer::Operation::Reserve& reserve,
- const Option<string>& principal)
+ const Option<Principal>& principal)
{
if (authorizer.isNone()) {
return true; // Authorization is disabled.
@@ -3420,11 +3429,12 @@ Future<bool> Master::authorizeReserveResources(
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
- // The operation will be authorized if the principal is allowed to make
+ // The operation will be authorized if the entity is allowed to make
// reservations for all roles included in `reserve.resources`.
// Add an element to `request.roles` for each unique role in the resources.
hashset<string> roles;
@@ -3440,7 +3450,7 @@ Future<bool> Master::authorizeReserveResources(
}
LOG(INFO) << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
<< "' to reserve resources '" << reserve.resources() << "'";
// NOTE: Empty authorizations are not valid and are checked by a validator.
@@ -3468,7 +3478,7 @@ Future<bool> Master::authorizeReserveResources(
Future<bool> Master::authorizeUnreserveResources(
const Offer::Operation::Unreserve& unreserve,
- const Option<string>& principal)
+ const Option<Principal>& principal)
{
if (authorizer.isNone()) {
return true; // Authorization is disabled.
@@ -3477,8 +3487,9 @@ Future<bool> Master::authorizeUnreserveResources(
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
list<Future<bool>> authorizations;
@@ -3498,10 +3509,9 @@ Future<bool> Master::authorizeUnreserveResources(
}
}
- LOG(INFO)
- << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
- << "' to unreserve resources '" << unreserve.resources() << "'";
+ LOG(INFO) << "Authorizing principal '"
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
+ << "' to unreserve resources '" << unreserve.resources() << "'";
if (authorizations.empty()) {
return authorizer.get()->authorized(request);
@@ -3523,7 +3533,7 @@ Future<bool> Master::authorizeUnreserveResources(
Future<bool> Master::authorizeCreateVolume(
const Offer::Operation::Create& create,
- const Option<string>& principal)
+ const Option<Principal>& principal)
{
if (authorizer.isNone()) {
return true; // Authorization is disabled.
@@ -3532,11 +3542,12 @@ Future<bool> Master::authorizeCreateVolume(
authorization::Request request;
request.set_action(authorization::CREATE_VOLUME);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
- // The operation will be authorized if the principal is allowed to create
+ // The operation will be authorized if the entity is allowed to create
// volumes for all roles included in `create.volumes`.
// Add an element to `request.roles` for each unique role in the volumes.
hashset<string> roles;
@@ -3551,10 +3562,9 @@ Future<bool> Master::authorizeCreateVolume(
}
}
- LOG(INFO)
- << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
- << "' to create volumes";
+ LOG(INFO) << "Authorizing principal '"
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
+ << "' to create volumes '" << create.volumes() << "'";
if (authorizations.empty()) {
return authorizer.get()->authorized(request);
@@ -3576,7 +3586,7 @@ Future<bool> Master::authorizeCreateVolume(
Future<bool> Master::authorizeDestroyVolume(
const Offer::Operation::Destroy& destroy,
- const Option<string>& principal)
+ const Option<Principal>& principal)
{
if (authorizer.isNone()) {
return true; // Authorization is disabled.
@@ -3585,8 +3595,9 @@ Future<bool> Master::authorizeDestroyVolume(
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
list<Future<bool>> authorizations;
@@ -3603,11 +3614,9 @@ Future<bool> Master::authorizeDestroyVolume(
}
}
- LOG(INFO)
- << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
- << "' to destroy volumes '"
- << stringify(destroy.volumes()) << "'";
+ LOG(INFO) << "Authorizing principal '"
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
+ << "' to destroy volumes '" << destroy.volumes() << "'";
if (authorizations.empty()) {
return authorizer.get()->authorized(request);
@@ -3876,9 +3885,9 @@ void Master::accept(
// The RESERVE operation allows a principal to reserve resources.
case Offer::Operation::RESERVE: {
- Option<string> principal = framework->info.has_principal()
- ? framework->info.principal()
- : Option<string>::none();
+ Option<Principal> principal = framework->info.has_principal()
+ ? Principal(framework->info.principal())
+ : Option<Principal>::none();
futures.push_back(
authorizeReserveResources(
@@ -3889,9 +3898,9 @@ void Master::accept(
// The UNRESERVE operation allows a principal to unreserve resources.
case Offer::Operation::UNRESERVE: {
- Option<string> principal = framework->info.has_principal()
- ? framework->info.principal()
- : Option<string>::none();
+ Option<Principal> principal = framework->info.has_principal()
+ ? Principal(framework->info.principal())
+ : Option<Principal>::none();
futures.push_back(
authorizeUnreserveResources(
@@ -3902,9 +3911,9 @@ void Master::accept(
// The CREATE operation allows the creation of a persistent volume.
case Offer::Operation::CREATE: {
- Option<string> principal = framework->info.has_principal()
- ? framework->info.principal()
- : Option<string>::none();
+ Option<Principal> principal = framework->info.has_principal()
+ ? Principal(framework->info.principal())
+ : Option<Principal>::none();
futures.push_back(
authorizeCreateVolume(
@@ -3915,9 +3924,9 @@ void Master::accept(
// The DESTROY operation allows the destruction of a persistent volume.
case Offer::Operation::DESTROY: {
- Option<string> principal = framework->info.has_principal()
- ? framework->info.principal()
- : Option<string>::none();
+ Option<Principal> principal = framework->info.has_principal()
+ ? Principal(framework->info.principal())
+ : Option<Principal>::none();
futures.push_back(
authorizeDestroyVolume(
@@ -4100,9 +4109,9 @@ void Master::_accept(
continue;
}
- Option<string> principal = framework->info.has_principal()
- ? framework->info.principal()
- : Option<string>::none();
+ Option<Principal> principal = framework->info.has_principal()
+ ? Principal(framework->info.principal())
+ : Option<Principal>::none();
// Make sure this reserve operation is valid.
Option<Error> error = validation::operation::validate(
@@ -4213,9 +4222,9 @@ void Master::_accept(
continue;
}
- Option<string> principal = framework->info.has_principal() ?
- framework->info.principal() :
- Option<string>::none();
+ Option<Principal> principal = framework->info.has_principal()
+ ? Principal(framework->info.principal())
+ : Option<Principal>::none();
// Make sure this create operation is valid.
Option<Error> error = validation::operation::validate(
http://git-wip-us.apache.org/repos/asf/mesos/blob/da47646e/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 81320e0..47c5e61 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -680,7 +680,7 @@ protected:
*/
process::Future<bool> authorizeReserveResources(
const Offer::Operation::Reserve& reserve,
- const Option<std::string>& principal);
+ const Option<process::http::authentication::Principal>& principal);
/**
* Authorizes an `UNRESERVE` offer operation.
@@ -701,7 +701,7 @@ protected:
*/
process::Future<bool> authorizeUnreserveResources(
const Offer::Operation::Unreserve& unreserve,
- const Option<std::string>& principal);
+ const Option<process::http::authentication::Principal>& principal);
/**
* Authorizes a `CREATE` offer operation.
@@ -722,7 +722,7 @@ protected:
*/
process::Future<bool> authorizeCreateVolume(
const Offer::Operation::Create& create,
- const Option<std::string>& principal);
+ const Option<process::http::authentication::Principal>& principal);
/**
* Authorizes a `DESTROY` offer operation.
@@ -743,7 +743,7 @@ protected:
*/
process::Future<bool> authorizeDestroyVolume(
const Offer::Operation::Destroy& destroy,
- const Option<std::string>& principal);
+ const Option<process::http::authentication::Principal>& principal);
// Add the task and its executor (if not already running) to the
// framework and slave. Returns the resources consumed as a result,
@@ -931,7 +931,7 @@ private:
const process::Future<bool>& registrarResult);
process::Future<bool> authorizeLogAccess(
- const Option<std::string>& principal);
+ const Option<process::http::authentication::Principal>& principal);
/**
* Returns whether the given role is on the whitelist.
@@ -976,28 +976,33 @@ private:
// Returns a list of set quotas.
process::Future<process::http::Response> status(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> status(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> set(
const mesos::master::Call& call,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> set(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> remove(
const mesos::master::Call& call,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> remove(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
private:
// Heuristically tries to determine whether a quota request could
@@ -1045,7 +1050,7 @@ private:
void rescindOffers(const mesos::quota::QuotaInfo& request) const;
process::Future<bool> authorizeGetQuota(
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
const mesos::quota::QuotaInfo& quotaInfo) const;
// TODO(mpark): The following functions `authorizeSetQuota` and
@@ -1053,19 +1058,21 @@ private:
// the end of deprecation cycle which started with 1.0.
process::Future<bool> authorizeSetQuota(
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
const mesos::quota::QuotaInfo& quotaInfo) const;
process::Future<bool> authorizeRemoveQuota(
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
const mesos::quota::QuotaInfo& quotaInfo) const;
process::Future<mesos::quota::QuotaStatus> _status(
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> _set(
const mesos::quota::QuotaRequest& quotaRequest,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> __set(
const mesos::quota::QuotaInfo& quotaInfo,
@@ -1073,7 +1080,8 @@ private:
process::Future<process::http::Response> _remove(
const std::string& role,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> __remove(
const std::string& role) const;
@@ -1101,29 +1109,31 @@ private:
process::Future<process::http::Response> get(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> get(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> update(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> update(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
private:
process::Future<bool> authorizeGetWeight(
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
const WeightInfo& weight) const;
process::Future<bool> authorizeUpdateWeights(
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
const std::vector<std::string>& roles) const;
process::Future<std::vector<WeightInfo>> _filterWeights(
@@ -1131,10 +1141,11 @@ private:
const std::list<bool>& roleAuthorizations) const;
process::Future<std::vector<WeightInfo>> _getWeights(
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response>_updateWeights(
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
const google::protobuf::RepeatedPtrField<WeightInfo>& weightInfos)
const;
@@ -1164,32 +1175,38 @@ private:
// /api/v1
process::Future<process::http::Response> api(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /api/v1/scheduler
process::Future<process::http::Response> scheduler(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/create-volumes
process::Future<process::http::Response> createVolumes(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/destroy-volumes
process::Future<process::http::Response> destroyVolumes(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/flags
process::Future<process::http::Response> flags(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/frameworks
process::Future<process::http::Response> frameworks(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/health
process::Future<process::http::Response> health(
@@ -1202,72 +1219,86 @@ private:
// /master/reserve
process::Future<process::http::Response> reserve(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/roles
process::Future<process::http::Response> roles(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/teardown
process::Future<process::http::Response> teardown(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/slaves
process::Future<process::http::Response> slaves(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/state
process::Future<process::http::Response> state(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/state-summary
process::Future<process::http::Response> stateSummary(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/tasks
process::Future<process::http::Response> tasks(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/maintenance/schedule
process::Future<process::http::Response> maintenanceSchedule(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/maintenance/status
process::Future<process::http::Response> maintenanceStatus(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/machine/down
process::Future<process::http::Response> machineDown(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/machine/up
process::Future<process::http::Response> machineUp(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/unreserve
process::Future<process::http::Response> unreserve(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/quota
process::Future<process::http::Response> quota(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// /master/weights
process::Future<process::http::Response> weights(
const process::http::Request& request,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
static std::string API_HELP();
static std::string SCHEDULER_HELP();
@@ -1298,13 +1329,15 @@ private:
class FlagsError; // Forward declaration.
process::Future<Try<JSON::Object, FlagsError>> _flags(
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<std::vector<const Task*>> _tasks(
const size_t limit,
const size_t offset,
const std::string& order,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> _teardown(
const FrameworkID& id) const;
@@ -1326,22 +1359,26 @@ private:
process::Future<process::http::Response> _reserve(
const SlaveID& slaveId,
const Resources& resources,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> _unreserve(
const SlaveID& slaveId,
const Resources& resources,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> _createVolumes(
const SlaveID& slaveId,
const google::protobuf::RepeatedPtrField<Resource>& volumes,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
process::Future<process::http::Response> _destroyVolumes(
const SlaveID& slaveId,
const google::protobuf::RepeatedPtrField<Resource>& volumes,
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
/**
* Continuation for operations: /reserve, /unreserve,
@@ -1368,90 +1405,91 @@ private:
const Offer::Operation& operation) const;
process::Future<std::vector<std::string>> _roles(
- const Option<std::string>& principal) const;
+ const Option<process::http::authentication::Principal>&
+ principal) const;
// Master API handlers.
process::Future<process::http::Response> getAgents(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
mesos::master::Response::GetAgents _getAgents() const;
process::Future<process::http::Response> getFlags(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getHealth(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getVersion(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getRoles(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getMetrics(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getLoggingLevel(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> setLoggingLevel(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> listFiles(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getMaster(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> updateMaintenanceSchedule(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getMaintenanceSchedule(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getMaintenanceStatus(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> startMaintenance(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> stopMaintenance(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getTasks(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
mesos::master::Response::GetTasks _getTasks(
@@ -1460,27 +1498,27 @@ private:
process::Future<process::http::Response> createVolumes(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> destroyVolumes(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> reserveResources(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> unreserveResources(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> getFrameworks(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
mesos::master::Response::GetFrameworks _getFrameworks(
@@ -1488,7 +1526,7 @@ private:
process::Future<process::http::Response> getExecutors(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
mesos::master::Response::GetExecutors _getExecutors(
@@ -1497,7 +1535,7 @@ private:
process::Future<process::http::Response> getState(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
mesos::master::Response::GetState _getState(
@@ -1507,12 +1545,12 @@ private:
process::Future<process::http::Response> subscribe(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
process::Future<process::http::Response> readFile(
const mesos::master::Call& call,
- const Option<std::string>& principal,
+ const Option<process::http::authentication::Principal>& principal,
ContentType contentType) const;
Master* master;
http://git-wip-us.apache.org/repos/asf/mesos/blob/da47646e/src/master/quota_handler.cpp
----------------------------------------------------------------------
diff --git a/src/master/quota_handler.cpp b/src/master/quota_handler.cpp
index 3ad28e4..5212ed7 100644
--- a/src/master/quota_handler.cpp
+++ b/src/master/quota_handler.cpp
@@ -50,6 +50,8 @@ using http::Conflict;
using http::Forbidden;
using http::OK;
+using mesos::authorization::createSubject;
+
using mesos::quota::QuotaInfo;
using mesos::quota::QuotaRequest;
using mesos::quota::QuotaStatus;
@@ -57,6 +59,8 @@ using mesos::quota::QuotaStatus;
using process::Future;
using process::Owned;
+using process::http::authentication::Principal;
+
using std::list;
using std::string;
using std::vector;
@@ -213,7 +217,7 @@ void Master::QuotaHandler::rescindOffers(const QuotaInfo& request) const
Future<http::Response> Master::QuotaHandler::status(
const mesos::master::Call& call,
- const Option<string>& principal,
+ const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_QUOTA, call.type());
@@ -232,7 +236,7 @@ Future<http::Response> Master::QuotaHandler::status(
Future<http::Response> Master::QuotaHandler::status(
const http::Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
VLOG(1) << "Handling quota status request";
@@ -247,7 +251,7 @@ Future<http::Response> Master::QuotaHandler::status(
Future<QuotaStatus> Master::QuotaHandler::_status(
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
// Quotas can be updated during preparation of the response.
// Copy current view of the collection to avoid conflicts.
@@ -296,7 +300,7 @@ Future<QuotaStatus> Master::QuotaHandler::_status(
Future<http::Response> Master::QuotaHandler::set(
const mesos::master::Call& call,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
CHECK_EQ(mesos::master::Call::SET_QUOTA, call.type());
CHECK(call.has_set_quota());
@@ -307,7 +311,7 @@ Future<http::Response> Master::QuotaHandler::set(
Future<http::Response> Master::QuotaHandler::set(
const http::Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
VLOG(1) << "Setting quota from request: '" << request.body << "'";
@@ -338,7 +342,7 @@ Future<http::Response> Master::QuotaHandler::set(
Future<http::Response> Master::QuotaHandler::_set(
const QuotaRequest& quotaRequest,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
Try<QuotaInfo> create = quota::createQuotaInfo(quotaRequest);
if (create.isError()) {
@@ -376,7 +380,12 @@ Future<http::Response> Master::QuotaHandler::_set(
const bool forced = quotaRequest.force();
if (principal.isSome()) {
- quotaInfo.set_principal(principal.get());
+ // We assume that `principal->value.isSome()` is true. The master's HTTP
+ // handlers enforce this constraint, and V0 authenticators will only return
+ // principals of that form.
+ CHECK_SOME(principal->value);
+
+ quotaInfo.set_principal(principal->value.get());
}
return authorizeSetQuota(principal, quotaInfo)
@@ -439,7 +448,7 @@ Future<http::Response> Master::QuotaHandler::__set(
Future<http::Response> Master::QuotaHandler::remove(
const mesos::master::Call& call,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
CHECK_EQ(mesos::master::Call::REMOVE_QUOTA, call.type());
CHECK(call.has_remove_quota());
@@ -450,7 +459,7 @@ Future<http::Response> Master::QuotaHandler::remove(
Future<http::Response> Master::QuotaHandler::remove(
const http::Request& request,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
VLOG(1) << "Removing quota for request path: '" << request.url.path << "'";
@@ -497,7 +506,7 @@ Future<http::Response> Master::QuotaHandler::remove(
Future<http::Response> Master::QuotaHandler::_remove(
const string& role,
- const Option<string>& principal) const
+ const Option<Principal>& principal) const
{
return authorizeRemoveQuota(principal, master->quotas[role].info)
.then(defer(master->self(), [=](bool authorized) -> Future<http::Response> {
@@ -531,7 +540,7 @@ Future<http::Response> Master::QuotaHandler::__remove(const string& role) const
Future<bool> Master::QuotaHandler::authorizeGetQuota(
- const Option<string>& principal,
+ const Option<Principal>& principal,
const QuotaInfo& quotaInfo) const
{
if (master->authorizer.isNone()) {
@@ -539,14 +548,15 @@ Future<bool> Master::QuotaHandler::authorizeGetQuota(
}
LOG(INFO) << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
<< "' to get quota for role '" << quotaInfo.role() << "'";
authorization::Request request;
request.set_action(authorization::GET_QUOTA);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
// TODO(alexr): The `value` field is set for backwards compatibility
@@ -561,7 +571,7 @@ Future<bool> Master::QuotaHandler::authorizeGetQuota(
// TODO(zhitao): Remove this function at the end of the
// deprecation cycle which started with 1.0.
Future<bool> Master::QuotaHandler::authorizeSetQuota(
- const Option<string>& principal,
+ const Option<Principal>& principal,
const QuotaInfo& quotaInfo) const
{
if (master->authorizer.isNone()) {
@@ -569,14 +579,15 @@ Future<bool> Master::QuotaHandler::authorizeSetQuota(
}
LOG(INFO) << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
<< "' to set quota for role '" << quotaInfo.role() << "'";
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
request.mutable_object()->set_value("SetQuota");
@@ -589,7 +600,7 @@ Future<bool> Master::QuotaHandler::authorizeSetQuota(
// TODO(zhitao): Remove this function at the end of the
// deprecation cycle which started with 1.0.
Future<bool> Master::QuotaHandler::authorizeRemoveQuota(
- const Option<string>& principal,
+ const Option<Principal>& principal,
const QuotaInfo& quotaInfo) const
{
if (master->authorizer.isNone()) {
@@ -597,14 +608,15 @@ Future<bool> Master::QuotaHandler::authorizeRemoveQuota(
}
LOG(INFO) << "Authorizing principal '"
- << (principal.isSome() ? principal.get() : "ANY")
+ << (principal.isSome() ? stringify(principal.get()) : "ANY")
<< "' to remove quota for role '" << quotaInfo.role() << "'";
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
- if (principal.isSome()) {
- request.mutable_subject()->set_value(principal.get());
+ Option<authorization::Subject> subject = createSubject(principal);
+ if (subject.isSome()) {
+ request.mutable_subject()->CopyFrom(subject.get());
}
request.mutable_object()->set_value("RemoveQuota");
http://git-wip-us.apache.org/repos/asf/mesos/blob/da47646e/src/master/registrar.cpp
----------------------------------------------------------------------
diff --git a/src/master/registrar.cpp b/src/master/registrar.cpp
index d7134ee..0029cc7 100644
--- a/src/master/registrar.cpp
+++ b/src/master/registrar.cpp
@@ -65,6 +65,8 @@ using process::TLDR;
using process::http::OK;
+using process::http::authentication::Principal;
+
using process::metrics::Gauge;
using process::metrics::Timer;
@@ -120,7 +122,7 @@ private:
// /registrar(N)/registry
Future<Response> registry(
const Request& request,
- const Option<string>& /* principal */);
+ const Option<Principal>&);
static string registryHelp();
// The 'Recover' operation adds the latest MasterInfo.
@@ -256,7 +258,7 @@ void fail(deque<Owned<Operation>>* operations, const string& message)
Future<Response> RegistrarProcess::registry(
const Request& request,
- const Option<string>& /* principal */)
+ const Option<Principal>&)
{
JSON::Object result;