This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new fb97080  Moved creating authz Object out of 
Master::authorizeResizeVolume.
fb97080 is described below

commit fb97080ba53e6387779c37b18a42c8375969493c
Author: Andrei Sekretenko <[email protected]>
AuthorDate: Tue Jan 7 12:10:31 2020 -0500

    Moved creating authz Object out of Master::authorizeResizeVolume.
    
    Review: https://reviews.apache.org/r/71861/
---
 src/master/authorization.cpp | 55 ++++++++++++++++++++++++++++++++++++++
 src/master/authorization.hpp | 25 ++++++++++++++++++
 src/master/http.cpp          | 10 ++++---
 src/master/master.cpp        | 63 +++-----------------------------------------
 src/master/master.hpp        | 22 ----------------
 5 files changed, 90 insertions(+), 85 deletions(-)

diff --git a/src/master/authorization.cpp b/src/master/authorization.cpp
index 9fde2ad..928deaf 100644
--- a/src/master/authorization.cpp
+++ b/src/master/authorization.cpp
@@ -20,12 +20,26 @@
 #include "master/authorization.hpp"
 
 using std::ostream;
+using std::string;
 
 
 namespace mesos {
 namespace authorization {
 
 
+ActionObject ActionObject::fromResourceWithLegacyValue(
+    const Action action,
+    const Resource& resource,
+    string value)
+{
+  Object object;
+  *object.mutable_resource() = resource;
+  *object.mutable_value() = std::move(value);
+
+  return ActionObject(action, std::move(object));
+}
+
+
 ActionObject ActionObject::taskLaunch(
     const TaskInfo& task,
     const FrameworkInfo& framework)
@@ -61,6 +75,47 @@ ActionObject ActionObject::frameworkRegistration(
 }
 
 
+// Returns effective reservation role of resource for the purpose
+// of authorizing an operation; that is, the the role of the most
+// refined reservation if the resource is reserved.
+//
+// NOTE: If the resource is not reserved, the default role '*' is
+// returned; this is needed to handle authorization of invalid
+// operations and could be avoided if we were able to guarantee
+// that authorization Objects for invalid operations are never built
+// (see MESOS-10083).
+//
+// NOTE: If the resource is not in the post-reservation-refinement
+// format, this function will crash the program.
+string getReservationRole(const Resource& resource)
+{
+  CHECK(!resource.has_role()) << resource;
+  CHECK(!resource.has_reservation()) << resource;
+
+  return Resources::isReserved(resource)
+    ? Resources::reservationRole(resource) : "*";
+}
+
+
+ActionObject ActionObject::growVolume(const Offer::Operation::GrowVolume& grow)
+{
+  return fromResourceWithLegacyValue(
+      authorization::RESIZE_VOLUME,
+      grow.volume(),
+      getReservationRole(grow.volume()));
+}
+
+
+ActionObject ActionObject::shrinkVolume(
+    const Offer::Operation::ShrinkVolume& shrink)
+{
+  return fromResourceWithLegacyValue(
+      authorization::RESIZE_VOLUME,
+      shrink.volume(),
+      getReservationRole(shrink.volume()));
+}
+
+
 ostream& operator<<(ostream& stream, const ActionObject& actionObject)
 {
   const Option<Object>& object = actionObject.object();
diff --git a/src/master/authorization.hpp b/src/master/authorization.hpp
index 54c30f8..3e79f65 100644
--- a/src/master/authorization.hpp
+++ b/src/master/authorization.hpp
@@ -18,6 +18,7 @@
 #define __MASTER_AUTHORIZATION_HPP__
 
 #include <ostream>
+#include <string>
 
 #include <stout/option.hpp>
 
@@ -46,12 +47,36 @@ public:
   static ActionObject frameworkRegistration(
       const FrameworkInfo& frameworkInfo);
 
+  // Methods that return action-object pair(s) for authorizing
+  // offer operations other than LAUNCH/LAUNCH_GROUP.
+  //
+  // NOTE: these methods rely on the caller to ensure that operation
+  // resources are in post-reservation-refinement format.
+  // Otherwise, they  may crash the program.
+
+  static ActionObject growVolume(
+      const Offer::Operation::GrowVolume& grow);
+
+  static ActionObject shrinkVolume(
+      const Offer::Operation::ShrinkVolume& shrink);
+
 private:
   Action action_;
   Option<Object> object_;
 
   ActionObject(Action action, Option<Object>&& object)
     : action_(action), object_(object){};
+
+  // Returns an action-object pair for the case that commonly
+  // occurs when authorizing non-LAUNCH operations: sets `action`,
+  // `object.resource` and `object.value`.
+  //
+  // NOTE: the deprecated `object.value` field is set to support legacy
+  // authorizers that have not been upgraded to look at `object.resource`.
+  static ActionObject fromResourceWithLegacyValue(
+      Action action,
+      const Resource& resource,
+      std::string value_);
 };
 
 // Outputs human-readable description of an ActionObject.
diff --git a/src/master/http.cpp b/src/master/http.cpp
index 72587bf..94084dd 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -83,6 +83,7 @@
 
 #include "logging/logging.hpp"
 
+#include "master/authorization.hpp"
 #include "master/machine.hpp"
 #include "master/maintenance.hpp"
 #include "master/master.hpp"
@@ -137,6 +138,7 @@ using std::tie;
 using std::tuple;
 using std::vector;
 
+using mesos::authorization::ActionObject;
 using mesos::authorization::createSubject;
 using mesos::authorization::DEACTIVATE_AGENT;
 using mesos::authorization::DRAIN_AGENT;
@@ -1262,8 +1264,8 @@ Future<Response> Master::Http::growVolume(
         stringify(*slave) + ": " + error->message);
   }
 
-  return master->authorizeResizeVolume(
-      operation.grow_volume().volume(), principal)
+  return master->authorize(
+      principal, ActionObject::growVolume(operation.grow_volume()))
     .then(defer(master->self(), [=](bool authorized) -> Future<Response> {
       if (!authorized) {
         return Forbidden();
@@ -1325,8 +1327,8 @@ Future<Response> Master::Http::shrinkVolume(
         stringify(*slave) + ": " + error->message);
   }
 
-  return master->authorizeResizeVolume(
-      operation.shrink_volume().volume(), principal)
+  return master->authorize(
+      principal, ActionObject::shrinkVolume(operation.shrink_volume()))
     .then(defer(master->self(), [=](bool authorized) -> Future<Response> {
       if (!authorized) {
         return Forbidden();
diff --git a/src/master/master.cpp b/src/master/master.cpp
index ff76831..e2f16f4 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -4014,51 +4014,6 @@ Future<bool> Master::authorizeDestroyVolume(
 }
 
 
-Future<bool> Master::authorizeResizeVolume(
-    const Resource& volume,
-    const Option<Principal>& principal)
-{
-  if (authorizer.isNone()) {
-    return true; // Authorization is disabled.
-  }
-
-  authorization::Request request;
-  request.set_action(authorization::RESIZE_VOLUME);
-
-  Option<authorization::Subject> subject = createSubject(principal);
-  if (subject.isSome()) {
-    request.mutable_subject()->CopyFrom(subject.get());
-  }
-
-  request.mutable_object()->mutable_resource()->CopyFrom(volume);
-
-  // We also set the deprecated `object.value` field to support legacy
-  // authorizers that have not been upgraded to look at `object.resource`.
-  //
-  // NOTE: We rely on the master to ensure that the resource is in the
-  // post-reservation-refinement format. If there is a stack of reservations,
-  // we perform authorization for the role of the most refined reservation,
-  // since we only support "pushing" one reservation at a time. That is, all
-  // of the previous reservations must have already been authorized.
-  //
-  // NOTE: Since authorization happens __before__ validation, we must check 
here
-  // that this resource has a reservation. If not, the error will be caught
-  // during validation, but we still authorize the resource with the default
-  // role '*' for backward compatibility.
-  CHECK(!volume.has_role()) << volume;
-  CHECK(!volume.has_reservation()) << volume;
-
-  request.mutable_object()->set_value(
-      Resources::isReserved(volume) ? Resources::reservationRole(volume) : 
"*");
-
-  LOG(INFO) << "Authorizing principal '"
-            << (principal.isSome() ? stringify(principal.get()) : "ANY")
-            << "' to resize volume '" << volume << "'";
-
-  return authorizer.get()->authorized(request);
-}
-
-
 Future<bool> Master::authorizeCreateDisk(
     const Offer::Operation::CreateDisk& createDisk,
     const Option<Principal>& principal)
@@ -4885,25 +4840,15 @@ void Master::accept(
       }
 
       case Offer::Operation::GROW_VOLUME: {
-        Option<Principal> principal = framework->info.has_principal()
-          ? Principal(framework->info.principal())
-          : Option<Principal>::none();
-
-        futures.push_back(
-            authorizeResizeVolume(
-                operation.grow_volume().volume(), principal));
+        futures.push_back(authorize(
+            principal, ActionObject::growVolume(operation.grow_volume())));
 
         break;
       }
 
       case Offer::Operation::SHRINK_VOLUME: {
-        Option<Principal> principal = framework->info.has_principal()
-          ? Principal(framework->info.principal())
-          : Option<Principal>::none();
-
-        futures.push_back(
-            authorizeResizeVolume(
-                operation.shrink_volume().volume(), principal));
+        futures.push_back(authorize(
+            principal, ActionObject::shrinkVolume(operation.shrink_volume())));
 
         break;
       }
diff --git a/src/master/master.hpp b/src/master/master.hpp
index 0fbe3fb..efc3c62 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -848,28 +848,6 @@ protected:
       const Offer::Operation::Destroy& destroy,
       const Option<process::http::authentication::Principal>& principal);
 
-  /**
-   * Authorizes resize of a volume triggered by either `GROW_VOLUME` or
-   * `SHRINK_VOLUME` operations.
-   *
-   * Returns whether the triggering operation is authorized with the provided
-   * principal. This function is used for authorization of operations
-   * originating both from frameworks and operators. Note that operations may 
be
-   * validated AFTER authorization, so it's possible that the operation could 
be
-   * malformed.
-   *
-   * @param volume The volume being resized.
-   * @param principal An `Option` containing the principal attempting this
-   *     operation.
-   *
-   * @return A `Future` containing a boolean value representing the success or
-   *     failure of this authorization. A failed `Future` implies that
-   *     validation of the operation did not succeed.
-   */
-  process::Future<bool> authorizeResizeVolume(
-      const Resource& volume,
-      const Option<process::http::authentication::Principal>& principal);
-
 
   /**
    * Authorizes a `CREATE_DISK` operation.

Reply via email to