http://git-wip-us.apache.org/repos/asf/mesos/blob/dc1e188a/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 05fd7ce..1d7e159 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -125,11 +125,22 @@ using std::tie;
using std::tuple;
using std::vector;
+using mesos::authorization::createSubject;
+using mesos::authorization::GET_MAINTENANCE_SCHEDULE;
+using mesos::authorization::GET_MAINTENANCE_STATUS;
+using mesos::authorization::MARK_AGENT_GONE;
+using mesos::authorization::SET_LOG_LEVEL;
+using mesos::authorization::START_MAINTENANCE;
+using mesos::authorization::STOP_MAINTENANCE;
+using mesos::authorization::UPDATE_MAINTENANCE_SCHEDULE;
+using mesos::authorization::VIEW_EXECUTOR;
+using mesos::authorization::VIEW_FLAGS;
+using mesos::authorization::VIEW_FRAMEWORK;
+using mesos::authorization::VIEW_ROLE;
+using mesos::authorization::VIEW_TASK;
namespace mesos {
-using mesos::authorization::createSubject;
-
static void json(
JSON::StringWriter* writer,
const FrameworkInfo::Capability& capability)
@@ -228,11 +239,9 @@ static void json(JSON::ObjectWriter* writer, const
Summary<Framework>& summary);
// user is authorized to view them.
struct FullFrameworkWriter {
FullFrameworkWriter(
- const Owned<AuthorizationAcceptor>& authorizeTask,
- const Owned<AuthorizationAcceptor>& authorizeExecutorInfo,
+ const Owned<ObjectApprovers>& approvers,
const Framework* framework)
- : authorizeTask_(authorizeTask),
- authorizeExecutorInfo_(authorizeExecutorInfo),
+ : approvers_(approvers),
framework_(framework) {}
void operator()(JSON::ObjectWriter* writer) const
@@ -277,7 +286,7 @@ struct FullFrameworkWriter {
writer->field("tasks", [this](JSON::ArrayWriter* writer) {
foreachvalue (const TaskInfo& taskInfo, framework_->pendingTasks) {
// Skip unauthorized tasks.
- if (!authorizeTask_->accept(taskInfo, framework_->info)) {
+ if (!approvers_->approved<VIEW_TASK>(taskInfo, framework_->info)) {
continue;
}
@@ -318,7 +327,7 @@ struct FullFrameworkWriter {
foreachvalue (Task* task, framework_->tasks) {
// Skip unauthorized tasks.
- if (!authorizeTask_->accept(*task, framework_->info)) {
+ if (!approvers_->approved<VIEW_TASK>(*task, framework_->info)) {
continue;
}
@@ -329,7 +338,7 @@ struct FullFrameworkWriter {
writer->field("unreachable_tasks", [this](JSON::ArrayWriter* writer) {
foreachvalue (const Owned<Task>& task, framework_->unreachableTasks) {
// Skip unauthorized tasks.
- if (!authorizeTask_->accept(*task, framework_->info)) {
+ if (!approvers_->approved<VIEW_TASK>(*task, framework_->info)) {
continue;
}
@@ -340,7 +349,7 @@ struct FullFrameworkWriter {
writer->field("completed_tasks", [this](JSON::ArrayWriter* writer) {
foreach (const Owned<Task>& task, framework_->completedTasks) {
// Skip unauthorized tasks.
- if (!authorizeTask_->accept(*task, framework_->info)) {
+ if (!approvers_->approved<VIEW_TASK>(*task, framework_->info)) {
continue;
}
@@ -366,7 +375,8 @@ struct FullFrameworkWriter {
&executor,
&slaveId](JSON::ObjectWriter* writer) {
// Skip unauthorized executors.
- if (!authorizeExecutorInfo_->accept(executor, framework_->info)) {
+ if (!approvers_->approved<VIEW_EXECUTOR>(
+ executor, framework_->info)) {
return;
}
@@ -383,8 +393,7 @@ struct FullFrameworkWriter {
}
}
- const Owned<AuthorizationAcceptor>& authorizeTask_;
- const Owned<AuthorizationAcceptor>& authorizeExecutorInfo_;
+ const Owned<ObjectApprovers>& approvers_;
const Framework* framework_;
};
@@ -393,8 +402,8 @@ struct SlaveWriter
{
SlaveWriter(
const Slave& slave,
- const Owned<AuthorizationAcceptor>& authorizeRole)
- : slave_(slave), authorizeRole_(authorizeRole) {}
+ const Owned<ObjectApprovers>& approvers)
+ : slave_(slave), approvers_(approvers) {}
void operator()(JSON::ObjectWriter* writer) const
{
@@ -419,7 +428,7 @@ struct SlaveWriter
// TODO(arojas): Consider showing unapproved resources in an
// aggregated special field, so that all resource values add up
// MESOS-7779.
- if (authorizeRole_->accept(role)) {
+ if (approvers_->approved<VIEW_ROLE>(role)) {
writer->field(role, reservation);
}
}
@@ -432,7 +441,7 @@ struct SlaveWriter
}
const Slave& slave_;
- const Owned<AuthorizationAcceptor>& authorizeRole_;
+ const Owned<ObjectApprovers>& approvers_;
};
@@ -440,10 +449,10 @@ struct SlavesWriter
{
SlavesWriter(
const Master::Slaves& slaves,
- const Owned<AuthorizationAcceptor>& authorizeRole,
+ const Owned<ObjectApprovers>& approvers,
const IDAcceptor<SlaveID>& selectSlaveId)
: slaves_(slaves),
- authorizeRole_(authorizeRole),
+ approvers_(approvers),
selectSlaveId_(selectSlaveId) {}
void operator()(JSON::ObjectWriter* writer) const
@@ -475,7 +484,7 @@ struct SlavesWriter
void writeSlave(const Slave* slave, JSON::ObjectWriter* writer) const
{
- SlaveWriter(*slave, authorizeRole_)(writer);
+ SlaveWriter(*slave, approvers_)(writer);
// Add the complete protobuf->JSON for all used, reserved,
// and offered resources. The other endpoints summarize
@@ -492,11 +501,11 @@ struct SlavesWriter
foreachpair (const string& role,
const Resources& resources,
reserved) {
- if (authorizeRole_->accept(role)) {
+ if (approvers_->approved<VIEW_ROLE>(role)) {
writer->field(role, [&resources, this](
JSON::ArrayWriter* writer) {
foreach (Resource resource, resources) {
- if (authorizeResource(resource, authorizeRole_)) {
+ if (approvers_->approved<VIEW_ROLE>(resource)) {
convertResourceFormat(&resource, ENDPOINT);
writer->element(JSON::Protobuf(resource));
}
@@ -512,7 +521,7 @@ struct SlavesWriter
"unreserved_resources_full",
[&unreservedResources, this](JSON::ArrayWriter* writer) {
foreach (Resource resource, unreservedResources) {
- if (authorizeResource(resource, authorizeRole_)) {
+ if (approvers_->approved<VIEW_ROLE>(resource)) {
convertResourceFormat(&resource, ENDPOINT);
writer->element(JSON::Protobuf(resource));
}
@@ -525,7 +534,7 @@ struct SlavesWriter
"used_resources_full",
[&usedResources, this](JSON::ArrayWriter* writer) {
foreach (Resource resource, usedResources) {
- if (authorizeResource(resource, authorizeRole_)) {
+ if (approvers_->approved<VIEW_ROLE>(resource)) {
convertResourceFormat(&resource, ENDPOINT);
writer->element(JSON::Protobuf(resource));
}
@@ -538,7 +547,7 @@ struct SlavesWriter
"offered_resources_full",
[&offeredResources, this](JSON::ArrayWriter* writer) {
foreach (Resource resource, offeredResources) {
- if (authorizeResource(resource, authorizeRole_)) {
+ if (approvers_->approved<VIEW_ROLE>(resource)) {
convertResourceFormat(&resource, ENDPOINT);
writer->element(JSON::Protobuf(resource));
}
@@ -547,7 +556,7 @@ struct SlavesWriter
}
const Master::Slaves& slaves_;
- const Owned<AuthorizationAcceptor>& authorizeRole_;
+ const Owned<ObjectApprovers>& approvers_;
const IDAcceptor<SlaveID>& selectSlaveId_;
};
@@ -806,51 +815,13 @@ Future<Response> Master::Http::subscribe(
{
CHECK_EQ(mesos::master::Call::SUBSCRIBE, call.type());
- // Retrieve Approvers for authorizing frameworks and tasks.
- Future<Owned<ObjectApprover>> frameworksApprover;
- Future<Owned<ObjectApprover>> tasksApprover;
- Future<Owned<ObjectApprover>> executorsApprover;
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- frameworksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_FRAMEWORK);
-
- tasksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_TASK);
-
- executorsApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_EXECUTOR);
- } else {
- frameworksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- tasksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- executorsApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- Future<Owned<AuthorizationAcceptor>> rolesAcceptor =
- AuthorizationAcceptor::create(
- principal,
- master->authorizer,
- authorization::VIEW_ROLE);
-
- return collect(
- frameworksApprover, tasksApprover, executorsApprover, rolesAcceptor)
- .then(defer(master->self(),
- [=](const tuple<Owned<ObjectApprover>,
- Owned<ObjectApprover>,
- Owned<ObjectApprover>,
- Owned<AuthorizationAcceptor>>& approvers)
- -> Future<Response> {
- // Get approver from tuple.
- Owned<ObjectApprover> frameworksApprover;
- Owned<ObjectApprover> tasksApprover;
- Owned<ObjectApprover> executorsApprover;
- Owned<AuthorizationAcceptor> rolesAcceptor;
- tie(frameworksApprover,
- tasksApprover,
- executorsApprover,
- rolesAcceptor) = approvers;
-
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK, VIEW_TASK, VIEW_EXECUTOR, VIEW_ROLE})
+ .then(defer(
+ master->self(),
+ [=](const Owned<ObjectApprovers>& approvers) -> Future<Response> {
Pipe pipe;
OK ok;
@@ -864,11 +835,7 @@ Future<Response> Master::Http::subscribe(
mesos::master::Event event;
event.set_type(mesos::master::Event::SUBSCRIBED);
*event.mutable_subscribed()->mutable_get_state() =
- _getState(
- frameworksApprover,
- tasksApprover,
- executorsApprover,
- rolesAcceptor);
+ _getState(approvers);
event.mutable_subscribed()->set_heartbeat_interval_seconds(
DEFAULT_HEARTBEAT_INTERVAL.secs());
@@ -880,7 +847,7 @@ Future<Response> Master::Http::subscribe(
http.send<mesos::master::Event, v1::master::Event>(heartbeatEvent);
return ok;
- }));
+ }));
}
@@ -1556,97 +1523,63 @@ Future<Response> Master::Http::frameworks(
return redirect(request);
}
- Future<Owned<AuthorizationAcceptor>> authorizeFrameworkInfo =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_FRAMEWORK);
- Future<Owned<AuthorizationAcceptor>> authorizeTask =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_TASK);
- Future<Owned<AuthorizationAcceptor>> authorizeExecutorInfo =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_EXECUTOR);
- Future<IDAcceptor<FrameworkID>> selectFrameworkId =
- IDAcceptor<FrameworkID>(request.url.query.get("framework_id"));
-
- return collect(
- authorizeFrameworkInfo,
- authorizeTask,
- authorizeExecutorInfo,
- selectFrameworkId)
- .then(defer(master->self(),
- [this, request](const tuple<Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>,
- IDAcceptor<FrameworkID>>& acceptors)
- -> Response {
- // This lambda is consumed before the outer lambda
- // returns, hence capture by reference is fine here.
- auto frameworks = [this, &acceptors](JSON::ObjectWriter* writer) {
- Owned<AuthorizationAcceptor> authorizeFrameworkInfo;
- Owned<AuthorizationAcceptor> authorizeTask;
- Owned<AuthorizationAcceptor> authorizeExecutorInfo;
- IDAcceptor<FrameworkID> selectFrameworkId;
- tie(authorizeFrameworkInfo,
- authorizeTask,
- authorizeExecutorInfo,
- selectFrameworkId) = acceptors;
-
- // Model all of the frameworks.
- writer->field(
- "frameworks",
- [this,
- &authorizeFrameworkInfo,
- &authorizeTask,
- &authorizeExecutorInfo,
- &selectFrameworkId](JSON::ArrayWriter* writer) {
- foreachvalue (Framework* framework, master->frameworks.registered) {
- // Skip unauthorized frameworks or frameworks without a matching
ID.
- if (!selectFrameworkId.accept(framework->id()) ||
- !authorizeFrameworkInfo->accept(framework->info)) {
- continue;
- }
-
- FullFrameworkWriter frameworkWriter(
- authorizeTask,
- authorizeExecutorInfo,
- framework);
-
- writer->element(frameworkWriter);
- }
- });
-
- // Model all of the completed frameworks.
- writer->field(
- "completed_frameworks",
- [this,
- &authorizeFrameworkInfo,
- &authorizeTask,
- &authorizeExecutorInfo,
- &selectFrameworkId](JSON::ArrayWriter* writer) {
- foreachvalue (const Owned<Framework>& framework,
- master->frameworks.completed) {
- // Skip unauthorized frameworks or frameworks without a matching
ID.
- if (!selectFrameworkId.accept(framework->id()) ||
- !authorizeFrameworkInfo->accept(framework->info)) {
- continue;
- }
-
- FullFrameworkWriter frameworkWriter(
- authorizeTask,
- authorizeExecutorInfo,
- framework.get());
-
- writer->element(frameworkWriter);
- }
- });
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK, VIEW_TASK, VIEW_EXECUTOR})
+ .then(defer(
+ master->self(),
+ [this, request](const Owned<ObjectApprovers>& approvers) -> Response {
+ IDAcceptor<FrameworkID> selectFrameworkId(
+ request.url.query.get("framework_id"));
+ // This lambda is consumed before the outer lambda
+ // returns, hence capture by reference is fine here.
+ auto frameworks = [this, &approvers, &selectFrameworkId](
+ JSON::ObjectWriter* writer) {
+ // Model all of the frameworks.
+ writer->field(
+ "frameworks",
+ [this, &approvers, &selectFrameworkId](
+ JSON::ArrayWriter* writer) {
+ foreachvalue (
+ Framework* framework, master->frameworks.registered) {
+ // Skip unauthorized frameworks or frameworks
+ // without a matching ID.
+ if (!selectFrameworkId.accept(framework->id()) ||
+ !approvers->approved<VIEW_FRAMEWORK>(framework->info))
{
+ continue;
+ }
+
+ writer->element(FullFrameworkWriter(approvers, framework));
+ }
+ });
+
+ // Model all of the completed frameworks.
+ writer->field(
+ "completed_frameworks",
+ [this, &approvers, &selectFrameworkId](
+ JSON::ArrayWriter* writer) {
+ foreachvalue (const Owned<Framework>& framework,
+ master->frameworks.completed) {
+ // Skip unauthorized frameworks or frameworks
+ // without a matching ID.
+ if (!selectFrameworkId.accept(framework->id()) ||
+ !approvers->approved<VIEW_FRAMEWORK>(framework->info))
{
+ continue;
+ }
+
+ writer->element(
+ FullFrameworkWriter(approvers, framework.get()));
+ }
+ });
- // Unregistered frameworks are no longer possible. We emit an
- // empty array for the sake of backward compatibility.
- writer->field("unregistered_frameworks", [](JSON::ArrayWriter*) {});
- };
+ // Unregistered frameworks are no longer possible. We emit an
+ // empty array for the sake of backward compatibility.
+ writer->field("unregistered_frameworks", [](JSON::ArrayWriter*)
{});
+ };
- return OK(jsonify(frameworks), request.url.query.get("jsonp"));
- }));
+ return OK(jsonify(frameworks), request.url.query.get("jsonp"));
+ }));
}
@@ -1707,40 +1640,31 @@ Future<Response> Master::Http::getFrameworks(
{
CHECK_EQ(mesos::master::Call::GET_FRAMEWORKS, call.type());
- // Retrieve `ObjectApprover`s for authorizing frameworks.
- Future<Owned<ObjectApprover>> frameworksApprover;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- frameworksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_FRAMEWORK);
- } else {
- frameworksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return frameworksApprover
- .then(defer(master->self(),
- [=](const Owned<ObjectApprover>& frameworksApprover)
- -> Future<Response> {
- mesos::master::Response response;
- response.set_type(mesos::master::Response::GET_FRAMEWORKS);
- *response.mutable_get_frameworks() = _getFrameworks(frameworksApprover);
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK})
+ .then(defer(
+ master->self(),
+ [=](const Owned<ObjectApprovers>& approvers) -> Future<Response> {
+ mesos::master::Response response;
+ response.set_type(mesos::master::Response::GET_FRAMEWORKS);
+ *response.mutable_get_frameworks() = _getFrameworks(approvers);
- return OK(serialize(contentType, evolve(response)),
- stringify(contentType));
- }));
+ return OK(
+ serialize(contentType, evolve(response)),
stringify(contentType));
+ }));
}
mesos::master::Response::GetFrameworks Master::Http::_getFrameworks(
- const Owned<ObjectApprover>& frameworksApprover) const
+ const Owned<ObjectApprovers>& approvers) const
{
mesos::master::Response::GetFrameworks getFrameworks;
foreachvalue (const Framework* framework,
master->frameworks.registered) {
// Skip unauthorized frameworks.
- if (!approveViewFrameworkInfo(frameworksApprover, framework->info)) {
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -1750,7 +1674,7 @@ mesos::master::Response::GetFrameworks
Master::Http::_getFrameworks(
foreachvalue (const Owned<Framework>& framework,
master->frameworks.completed) {
// Skip unauthorized frameworks.
- if (!approveViewFrameworkInfo(frameworksApprover, framework->info)) {
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -1768,53 +1692,32 @@ Future<Response> Master::Http::getExecutors(
{
CHECK_EQ(mesos::master::Call::GET_EXECUTORS, call.type());
- // Retrieve `ObjectApprover`s for authorizing frameworks and executors.
- Future<Owned<ObjectApprover>> frameworksApprover;
- Future<Owned<ObjectApprover>> executorsApprover;
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- frameworksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_FRAMEWORK);
-
- executorsApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_EXECUTOR);
- } else {
- frameworksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- executorsApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return collect(frameworksApprover, executorsApprover)
- .then(defer(master->self(),
- [=](const tuple<Owned<ObjectApprover>,
- Owned<ObjectApprover>>& approvers)
- -> Future<Response> {
- // Get approver from tuple.
- Owned<ObjectApprover> frameworksApprover;
- Owned<ObjectApprover> executorsApprover;
- tie(frameworksApprover, executorsApprover) = approvers;
-
- mesos::master::Response response;
- response.set_type(mesos::master::Response::GET_EXECUTORS);
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK, VIEW_EXECUTOR})
+ .then(defer(
+ master->self(),
+ [=](const Owned<ObjectApprovers>& approvers) -> Response {
+ mesos::master::Response response;
+ response.set_type(mesos::master::Response::GET_EXECUTORS);
- *response.mutable_get_executors() =
- _getExecutors(frameworksApprover, executorsApprover);
+ *response.mutable_get_executors() = _getExecutors(approvers);
- return OK(serialize(contentType, evolve(response)),
- stringify(contentType));
- }));
+ return OK(
+ serialize(contentType, evolve(response)),
stringify(contentType));
+ }));
}
mesos::master::Response::GetExecutors Master::Http::_getExecutors(
- const Owned<ObjectApprover>& frameworksApprover,
- const Owned<ObjectApprover>& executorsApprover) const
+ const Owned<ObjectApprovers>& approvers) const
{
// Construct framework list with both active and completed frameworks.
vector<const Framework*> frameworks;
foreachvalue (Framework* framework, master->frameworks.registered) {
// Skip unauthorized frameworks.
- if (!approveViewFrameworkInfo(frameworksApprover, framework->info)) {
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -1824,7 +1727,7 @@ mesos::master::Response::GetExecutors
Master::Http::_getExecutors(
foreachvalue (const Owned<Framework>& framework,
master->frameworks.completed) {
// Skip unauthorized frameworks.
- if (!approveViewFrameworkInfo(frameworksApprover, framework->info)) {
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -1839,9 +1742,8 @@ mesos::master::Response::GetExecutors
Master::Http::_getExecutors(
framework->executors) {
foreachvalue (const ExecutorInfo& executorInfo, executorsMap) {
// Skip unauthorized executors.
- if (!approveViewExecutorInfo(executorsApprover,
- executorInfo,
- framework->info)) {
+ if (!approvers->approved<VIEW_EXECUTOR>(
+ executorInfo, framework->info)) {
continue;
}
@@ -1865,72 +1767,26 @@ Future<Response> Master::Http::getState(
{
CHECK_EQ(mesos::master::Call::GET_STATE, call.type());
- // Retrieve Approvers for authorizing frameworks and tasks.
- Future<Owned<ObjectApprover>> frameworksApprover;
- Future<Owned<ObjectApprover>> tasksApprover;
- Future<Owned<ObjectApprover>> executorsApprover;
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- frameworksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_FRAMEWORK);
-
- tasksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_TASK);
-
- executorsApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_EXECUTOR);
- } else {
- frameworksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- tasksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- executorsApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- Future<Owned<AuthorizationAcceptor>> rolesAcceptor =
- AuthorizationAcceptor::create(
- principal,
- master->authorizer,
- authorization::VIEW_ROLE);
-
- return collect(
- frameworksApprover, tasksApprover, executorsApprover, rolesAcceptor)
- .then(defer(master->self(),
- [=](const tuple<Owned<ObjectApprover>,
- Owned<ObjectApprover>,
- Owned<ObjectApprover>,
- Owned<AuthorizationAcceptor>>& approvers)
- -> Future<Response> {
- // Get approver from tuple.
- Owned<ObjectApprover> frameworksApprover;
- Owned<ObjectApprover> tasksApprover;
- Owned<ObjectApprover> executorsApprover;
- Owned<AuthorizationAcceptor> rolesAcceptor;
- tie(frameworksApprover,
- tasksApprover,
- executorsApprover,
- rolesAcceptor) = approvers;
-
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK, VIEW_TASK, VIEW_EXECUTOR, VIEW_ROLE})
+ .then(defer(
+ master->self(),
+ [=](const Owned<ObjectApprovers>& approvers) -> Response {
mesos::master::Response response;
response.set_type(mesos::master::Response::GET_STATE);
- *response.mutable_get_state() =
- _getState(
- frameworksApprover,
- tasksApprover,
- executorsApprover,
- rolesAcceptor);
+ *response.mutable_get_state() = _getState(approvers);
return OK(
serialize(contentType, evolve(response)),
stringify(contentType));
- }));
+ }));
}
mesos::master::Response::GetState Master::Http::_getState(
- const Owned<ObjectApprover>& frameworksApprover,
- const Owned<ObjectApprover>& tasksApprover,
- const Owned<ObjectApprover>& executorsApprover,
- const Owned<AuthorizationAcceptor>& rolesAcceptor) const
+ const Owned<ObjectApprovers>& approvers) const
{
// NOTE: This function must be blocking instead of returning a
// `Future`. This is because `subscribe()` needs to atomically
@@ -1939,17 +1795,10 @@ mesos::master::Response::GetState
Master::Http::_getState(
mesos::master::Response::GetState getState;
- *getState.mutable_get_tasks() =
- _getTasks(frameworksApprover, tasksApprover);
-
- *getState.mutable_get_executors() =
- _getExecutors(frameworksApprover, executorsApprover);
-
- *getState.mutable_get_frameworks() =
- _getFrameworks(frameworksApprover);
-
- *getState.mutable_get_agents() =
- _getAgents(rolesAcceptor);
+ *getState.mutable_get_tasks() = _getTasks(approvers);
+ *getState.mutable_get_executors() = _getExecutors(approvers);
+ *getState.mutable_get_frameworks() = _getFrameworks(approvers);
+ *getState.mutable_get_agents() = _getAgents(approvers);
return getState;
}
@@ -2207,32 +2056,18 @@ Future<Response> Master::Http::setLoggingLevel(
Duration duration =
Nanoseconds(call.set_logging_level().duration().nanoseconds());
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::SET_LOG_LEVEL);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver.then([level, duration](const Owned<ObjectApprover>& approver)
- -> Future<Response> {
- Try<bool> approved = approver->approved((ObjectApprover::Object()));
-
- if (approved.isError()) {
- return InternalServerError("Authorization error: " + approved.error());
- } else if (!approved.get()) {
- return Forbidden();
- }
+ return ObjectApprovers::create(master->authorizer, principal,
{SET_LOG_LEVEL})
+ .then([level, duration](const Owned<ObjectApprovers>& approvers)
+ -> Future<Response> {
+ if (!approvers->approved<SET_LOG_LEVEL>()) {
+ return Forbidden();
+ }
- return dispatch(process::logging(), &Logging::set_level, level, duration)
+ return dispatch(process::logging(), &Logging::set_level, level, duration)
.then([]() -> Response {
return OK();
});
- });
+ });
}
@@ -2538,63 +2373,52 @@ Future<Response> Master::Http::slaves(
return redirect(request);
}
- Future<Owned<AuthorizationAcceptor>> authorizeRole =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_ROLE);
- Future<IDAcceptor<SlaveID>> selectSlaveId =
- IDAcceptor<SlaveID>(request.url.query.get("slave_id"));
-
- Master* master = this->master;
+ Option<string> slaveId = request.url.query.get("slave_id");
Option<string> jsonp = request.url.query.get("jsonp");
- return collect(authorizeRole, selectSlaveId)
- .then(defer(master->self(),
- [master, jsonp](const tuple<Owned<AuthorizationAcceptor>,
- IDAcceptor<SlaveID>>& acceptors)
- -> Future<Response> {
- Owned<AuthorizationAcceptor> authorizeRole;
- IDAcceptor<SlaveID> selectSlaveId;
- tie(authorizeRole, selectSlaveId) = acceptors;
+ return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
+ .then(defer(
+ master->self(),
+ [this, slaveId, jsonp](const Owned<ObjectApprovers>& approvers)
+ -> Response {
+ IDAcceptor<SlaveID> selectSlaveId(slaveId);
- return OK(
- jsonify(SlavesWriter(master->slaves, authorizeRole, selectSlaveId)),
- jsonp);
- }));
+ return OK(
+ jsonify(SlavesWriter(master->slaves, approvers, selectSlaveId)),
+ jsonp);
+ }));
}
-Future<process::http::Response> Master::Http::getAgents(
+Future<Response> Master::Http::getAgents(
const mesos::master::Call& call,
const Option<Principal>& principal,
ContentType contentType) const
{
CHECK_EQ(mesos::master::Call::GET_AGENTS, call.type());
- return AuthorizationAcceptor::create(
- principal,
- master->authorizer,
- authorization::VIEW_ROLE)
- .then(defer(master->self(),
- [=](const Owned<AuthorizationAcceptor>& rolesAcceptor)
- -> Future<process::http::Response> {
+ return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
+ .then(defer(
+ master->self(),
+ [=](const Owned<ObjectApprovers>& approvers) -> Response {
mesos::master::Response response;
response.set_type(mesos::master::Response::GET_AGENTS);
- *response.mutable_get_agents() = _getAgents(rolesAcceptor);
+ *response.mutable_get_agents() = _getAgents(approvers);
- return OK(serialize(contentType, evolve(response)),
- stringify(contentType));
+ return OK(
+ serialize(contentType, evolve(response)),
stringify(contentType));
}));
}
mesos::master::Response::GetAgents Master::Http::_getAgents(
- const Owned<AuthorizationAcceptor>& rolesAcceptor) const
+ const Owned<ObjectApprovers>& approvers) const
{
mesos::master::Response::GetAgents getAgents;
foreachvalue (const Slave* slave, master->slaves.registered) {
mesos::master::Response::GetAgents::Agent* agent = getAgents.add_agents();
- *agent = protobuf::master::event::createAgentResponse(
- *slave, rolesAcceptor);
+ *agent =
+ protobuf::master::event::createAgentResponse(*slave, approvers);
}
foreachvalue (const SlaveInfo& slaveInfo, master->slaves.recovered) {
@@ -2602,7 +2426,7 @@ mesos::master::Response::GetAgents
Master::Http::_getAgents(
agent->CopyFrom(slaveInfo);
agent->clear_resources();
foreach (const Resource& resource, slaveInfo.resources()) {
- if (authorizeResource(resource, rolesAcceptor)) {
+ if (approvers->approved<VIEW_ROLE>(resource)) {
agent->add_resources()->CopyFrom(resource);
}
}
@@ -2855,195 +2679,150 @@ Future<Response> Master::Http::state(
return redirect(request);
}
- Future<Owned<AuthorizationAcceptor>> authorizeRole =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_ROLE);
- Future<Owned<AuthorizationAcceptor>> authorizeFrameworkInfo =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_FRAMEWORK);
- Future<Owned<AuthorizationAcceptor>> authorizeTask =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_TASK);
- Future<Owned<AuthorizationAcceptor>> authorizeExecutorInfo =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_EXECUTOR);
- Future<Owned<AuthorizationAcceptor>> authorizeFlags =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_FLAGS);
-
- return collect(
- authorizeRole,
- authorizeFrameworkInfo,
- authorizeTask,
- authorizeExecutorInfo,
- authorizeFlags)
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_ROLE, VIEW_FRAMEWORK, VIEW_TASK, VIEW_EXECUTOR, VIEW_FLAGS})
.then(defer(
master->self(),
- [this, request](const tuple<Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>>& acceptors)
- -> Response {
- // This lambda is consumed before the outer lambda
- // returns, hence capture by reference is fine here.
- auto state = [this, &acceptors](JSON::ObjectWriter* writer) {
- Owned<AuthorizationAcceptor> authorizeRole;
- Owned<AuthorizationAcceptor> authorizeFrameworkInfo;
- Owned<AuthorizationAcceptor> authorizeTask;
- Owned<AuthorizationAcceptor> authorizeExecutorInfo;
- Owned<AuthorizationAcceptor> authorizeFlags;
- tie(authorizeRole,
- authorizeFrameworkInfo,
- authorizeTask,
- authorizeExecutorInfo,
- authorizeFlags) = acceptors;
-
- writer->field("version", MESOS_VERSION);
-
- if (build::GIT_SHA.isSome()) {
- writer->field("git_sha", build::GIT_SHA.get());
- }
-
- if (build::GIT_BRANCH.isSome()) {
- writer->field("git_branch", build::GIT_BRANCH.get());
- }
-
- if (build::GIT_TAG.isSome()) {
- writer->field("git_tag", build::GIT_TAG.get());
- }
-
- writer->field("build_date", build::DATE);
- writer->field("build_time", build::TIME);
- writer->field("build_user", build::USER);
- writer->field("start_time", master->startTime.secs());
-
- if (master->electedTime.isSome()) {
- writer->field("elected_time", master->electedTime->secs());
- }
-
- writer->field("id", master->info().id());
- writer->field("pid", string(master->self()));
- writer->field("hostname", master->info().hostname());
- writer->field("capabilities", master->info().capabilities());
- writer->field("activated_slaves", master->_slaves_active());
- writer->field("deactivated_slaves", master->_slaves_inactive());
- writer->field("unreachable_slaves", master->_slaves_unreachable());
-
- if (master->info().has_domain()) {
- writer->field("domain", master->info().domain());
- }
-
- // TODO(haosdent): Deprecated this in favor of `leader_info` below.
- if (master->leader.isSome()) {
- writer->field("leader", master->leader->pid());
- }
+ [this, request](const Owned<ObjectApprovers>& approvers) -> Response {
+ // This lambda is consumed before the outer lambda
+ // returns, hence capture by reference is fine here.
+ auto state = [this, &approvers](JSON::ObjectWriter* writer) {
+ writer->field("version", MESOS_VERSION);
+
+ if (build::GIT_SHA.isSome()) {
+ writer->field("git_sha", build::GIT_SHA.get());
+ }
- if (master->leader.isSome()) {
- writer->field("leader_info", [this](JSON::ObjectWriter* writer) {
- json(writer, master->leader.get());
- });
- }
+ if (build::GIT_BRANCH.isSome()) {
+ writer->field("git_branch", build::GIT_BRANCH.get());
+ }
- if (authorizeFlags->accept()) {
- if (master->flags.cluster.isSome()) {
- writer->field("cluster", master->flags.cluster.get());
- }
+ if (build::GIT_TAG.isSome()) {
+ writer->field("git_tag", build::GIT_TAG.get());
+ }
- if (master->flags.log_dir.isSome()) {
- writer->field("log_dir", master->flags.log_dir.get());
- }
+ writer->field("build_date", build::DATE);
+ writer->field("build_time", build::TIME);
+ writer->field("build_user", build::USER);
+ writer->field("start_time", master->startTime.secs());
- if (master->flags.external_log_file.isSome()) {
- writer->field("external_log_file",
- master->flags.external_log_file.get());
- }
+ if (master->electedTime.isSome()) {
+ writer->field("elected_time", master->electedTime->secs());
+ }
- writer->field("flags", [this](JSON::ObjectWriter* writer) {
- foreachvalue (const flags::Flag& flag, master->flags) {
- Option<string> value = flag.stringify(master->flags);
- if (value.isSome()) {
- writer->field(flag.effective_name().value, value.get());
- }
- }
- });
- }
+ writer->field("id", master->info().id());
+ writer->field("pid", string(master->self()));
+ writer->field("hostname", master->info().hostname());
+ writer->field("capabilities", master->info().capabilities());
+ writer->field("activated_slaves", master->_slaves_active());
+ writer->field("deactivated_slaves", master->_slaves_inactive());
+ writer->field("unreachable_slaves", master->_slaves_unreachable());
- // Model all of the registered slaves.
- writer->field("slaves",
- [this, &authorizeRole](JSON::ArrayWriter* writer) {
- foreachvalue (Slave* slave, master->slaves.registered) {
- writer->element(SlaveWriter(*slave, authorizeRole));
+ if (master->info().has_domain()) {
+ writer->field("domain", master->info().domain());
}
- });
- // Model all of the recovered slaves.
- writer->field("recovered_slaves", [this](JSON::ArrayWriter* writer) {
- foreachvalue (const SlaveInfo& slaveInfo, master->slaves.recovered) {
- writer->element([&slaveInfo](JSON::ObjectWriter* writer) {
- json(writer, slaveInfo);
- });
- }
- });
+ // TODO(haosdent): Deprecated this in favor of `leader_info` below.
+ if (master->leader.isSome()) {
+ writer->field("leader", master->leader->pid());
+ }
- // Model all of the frameworks.
- writer->field(
- "frameworks",
- [this,
- &authorizeFrameworkInfo,
- &authorizeTask,
- &authorizeExecutorInfo](JSON::ArrayWriter* writer) {
- foreachvalue (
- Framework* framework,
- master->frameworks.registered) {
- // Skip unauthorized frameworks.
- if (!authorizeFrameworkInfo->accept(framework->info)) {
- continue;
+ if (master->leader.isSome()) {
+ writer->field("leader_info", [this](JSON::ObjectWriter* writer) {
+ json(writer, master->leader.get());
+ });
}
- auto frameworkWriter = FullFrameworkWriter(
- authorizeTask,
- authorizeExecutorInfo,
- framework);
+ if (approvers->approved<VIEW_FLAGS>()) {
+ if (master->flags.cluster.isSome()) {
+ writer->field("cluster", master->flags.cluster.get());
+ }
- writer->element(frameworkWriter);
- }
- });
+ if (master->flags.log_dir.isSome()) {
+ writer->field("log_dir", master->flags.log_dir.get());
+ }
- // Model all of the completed frameworks.
- writer->field(
- "completed_frameworks",
- [this,
- &authorizeFrameworkInfo,
- &authorizeTask,
- &authorizeExecutorInfo](JSON::ArrayWriter* writer) {
- foreachvalue (const Owned<Framework>& framework,
- master->frameworks.completed) {
- // Skip unauthorized frameworks.
- if (!authorizeFrameworkInfo->accept(framework->info)) {
- continue;
- }
+ if (master->flags.external_log_file.isSome()) {
+ writer->field("external_log_file",
+ master->flags.external_log_file.get());
+ }
- auto frameworkWriter = FullFrameworkWriter(
- authorizeTask,
- authorizeExecutorInfo,
- framework.get());
+ writer->field("flags", [this](JSON::ObjectWriter* writer) {
+ foreachvalue (const flags::Flag& flag, master->flags) {
+ Option<string> value = flag.stringify(master->flags);
+ if (value.isSome()) {
+ writer->field(flag.effective_name().value, value.get());
+ }
+ }
+ });
+ }
- writer->element(frameworkWriter);
- }
- });
+ // Model all of the registered slaves.
+ writer->field(
+ "slaves",
+ [this, &approvers](JSON::ArrayWriter* writer) {
+ foreachvalue (Slave* slave, master->slaves.registered) {
+ writer->element(SlaveWriter(*slave, approvers));
+ }
+ });
+
+ // Model all of the recovered slaves.
+ writer->field(
+ "recovered_slaves",
+ [this](JSON::ArrayWriter* writer) {
+ foreachvalue (
+ const SlaveInfo& slaveInfo, master->slaves.recovered) {
+ writer->element([&slaveInfo](JSON::ObjectWriter* writer) {
+ json(writer, slaveInfo);
+ });
+ }
+ });
+
+ // Model all of the frameworks.
+ writer->field(
+ "frameworks",
+ [this, &approvers](JSON::ArrayWriter* writer) {
+ foreachvalue (
+ Framework* framework, master->frameworks.registered) {
+ // Skip unauthorized frameworks.
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info))
{
+ continue;
+ }
+
+ writer->element(FullFrameworkWriter(approvers, framework));
+ }
+ });
+
+ // Model all of the completed frameworks.
+ writer->field(
+ "completed_frameworks",
+ [this, &approvers](JSON::ArrayWriter* writer) {
+ foreachvalue (
+ const Owned<Framework>& framework,
+ master->frameworks.completed) {
+ // Skip unauthorized frameworks.
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info))
{
+ continue;
+ }
+
+ writer->element(
+ FullFrameworkWriter(approvers, framework.get()));
+ }
+ });
- // Orphan tasks are no longer possible. We emit an empty array
- // for the sake of backward compatibility.
- writer->field("orphan_tasks", [](JSON::ArrayWriter*) {});
+ // Orphan tasks are no longer possible. We emit an empty array
+ // for the sake of backward compatibility.
+ writer->field("orphan_tasks", [](JSON::ArrayWriter*) {});
- // Unregistered frameworks are no longer possible. We emit an
- // empty array for the sake of backward compatibility.
- writer->field("unregistered_frameworks", [](JSON::ArrayWriter*) {});
- };
+ // Unregistered frameworks are no longer possible. We emit an
+ // empty array for the sake of backward compatibility.
+ writer->field("unregistered_frameworks", [](JSON::ArrayWriter*)
{});
+ };
- return OK(jsonify(state), request.url.query.get("jsonp"));
- }));
+ return OK(jsonify(state), request.url.query.get("jsonp"));
+ }));
}
@@ -3318,156 +3097,153 @@ Future<Response> Master::Http::stateSummary(
return redirect(request);
}
- Future<Owned<AuthorizationAcceptor>> authorizeRole =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_ROLE);
- Future<Owned<AuthorizationAcceptor>> authorizeFrameworkInfo =
- AuthorizationAcceptor::create(
- principal, master->authorizer, authorization::VIEW_FRAMEWORK);
-
- return collect(authorizeRole, authorizeFrameworkInfo).then(defer(
- master->self(),
- [this, request](const tuple<Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>>& acceptors)
- -> Response {
- auto stateSummary = [this, &acceptors](JSON::ObjectWriter* writer) {
- Owned<AuthorizationAcceptor> authorizeRole;
- Owned<AuthorizationAcceptor> authorizeFrameworkInfo;
- tie(authorizeRole, authorizeFrameworkInfo) = acceptors;
-
- writer->field("hostname", master->info().hostname());
-
- if (master->flags.cluster.isSome()) {
- writer->field("cluster", master->flags.cluster.get());
- }
-
- // We use the tasks in the 'Frameworks' struct to compute summaries
- // for this endpoint. This is done 1) for consistency between the
- // 'slaves' and 'frameworks' subsections below 2) because we want to
- // provide summary information for frameworks that are currently
- // registered 3) the frameworks keep a circular buffer of completed
- // tasks that we can use to keep a limited view on the history of
- // recent completed / failed tasks.
-
- // Generate mappings from 'slave' to 'framework' and reverse.
- SlaveFrameworkMapping slaveFrameworkMapping(
- master->frameworks.registered);
-
- // Generate 'TaskState' summaries for all framework and slave ids.
- TaskStateSummaries taskStateSummaries(master->frameworks.registered);
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_ROLE, VIEW_FRAMEWORK})
+ .then(defer(
+ master->self(),
+ [this, request](const Owned<ObjectApprovers>& approvers) -> Response {
+ auto stateSummary = [this, &approvers](JSON::ObjectWriter* writer) {
+ writer->field("hostname", master->info().hostname());
- // Model all of the slaves.
- writer->field(
- "slaves",
- [this,
- &slaveFrameworkMapping,
- &taskStateSummaries,
- &authorizeRole](JSON::ArrayWriter* writer) {
- foreachvalue (Slave* slave, master->slaves.registered) {
- writer->element(
- [&slave,
- &slaveFrameworkMapping,
- &taskStateSummaries,
- &authorizeRole](JSON::ObjectWriter* writer) {
- SlaveWriter slaveWriter(*slave, authorizeRole);
- slaveWriter(writer);
-
- // Add the 'TaskState' summary for this slave.
- const TaskStateSummary& summary =
- taskStateSummaries.slave(slave->id);
-
- // Certain per-agent status totals will always be zero
- // (e.g., TASK_ERROR, TASK_UNREACHABLE). We report them
- // here anyway, for completeness.
- //
- // TODO(neilc): Update for TASK_GONE and
- // TASK_GONE_BY_OPERATOR.
- writer->field("TASK_STAGING", summary.staging);
- writer->field("TASK_STARTING", summary.starting);
- writer->field("TASK_RUNNING", summary.running);
- writer->field("TASK_KILLING", summary.killing);
- writer->field("TASK_FINISHED", summary.finished);
- writer->field("TASK_KILLED", summary.killed);
- writer->field("TASK_FAILED", summary.failed);
- writer->field("TASK_LOST", summary.lost);
- writer->field("TASK_ERROR", summary.error);
- writer->field("TASK_UNREACHABLE", summary.unreachable);
-
- // Add the ids of all the frameworks running on this
- // slave.
- const hashset<FrameworkID>& frameworks =
- slaveFrameworkMapping.frameworks(slave->id);
-
- writer->field(
- "framework_ids",
- [&frameworks](JSON::ArrayWriter* writer) {
- foreach (
- const FrameworkID& frameworkId,
- frameworks) {
- writer->element(frameworkId.value());
- }
- });
- });
- }
- });
+ if (master->flags.cluster.isSome()) {
+ writer->field("cluster", master->flags.cluster.get());
+ }
- // Model all of the frameworks.
- writer->field(
- "frameworks",
- [this,
- &slaveFrameworkMapping,
- &taskStateSummaries,
- &authorizeFrameworkInfo](JSON::ArrayWriter* writer) {
- foreachpair (const FrameworkID& frameworkId,
- Framework* framework,
- master->frameworks.registered) {
- // Skip unauthorized frameworks.
- if (!authorizeFrameworkInfo->accept(framework->info)) {
- continue;
+ // We use the tasks in the 'Frameworks' struct to compute summaries
+ // for this endpoint. This is done 1) for consistency between the
+ // 'slaves' and 'frameworks' subsections below 2) because we want
to
+ // provide summary information for frameworks that are currently
+ // registered 3) the frameworks keep a circular buffer of completed
+ // tasks that we can use to keep a limited view on the history of
+ // recent completed / failed tasks.
+
+ // Generate mappings from 'slave' to 'framework' and reverse.
+ SlaveFrameworkMapping slaveFrameworkMapping(
+ master->frameworks.registered);
+
+ // Generate 'TaskState' summaries for all framework and slave ids.
+ TaskStateSummaries taskStateSummaries(
+ master->frameworks.registered);
+
+ // Model all of the slaves.
+ writer->field(
+ "slaves",
+ [this,
+ &slaveFrameworkMapping,
+ &taskStateSummaries,
+ &approvers](JSON::ArrayWriter* writer) {
+ foreachvalue (Slave* slave, master->slaves.registered) {
+ writer->element(
+ [&slave,
+ &slaveFrameworkMapping,
+ &taskStateSummaries,
+ &approvers](JSON::ObjectWriter* writer) {
+ SlaveWriter slaveWriter(*slave, approvers);
+ slaveWriter(writer);
+
+ // Add the 'TaskState' summary for this slave.
+ const TaskStateSummary& summary =
+ taskStateSummaries.slave(slave->id);
+
+ // Certain per-agent status totals will always be
zero
+ // (e.g., TASK_ERROR, TASK_UNREACHABLE). We report
+ // them here anyway, for completeness.
+ //
+ // TODO(neilc): Update for TASK_GONE and
+ // TASK_GONE_BY_OPERATOR.
+ writer->field("TASK_STAGING", summary.staging);
+ writer->field("TASK_STARTING", summary.starting);
+ writer->field("TASK_RUNNING", summary.running);
+ writer->field("TASK_KILLING", summary.killing);
+ writer->field("TASK_FINISHED", summary.finished);
+ writer->field("TASK_KILLED", summary.killed);
+ writer->field("TASK_FAILED", summary.failed);
+ writer->field("TASK_LOST", summary.lost);
+ writer->field("TASK_ERROR", summary.error);
+ writer->field(
+ "TASK_UNREACHABLE",
+ summary.unreachable);
+
+ // Add the ids of all the frameworks running on this
+ // slave.
+ const hashset<FrameworkID>& frameworks =
+ slaveFrameworkMapping.frameworks(slave->id);
+
+ writer->field(
+ "framework_ids",
+ [&frameworks](JSON::ArrayWriter* writer) {
+ foreach (
+ const FrameworkID& frameworkId,
+ frameworks) {
+ writer->element(frameworkId.value());
+ }
+ });
+ });
}
+ });
+
+ // Model all of the frameworks.
+ writer->field(
+ "frameworks",
+ [this,
+ &slaveFrameworkMapping,
+ &taskStateSummaries,
+ &approvers](JSON::ArrayWriter* writer) {
+ foreachpair (const FrameworkID& frameworkId,
+ Framework* framework,
+ master->frameworks.registered) {
+ // Skip unauthorized frameworks.
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info))
{
+ continue;
+ }
+
+ writer->element(
+ [&frameworkId,
+ &framework,
+ &slaveFrameworkMapping,
+ &taskStateSummaries](JSON::ObjectWriter* writer) {
+ json(writer, Summary<Framework>(*framework));
+
+ // Add the 'TaskState' summary for this framework.
+ const TaskStateSummary& summary =
+ taskStateSummaries.framework(frameworkId);
+
+ // TODO(neilc): Update for TASK_GONE and
+ // TASK_GONE_BY_OPERATOR.
+ writer->field("TASK_STAGING", summary.staging);
+ writer->field("TASK_STARTING", summary.starting);
+ writer->field("TASK_RUNNING", summary.running);
+ writer->field("TASK_KILLING", summary.killing);
+ writer->field("TASK_FINISHED", summary.finished);
+ writer->field("TASK_KILLED", summary.killed);
+ writer->field("TASK_FAILED", summary.failed);
+ writer->field("TASK_LOST", summary.lost);
+ writer->field("TASK_ERROR", summary.error);
+ writer->field(
+ "TASK_UNREACHABLE",
+ summary.unreachable);
+
+ // Add the ids of all the slaves running
+ // this framework.
+ const hashset<SlaveID>& slaves =
+ slaveFrameworkMapping.slaves(frameworkId);
+
+ writer->field(
+ "slave_ids",
+ [&slaves](JSON::ArrayWriter* writer) {
+ foreach (const SlaveID& slaveId, slaves) {
+ writer->element(slaveId.value());
+ }
+ });
+ });
+ }
+ });
+ };
- writer->element(
- [&frameworkId,
- &framework,
- &slaveFrameworkMapping,
- &taskStateSummaries](JSON::ObjectWriter* writer) {
- json(writer, Summary<Framework>(*framework));
-
- // Add the 'TaskState' summary for this framework.
- const TaskStateSummary& summary =
- taskStateSummaries.framework(frameworkId);
-
- // TODO(neilc): Update for TASK_GONE and
- // TASK_GONE_BY_OPERATOR.
- writer->field("TASK_STAGING", summary.staging);
- writer->field("TASK_STARTING", summary.starting);
- writer->field("TASK_RUNNING", summary.running);
- writer->field("TASK_KILLING", summary.killing);
- writer->field("TASK_FINISHED", summary.finished);
- writer->field("TASK_KILLED", summary.killed);
- writer->field("TASK_FAILED", summary.failed);
- writer->field("TASK_LOST", summary.lost);
- writer->field("TASK_ERROR", summary.error);
- writer->field("TASK_UNREACHABLE", summary.unreachable);
-
- // Add the ids of all the slaves running this
framework.
- const hashset<SlaveID>& slaves =
- slaveFrameworkMapping.slaves(frameworkId);
-
- writer->field(
- "slave_ids",
- [&slaves](JSON::ArrayWriter* writer) {
- foreach (const SlaveID& slaveId, slaves) {
- writer->element(slaveId.value());
- }
- });
- });
- }
- });
- };
-
- return OK(jsonify(stateSummary), request.url.query.get("jsonp"));
- }));
+ return OK(jsonify(stateSummary), request.url.query.get("jsonp"));
+ }));
}
@@ -3540,21 +3316,9 @@ string Master::Http::ROLES_HELP()
Future<vector<string>> Master::Http::_roles(
const Option<Principal>& principal) const
{
- // Retrieve `ObjectApprover`s for authorizing roles.
- Future<Owned<ObjectApprover>> rolesApprover;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- rolesApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_ROLE);
- } else {
- rolesApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return rolesApprover
+ return ObjectApprovers::create(master->authorizer, principal, {VIEW_ROLE})
.then(defer(master->self(),
- [this](const Owned<ObjectApprover>& rolesApprover)
+ [this](const Owned<ObjectApprovers>& approvers)
-> vector<string> {
JSON::Object object;
@@ -3587,7 +3351,7 @@ Future<vector<string>> Master::Http::_roles(
filteredRoleList.reserve(roleList.size());
foreach (const string& role, roleList) {
- if (approveViewRole(rolesApprover, role)) {
+ if (approvers->approved<VIEW_ROLE>(role)) {
filteredRoleList.push_back(role);
}
}
@@ -4032,40 +3796,18 @@ Future<Response> Master::Http::tasks(
Option<string> order = request.url.query.get("order");
string _order = order.isSome() && (order.get() == "asc") ? "asc" : "des";
- Future<Owned<AuthorizationAcceptor>> authorizeFrameworkInfo =
- AuthorizationAcceptor::create(
- principal,
- master->authorizer,
- authorization::VIEW_FRAMEWORK);
- Future<Owned<AuthorizationAcceptor>> authorizeTask =
- AuthorizationAcceptor::create(
- principal,
- master->authorizer,
- authorization::VIEW_TASK);
- Future<IDAcceptor<FrameworkID>> selectFrameworkId =
- IDAcceptor<FrameworkID>(request.url.query.get("framework_id"));
- Future<IDAcceptor<TaskID>> selectTaskId =
- IDAcceptor<TaskID>(request.url.query.get("task_id"));
-
- return collect(
- authorizeFrameworkInfo,
- authorizeTask,
- selectFrameworkId,
- selectTaskId)
+ Option<string> frameworkId = request.url.query.get("framework_id");
+ Option<string> taskId = request.url.query.get("task_id");
+
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK, VIEW_TASK})
.then(defer(
master->self(),
- [=](const tuple<Owned<AuthorizationAcceptor>,
- Owned<AuthorizationAcceptor>,
- IDAcceptor<FrameworkID>,
- IDAcceptor<TaskID>>& acceptors)-> Future<Response> {
- Owned<AuthorizationAcceptor> authorizeFrameworkInfo;
- Owned<AuthorizationAcceptor> authorizeTask;
- IDAcceptor<FrameworkID> selectFrameworkId;
- IDAcceptor<TaskID> selectTaskId;
- tie(authorizeFrameworkInfo,
- authorizeTask,
- selectFrameworkId,
- selectTaskId) = acceptors;
+ [=](const Owned<ObjectApprovers>& approvers) -> Response {
+ IDAcceptor<FrameworkID> selectFrameworkId(frameworkId);
+ IDAcceptor<TaskID> selectTaskId(taskId);
// Construct framework list with both active and completed
frameworks.
vector<const Framework*> frameworks;
@@ -4073,7 +3815,7 @@ Future<Response> Master::Http::tasks(
// Skip unauthorized frameworks or frameworks without matching
// framework ID.
if (!selectFrameworkId.accept(framework->id()) ||
- !authorizeFrameworkInfo->accept(framework->info)) {
+ !approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -4085,7 +3827,7 @@ Future<Response> Master::Http::tasks(
// Skip unauthorized frameworks or frameworks without matching
// framework ID.
if (!selectFrameworkId.accept(framework->id()) ||
- !authorizeFrameworkInfo->accept(framework->info)) {
+ !approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -4100,7 +3842,7 @@ Future<Response> Master::Http::tasks(
CHECK_NOTNULL(task);
// Skip unauthorized tasks or tasks without matching task ID.
if (!selectTaskId.accept(task->task_id()) ||
- !authorizeTask->accept(*task, framework->info)) {
+ !approvers->approved<VIEW_TASK>(*task, framework->info)) {
continue;
}
@@ -4112,7 +3854,7 @@ Future<Response> Master::Http::tasks(
framework->unreachableTasks) {
// Skip unauthorized tasks or tasks without matching task ID.
if (!selectTaskId.accept(task->task_id()) ||
- !authorizeTask->accept(*task, framework->info)) {
+ !approvers->approved<VIEW_TASK>(*task, framework->info)) {
continue;
}
@@ -4122,7 +3864,7 @@ Future<Response> Master::Http::tasks(
foreach (const Owned<Task>& task, framework->completedTasks) {
// Skip unauthorized tasks or tasks without matching task ID.
if (!selectTaskId.accept(task->task_id()) ||
- !authorizeTask->accept(*task, framework->info)) {
+ !approvers->approved<VIEW_TASK>(*task, framework->info)) {
continue;
}
@@ -4141,14 +3883,15 @@ Future<Response> Master::Http::tasks(
auto tasksWriter =
[&tasks, limit, offset](JSON::ObjectWriter* writer) {
- writer->field("tasks",
- [&tasks, limit, offset](JSON::ArrayWriter* writer) {
- // Collect 'limit' number of tasks starting from 'offset'.
- size_t end = std::min(offset + limit, tasks.size());
- for (size_t i = offset; i < end; i++) {
- writer->element(*tasks[i]);
- }
- });
+ writer->field(
+ "tasks",
+ [&tasks, limit, offset](JSON::ArrayWriter* writer) {
+ // Collect 'limit' number of tasks starting from 'offset'.
+ size_t end = std::min(offset + limit, tasks.size());
+ for (size_t i = offset; i < end; i++) {
+ writer->element(*tasks[i]);
+ }
+ });
};
return OK(jsonify(tasksWriter), request.url.query.get("jsonp"));
@@ -4163,54 +3906,32 @@ Future<Response> Master::Http::getTasks(
{
CHECK_EQ(mesos::master::Call::GET_TASKS, call.type());
- // Retrieve Approvers for authorizing frameworks and tasks.
- Future<Owned<ObjectApprover>> frameworksApprover;
- Future<Owned<ObjectApprover>> tasksApprover;
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- frameworksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_FRAMEWORK);
-
- tasksApprover = master->authorizer.get()->getObjectApprover(
- subject, authorization::VIEW_TASK);
- } else {
- frameworksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- tasksApprover = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return collect(frameworksApprover, tasksApprover)
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {VIEW_FRAMEWORK, VIEW_TASK})
.then(defer(
master->self(),
- [=](const tuple<Owned<ObjectApprover>,
- Owned<ObjectApprover>>& approvers)
- -> Future<Response> {
- // Get approver from tuple.
- Owned<ObjectApprover> frameworksApprover;
- Owned<ObjectApprover> tasksApprover;
- tie(frameworksApprover, tasksApprover) = approvers;
-
- mesos::master::Response response;
- response.set_type(mesos::master::Response::GET_TASKS);
+ [=](const Owned<ObjectApprovers>& approvers) -> Response {
+ mesos::master::Response response;
+ response.set_type(mesos::master::Response::GET_TASKS);
- *response.mutable_get_tasks() =
- _getTasks(frameworksApprover, tasksApprover);
+ *response.mutable_get_tasks() = _getTasks(approvers);
- return OK(serialize(contentType, evolve(response)),
- stringify(contentType));
+ return OK(
+ serialize(contentType, evolve(response)),
stringify(contentType));
}));
}
mesos::master::Response::GetTasks Master::Http::_getTasks(
- const Owned<ObjectApprover>& frameworksApprover,
- const Owned<ObjectApprover>& tasksApprover) const
+ const Owned<ObjectApprovers>& approvers) const
{
// Construct framework list with both active and completed frameworks.
vector<const Framework*> frameworks;
foreachvalue (Framework* framework, master->frameworks.registered) {
// Skip unauthorized frameworks.
- if (!approveViewFrameworkInfo(frameworksApprover, framework->info)) {
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -4220,7 +3941,7 @@ mesos::master::Response::GetTasks Master::Http::_getTasks(
foreachvalue (const Owned<Framework>& framework,
master->frameworks.completed) {
// Skip unauthorized frameworks.
- if (!approveViewFrameworkInfo(frameworksApprover, framework->info)) {
+ if (!approvers->approved<VIEW_FRAMEWORK>(framework->info)) {
continue;
}
@@ -4234,7 +3955,7 @@ mesos::master::Response::GetTasks Master::Http::_getTasks(
// Pending tasks.
foreachvalue (const TaskInfo& taskInfo, framework->pendingTasks) {
// Skip unauthorized tasks.
- if (!approveViewTaskInfo(tasksApprover, taskInfo, framework->info)) {
+ if (!approvers->approved<VIEW_TASK>(taskInfo, framework->info)) {
continue;
}
@@ -4246,7 +3967,7 @@ mesos::master::Response::GetTasks Master::Http::_getTasks(
foreachvalue (Task* task, framework->tasks) {
CHECK_NOTNULL(task);
// Skip unauthorized tasks.
- if (!approveViewTask(tasksApprover, *task, framework->info)) {
+ if (!approvers->approved<VIEW_TASK>(*task, framework->info)) {
continue;
}
@@ -4256,7 +3977,7 @@ mesos::master::Response::GetTasks Master::Http::_getTasks(
// Unreachable tasks.
foreachvalue (const Owned<Task>& task, framework->unreachableTasks) {
// Skip unauthorized tasks.
- if (!approveViewTask(tasksApprover, *task, framework->info)) {
+ if (!approvers->approved<VIEW_TASK>(*task, framework->info)) {
continue;
}
@@ -4266,7 +3987,7 @@ mesos::master::Response::GetTasks Master::Http::_getTasks(
// Completed tasks.
foreach (const Owned<Task>& task, framework->completedTasks) {
// Skip unauthorized tasks.
- if (!approveViewTask(tasksApprover, *task, framework->info)) {
+ if (!approvers->approved<VIEW_TASK>(*task, framework->info)) {
continue;
}
@@ -4327,25 +4048,17 @@ Future<Response> Master::Http::maintenanceSchedule(
// JSON-ify and return the current maintenance schedule.
if (request.method == "GET") {
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::GET_MAINTENANCE_SCHEDULE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
Option<string> jsonp = request.url.query.get("jsonp");
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {GET_MAINTENANCE_SCHEDULE})
+ .then(defer(
master->self(),
- [this, jsonp](
- const Owned<ObjectApprover>& approver) -> Future<Response> {
+ [this, jsonp](const Owned<ObjectApprovers>& approvers) -> Response {
const mesos::maintenance::Schedule schedule =
- _getMaintenanceSchedule(approver);
+ _getMaintenanceSchedule(approvers);
return OK(JSON::protobuf(schedule), jsonp);
}));
}
@@ -4369,7 +4082,7 @@ Future<Response> Master::Http::maintenanceSchedule(
mesos::maintenance::Schedule Master::Http::_getMaintenanceSchedule(
- const Owned<ObjectApprover>& approver) const
+ const Owned<ObjectApprovers>& approvers) const
{
// TODO(josephw): Return more than one schedule.
if (master->maintenance.schedules.empty()) {
@@ -4383,17 +4096,7 @@ mesos::maintenance::Schedule
Master::Http::_getMaintenanceSchedule(
mesos::maintenance::Window window_;
foreach (const MachineID& machine_id, window.machine_ids()) {
- Try<bool> approved =
- approver->approved(ObjectApprover::Object(machine_id));
-
- if (approved.isError()) {
- LOG(WARNING) << "Error during MachineID authorization: "
- << approved.error();
- // TODO(arojas): Consider exposing these errors to the caller.
- continue;
- }
-
- if (!approved.get()) {
+ if (!approvers->approved<GET_MAINTENANCE_SCHEDULE>(machine_id)) {
continue;
}
@@ -4424,35 +4127,24 @@ Future<Response>
Master::Http::_updateMaintenanceSchedule(
return BadRequest(isValid.error());
}
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::UPDATE_MAINTENANCE_SCHEDULE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {UPDATE_MAINTENANCE_SCHEDULE})
+ .then(defer(
master->self(),
- [this, schedule](const Owned<ObjectApprover>& approver) {
- return __updateMaintenanceSchedule(schedule, approver);
+ [this, schedule](const Owned<ObjectApprovers>& approvers) {
+ return __updateMaintenanceSchedule(schedule, approvers);
}));
}
Future<Response> Master::Http::__updateMaintenanceSchedule(
const mesos::maintenance::Schedule& schedule,
- const Owned<ObjectApprover>& approver) const
+ const Owned<ObjectApprovers>& approvers) const
{
foreach (const mesos::maintenance::Window& window, schedule.windows()) {
foreach (const MachineID& machine, window.machine_ids()) {
- Try<bool> approved = approver->approved(ObjectApprover::Object(machine));
-
- if (approved.isError()) {
- return InternalServerError("Authorization error: " + approved.error());
- } else if (!approved.get()) {
+ if (!approvers->approved<UPDATE_MAINTENANCE_SCHEDULE>(machine)) {
return Forbidden();
}
}
@@ -4549,27 +4241,19 @@ Future<Response> Master::Http::getMaintenanceSchedule(
{
CHECK_EQ(mesos::master::Call::GET_MAINTENANCE_SCHEDULE, call.type());
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::GET_MAINTENANCE_SCHEDULE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {GET_MAINTENANCE_SCHEDULE})
+ .then(defer(
master->self(),
- [this, contentType](
- const Owned<ObjectApprover>& approver) -> Future<Response> {
+ [this, contentType](const Owned<ObjectApprovers>& approvers) -> Response
{
mesos::master::Response response;
response.set_type(mesos::master::Response::GET_MAINTENANCE_SCHEDULE);
*response.mutable_get_maintenance_schedule()->mutable_schedule() =
- _getMaintenanceSchedule(approver);
+ _getMaintenanceSchedule(approvers);
return OK(serialize(contentType, evolve(response)),
stringify(contentType));
@@ -4643,28 +4327,21 @@ Future<Response> Master::Http::machineDown(
return BadRequest(ids.error());
}
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::START_MAINTENANCE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {START_MAINTENANCE})
+ .then(defer(
master->self(),
- [this, ids](const Owned<ObjectApprover>& approver) {
- return _startMaintenance(ids.get(), approver);
+ [this, ids](const Owned<ObjectApprovers>& approvers) {
+ return _startMaintenance(ids.get(), approvers);
}));
}
Future<Response> Master::Http::_startMaintenance(
const RepeatedPtrField<MachineID>& machineIds,
- const Owned<ObjectApprover>& approver) const
+ const Owned<ObjectApprovers>& approvers) const
{
// Validate every machine in the list.
Try<Nothing> isValid = maintenance::validation::machines(machineIds);
@@ -4687,18 +4364,14 @@ Future<Response> Master::Http::_startMaintenance(
"' is not in DRAINING mode and cannot be brought down");
}
- Try<bool> approved = approver->approved(ObjectApprover::Object(id));
-
- if (approved.isError()) {
- return InternalServerError("Authorization error: " + approved.error());
- } else if (!approved.get()) {
+ if (!approvers->approved<START_MAINTENANCE>(id)) {
return Forbidden();
}
}
return master->registrar->apply(Owned<RegistryOperation>(
new maintenance::StartMaintenance(machineIds)))
- .then(defer(master->self(), [=](bool result) -> Future<Response> {
+ .then(defer(master->self(), [=](bool result) -> Response {
// See the top comment in "master/maintenance.hpp" for why this check
// is here, and is appropriate.
CHECK(result);
@@ -4752,23 +4425,16 @@ Future<Response> Master::Http::startMaintenance(
CHECK_EQ(mesos::master::Call::START_MAINTENANCE, call.type());
CHECK(call.has_start_maintenance());
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::START_MAINTENANCE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
RepeatedPtrField<MachineID> machineIds = call.start_maintenance().machines();
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {START_MAINTENANCE})
+ .then(defer(
master->self(),
- [this, machineIds](const Owned<ObjectApprover>& approver) {
- return _startMaintenance(machineIds, approver);
+ [this, machineIds](const Owned<ObjectApprovers>& approvers) {
+ return _startMaintenance(machineIds, approvers);
}));
}
@@ -4824,28 +4490,21 @@ Future<Response> Master::Http::machineUp(
return BadRequest(ids.error());
}
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::STOP_MAINTENANCE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {STOP_MAINTENANCE})
+ .then(defer(
master->self(),
- [this, ids](const Owned<ObjectApprover>& approver) {
- return _stopMaintenance(ids.get(), approver);
+ [this, ids](const Owned<ObjectApprovers>& approvers) {
+ return _stopMaintenance(ids.get(), approvers);
}));
}
Future<Response> Master::Http::_stopMaintenance(
const RepeatedPtrField<MachineID>& machineIds,
- const Owned<ObjectApprover>& approver) const
+ const Owned<ObjectApprovers>& approvers) const
{
// Validate every machine in the list.
Try<Nothing> isValid = maintenance::validation::machines(machineIds);
@@ -4867,11 +4526,7 @@ Future<Response> Master::Http::_stopMaintenance(
"' is not in DOWN mode and cannot be brought up");
}
- Try<bool> approved = approver->approved(ObjectApprover::Object(id));
-
- if (approved.isError()) {
- return InternalServerError("Authorization error: " + approved.error());
- } else if (!approved.get()) {
+ if (!approvers->approved<STOP_MAINTENANCE>(id)) {
return Forbidden();
}
}
@@ -4934,22 +4589,14 @@ Future<Response> Master::Http::stopMaintenance(
RepeatedPtrField<MachineID> machineIds = call.stop_maintenance().machines();
-
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::STOP_MAINTENANCE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver.then(defer(
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {STOP_MAINTENANCE})
+ .then(defer(
master->self(),
- [this, machineIds](const Owned<ObjectApprover>& approver) {
- return _stopMaintenance(machineIds, approver);
+ [this, machineIds](const Owned<ObjectApprovers>& approvers) {
+ return _stopMaintenance(machineIds, approvers);
}));
}
@@ -4997,24 +4644,16 @@ Future<Response> Master::Http::maintenanceStatus(
return MethodNotAllowed({"GET"}, request.method);
}
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::GET_MAINTENANCE_STATUS);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
Option<string> jsonp = request.url.query.get("jsonp");
- return approver
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {GET_MAINTENANCE_STATUS})
.then(defer(
master->self(),
- [this](const Owned<ObjectApprover>& approver) {
- return _getMaintenanceStatus(approver);
+ [this](const Owned<ObjectApprovers>& approvers) {
+ return _getMaintenanceStatus(approvers);
}))
.then([jsonp](const mesos::maintenance::ClusterStatus& status) -> Response
{
return OK(JSON::protobuf(status), jsonp);
@@ -5023,7 +4662,7 @@ Future<Response> Master::Http::maintenanceStatus(
Future<mesos::maintenance::ClusterStatus> Master::Http::_getMaintenanceStatus(
- const Owned<ObjectApprover>& approver) const
+ const Owned<ObjectApprovers>& approvers) const
{
return master->allocator->getInverseOfferStatuses()
.then(defer(
@@ -5040,16 +4679,7 @@ Future<mesos::maintenance::ClusterStatus>
Master::Http::_getMaintenanceStatus(
const MachineID& id,
const Machine& machine,
master->machines) {
- Try<bool> approved = approver->approved(ObjectApprover::Object(id));
-
- if (approved.isError()) {
- LOG(WARNING) << "Error during MachineID authorization: "
- << approved.error();
- // TODO(arojas): Consider exposing these errors to the caller.
- continue;
- }
-
- if (!approved.get()) {
+ if (!approvers->approved<GET_MAINTENANCE_STATUS>(id)) {
continue;
}
@@ -5098,22 +4728,14 @@ Future<Response> Master::Http::getMaintenanceStatus(
{
CHECK_EQ(mesos::master::Call::GET_MAINTENANCE_STATUS, call.type());
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::GET_MAINTENANCE_STATUS);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
- return approver
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {GET_MAINTENANCE_STATUS})
.then(defer(
master->self(),
- [this](const Owned<ObjectApprover>& approver) {
- return _getMaintenanceStatus(approver);
+ [this](const Owned<ObjectApprovers>& approvers) {
+ return _getMaintenanceStatus(approvers);
}))
.then([contentType](const mesos::maintenance::ClusterStatus& status)
-> Response {
@@ -5354,32 +4976,22 @@ Future<Response> Master::Http::markAgentGone(
{
CHECK_EQ(mesos::master::Call::MARK_AGENT_GONE, call.type());
- Future<Owned<ObjectApprover>> approver;
-
- if (master->authorizer.isSome()) {
- Option<authorization::Subject> subject = createSubject(principal);
-
- approver = master->authorizer.get()->getObjectApprover(
- subject, authorization::MARK_AGENT_GONE);
- } else {
- approver = Owned<ObjectApprover>(new AcceptingObjectApprover());
- }
-
const SlaveID& slaveId = call.mark_agent_gone().slave_id();
- return approver.then(defer(master->self(),
- [this, slaveId](const Owned<ObjectApprover>& approver)
+ return ObjectApprovers::create(
+ master->authorizer,
+ principal,
+ {MARK_AGENT_GONE})
+ .then(defer(
+ master->self(),
+ [this, slaveId](const Owned<ObjectApprovers>& approvers)
-> Future<Response> {
- Try<bool> approved = approver->approved((ObjectApprover::Object()));
-
- if (approved.isError()) {
- return InternalServerError("Authorization error: " + approved.error());
- } else if (!approved.get()) {
- return Forbidden();
- }
+ if (!approvers->approved<MARK_AGENT_GONE>()) {
+ return Forbidden();
+ }
- return _markAgentGone(slaveId);
- }));
+ return _markAgentGone(slaveId);
+ }));
}