You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ti...@apache.org on 2016/01/06 18:32:06 UTC
[3/5] mesos git commit: Quota: Implemented quota remove authorization.
Quota: Implemented quota remove authorization.
Review: https://reviews.apache.org/r/41548/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4fe7880a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4fe7880a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4fe7880a
Branch: refs/heads/master
Commit: 4fe7880a44646f6659f6c0e9a013735cb6071e5d
Parents: 6998047
Author: Jan Schlicht <ja...@mesosphere.io>
Authored: Wed Jan 6 18:20:11 2016 +0100
Committer: Till Toenshoff <to...@me.com>
Committed: Wed Jan 6 18:20:11 2016 +0100
----------------------------------------------------------------------
include/mesos/quota/quota.proto | 3 ++
src/master/master.hpp | 9 ++++-
src/master/quota_handler.cpp | 74 +++++++++++++++++++++++++++++++-----
3 files changed, 75 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/4fe7880a/include/mesos/quota/quota.proto
----------------------------------------------------------------------
diff --git a/include/mesos/quota/quota.proto b/include/mesos/quota/quota.proto
index ab505b1..338412e 100644
--- a/include/mesos/quota/quota.proto
+++ b/include/mesos/quota/quota.proto
@@ -38,6 +38,9 @@ message QuotaInfo {
// dynamic reservations.
optional string role = 1;
+ // Principal which set the quota. Currently only operators can set quotas.
+ optional string principal = 2;
+
// Resources which are guaranteed to be allocatable by role.
// NOTE: `guarantee.role` should not specify any role except '*',
// because quota does not reserve specific resources.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4fe7880a/src/master/master.hpp
----------------------------------------------------------------------
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 2936d32..f764915 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -997,14 +997,21 @@ private:
// (including rescinding) is moved to allocator.
void rescindOffers(const mesos::quota::QuotaInfo& request) const;
- process::Future<bool> authorize(
+ process::Future<bool> authorizeSetQuota(
const Option<std::string>& principal,
const std::string& role) const;
+ process::Future<bool> authorizeRemoveQuota(
+ const Option<std::string>& requestPrincipal,
+ const Option<std::string>& quotaPrincipal) const;
+
process::Future<process::http::Response> _set(
const mesos::quota::QuotaInfo& quota,
bool forced) const;
+ process::Future<process::http::Response> _remove(
+ const std::string& role) const;
+
// To perform actions related to quota management, we require access to the
// master data structures. No synchronization primitives are needed here
// since `QuotaHandler`'s functions are invoked in the Master's actor.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4fe7880a/src/master/quota_handler.cpp
----------------------------------------------------------------------
diff --git a/src/master/quota_handler.cpp b/src/master/quota_handler.cpp
index ac4da74..93960f3 100644
--- a/src/master/quota_handler.cpp
+++ b/src/master/quota_handler.cpp
@@ -299,7 +299,7 @@ Future<http::Response> Master::QuotaHandler::set(
request.body + "': " + create.error());
}
- const QuotaInfo& quotaInfo = create.get();
+ QuotaInfo quotaInfo = create.get();
// Check that the `QuotaInfo` is a valid quota request.
Try<Nothing> validate = quota::validation::quotaInfo(quotaInfo);
@@ -335,13 +335,16 @@ Future<http::Response> Master::QuotaHandler::set(
request.body + "': " + force.error());
}
- const bool forced = force.isSome() ? force.get().value : false;
-
// Extract principal from request credentials.
- Option<string> principal =
- credential.isSome() ? credential.get().principal() : Option<string>::none();
+ Option<string> principal = None();
+ if (credential.isSome()) {
+ principal = credential.get().principal();
+ quotaInfo.set_principal(principal.get());
+ }
- return authorize(principal, quotaInfo.role())
+ const bool forced = force.isSome() ? force.get().value : false;
+
+ return authorizeSetQuota(principal, quotaInfo.role())
.then(defer(master->self(), [=](bool authorized) -> Future<http::Response> {
if (!authorized) {
return Unauthorized("Mesos master");
@@ -406,14 +409,12 @@ Future<http::Response> Master::QuotaHandler::remove(
{
VLOG(1) << "Removing quota for request path: '" << request.url.path << "'";
- // Authenticate the request.
+ // Authenticate the request.
Result<Credential> credential = master->http.authenticate(request);
if (credential.isError()) {
return Unauthorized("Mesos master", credential.error());
}
- // TODO(nfnt): Authorize the request.
-
// Check that the request type is DELETE which is guaranteed by the master.
CHECK_EQ("DELETE", request.method);
@@ -451,6 +452,27 @@ Future<http::Response> Master::QuotaHandler::remove(
"': Role '" + role + "' has no quota set");
}
+ // Extract principal from request credentials.
+ Option<string> principal =
+ credential.isSome() ? credential.get().principal() : Option<string>::none();
+
+ Option<string> quota_principal = master->quotas[role].info.has_principal()
+ ? master->quotas[role].info.principal()
+ : Option<string>::none();
+
+ return authorizeRemoveQuota(principal, quota_principal)
+ .then(defer(master->self(), [=](bool authorized) -> Future<http::Response> {
+ if (!authorized) {
+ return Unauthorized("Mesos master");
+ }
+
+ return _remove(role);
+ }));
+}
+
+
+Future<http::Response> Master::QuotaHandler::_remove(const string& role) const
+{
// Remove quota from the quota-related local state. We do this before
// updating the registry in order to make sure that we are not already
// trying to remove quota for this role (since this is a multi-phase event).
@@ -493,7 +515,7 @@ Future<http::Response> Master::QuotaHandler::status(
}
-Future<bool> Master::QuotaHandler::authorize(
+Future<bool> Master::QuotaHandler::authorizeSetQuota(
const Option<string>& principal,
const string& role) const
{
@@ -518,6 +540,38 @@ Future<bool> Master::QuotaHandler::authorize(
return master->authorizer.get()->authorize(request);
}
+
+Future<bool> Master::QuotaHandler::authorizeRemoveQuota(
+ const Option<string>& requestPrincipal,
+ const Option<string>& quotaPrincipal) const
+{
+ if (master->authorizer.isNone()) {
+ return true;
+ }
+
+ LOG(INFO) << "Authorizing principal '"
+ << (requestPrincipal.isSome() ? requestPrincipal.get() : "ANY")
+ << "' to remove quota set by '"
+ << (quotaPrincipal.isSome() ? quotaPrincipal.get() : "ANY")
+ << "'";
+
+ mesos::ACL::RemoveQuota request;
+
+ if (requestPrincipal.isSome()) {
+ request.mutable_principals()->add_values(requestPrincipal.get());
+ } else {
+ request.mutable_principals()->set_type(mesos::ACL::Entity::ANY);
+ }
+
+ if (quotaPrincipal.isSome()) {
+ request.mutable_quota_principals()->add_values(quotaPrincipal.get());
+ } else {
+ request.mutable_quota_principals()->set_type(mesos::ACL::Entity::ANY);
+ }
+
+ return master->authorizer.get()->authorize(request);
+}
+
} // namespace master {
} // namespace internal {
} // namespace mesos {