Repository: mesos
Updated Branches:
  refs/heads/master 72752fc6d -> 9fb6a11a5


Added and implemented RegisterAgent ACL.

Review: https://reviews.apache.org/r/57534


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/38afa9c1
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/38afa9c1
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/38afa9c1

Branch: refs/heads/master
Commit: 38afa9c1afa65d931bfcc215b5faa7da76d62c19
Parents: 72752fc
Author: Jiang Yan Xu <[email protected]>
Authored: Fri Mar 10 15:25:07 2017 -0800
Committer: Jiang Yan Xu <[email protected]>
Committed: Fri Apr 28 11:13:36 2017 -0700

----------------------------------------------------------------------
 include/mesos/authorizer/acls.proto       | 11 ++++++
 include/mesos/authorizer/authorizer.proto |  4 ++
 src/authorizer/local/authorizer.cpp       | 24 ++++++++++++
 src/tests/authorization_tests.cpp         | 54 ++++++++++++++++++++++++++
 4 files changed, 93 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/38afa9c1/include/mesos/authorizer/acls.proto
----------------------------------------------------------------------
diff --git a/include/mesos/authorizer/acls.proto 
b/include/mesos/authorizer/acls.proto
index 796ebb7..ae0b1ea 100644
--- a/include/mesos/authorizer/acls.proto
+++ b/include/mesos/authorizer/acls.proto
@@ -343,6 +343,16 @@ message ACL {
     // access.
     required Entity level = 2;
   }
+
+  // Which principals are authorized to register (and re-register) as agents.
+  message RegisterAgent {
+    // Subjects: Agent principals.
+    required Entity principals = 1;
+
+    // Objects: Given implicitly. Use Entity type ANY or NONE to allow or deny
+    // access.
+    required Entity agent = 2;
+  }
 }
 
 
@@ -407,4 +417,5 @@ message ACLs {
   repeated ACL.ViewContainer view_containers = 31;
   repeated ACL.SetLogLevel set_log_level = 32;
   repeated ACL.RemoveNestedContainer remove_nested_containers = 33;
+  repeated ACL.RegisterAgent register_agents = 34;
 }

http://git-wip-us.apache.org/repos/asf/mesos/blob/38afa9c1/include/mesos/authorizer/authorizer.proto
----------------------------------------------------------------------
diff --git a/include/mesos/authorizer/authorizer.proto 
b/include/mesos/authorizer/authorizer.proto
index 3ae5df5..c9184d1 100644
--- a/include/mesos/authorizer/authorizer.proto
+++ b/include/mesos/authorizer/authorizer.proto
@@ -193,6 +193,10 @@ enum Action {
   // This action will set objects of type `ExecutorInfo`, `FrameworkInfo`, and
   // `ContainerID`.
   REMOVE_NESTED_CONTAINER = 27;
+
+  // This action will not fill in any object fields, since a principal is
+  // either allowed to register as an agent or is unauthorized.
+  REGISTER_AGENT = 28;
 }
 
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/38afa9c1/src/authorizer/local/authorizer.cpp
----------------------------------------------------------------------
diff --git a/src/authorizer/local/authorizer.cpp 
b/src/authorizer/local/authorizer.cpp
index 0e323f3..89aaf4b 100644
--- a/src/authorizer/local/authorizer.cpp
+++ b/src/authorizer/local/authorizer.cpp
@@ -392,6 +392,10 @@ public:
           aclObject.set_type(mesos::ACL::Entity::ANY);
 
           break;
+        case authorization::REGISTER_AGENT:
+          aclObject.set_type(mesos::ACL::Entity::ANY);
+
+          break;
         case authorization::CREATE_VOLUME:
         case authorization::GET_QUOTA:
         case authorization::RESERVE_RESOURCES:
@@ -654,6 +658,7 @@ public:
         case authorization::VIEW_FRAMEWORK:
         case authorization::VIEW_TASK:
         case authorization::WAIT_NESTED_CONTAINER:
+        case authorization::REGISTER_AGENT:
         case authorization::UNKNOWN:
           UNREACHABLE();
       }
@@ -859,6 +864,7 @@ public:
       case authorization::VIEW_TASK:
       case authorization::WAIT_NESTED_CONTAINER:
       case authorization::REMOVE_NESTED_CONTAINER:
+      case authorization::REGISTER_AGENT:
         UNREACHABLE();
     }
 
@@ -1016,6 +1022,7 @@ public:
       case authorization::VIEW_TASK:
       case authorization::WAIT_NESTED_CONTAINER:
       case authorization::REMOVE_NESTED_CONTAINER:
+      case authorization::REGISTER_AGENT:
       case authorization::UNKNOWN: {
         Result<vector<GenericACL>> genericACLs =
           createGenericACLs(action, acls);
@@ -1231,6 +1238,16 @@ private:
         }
 
         return acls_;
+      case authorization::REGISTER_AGENT:
+        foreach (const ACL::RegisterAgent& acl, acls.register_agents()) {
+          GenericACL acl_;
+          acl_.subjects = acl.principals();
+          acl_.objects = acl.agent();
+
+          acls_.push_back(acl_);
+        }
+
+        return acls_;
       case authorization::REGISTER_FRAMEWORK:
       case authorization::CREATE_VOLUME:
       case authorization::RESERVE_RESOURCES:
@@ -1319,6 +1336,13 @@ Option<Error> LocalAuthorizer::validate(const ACLs& acls)
     }
   }
 
+  foreach (const ACL::RegisterAgent& acl, acls.register_agents()) {
+    if (acl.agent().type() == ACL::Entity::SOME) {
+      return Error(
+          "acls.register_agents.agent type must be either NONE or ANY");
+    }
+  }
+
   // TODO(alexr): Consider validating not only protobuf, but also the original
   // JSON in order to spot misspelled names. A misspelled action may affect
   // authorization result and hence lead to a security issue (e.g. when there

http://git-wip-us.apache.org/repos/asf/mesos/blob/38afa9c1/src/tests/authorization_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/authorization_tests.cpp 
b/src/tests/authorization_tests.cpp
index b59623f..32aa6ac 100644
--- a/src/tests/authorization_tests.cpp
+++ b/src/tests/authorization_tests.cpp
@@ -4889,6 +4889,60 @@ TYPED_TEST(AuthorizationTest, GetQuota)
   }
 }
 
+
+TYPED_TEST(AuthorizationTest, RegisterAgent)
+{
+  ACLs acls;
+
+  {
+    // "foo" principal can register as an agent.
+    mesos::ACL::RegisterAgent* acl = acls.add_register_agents();
+    acl->mutable_principals()->add_values("foo");
+    acl->mutable_agent()->set_type(mesos::ACL::Entity::ANY);
+  }
+
+  {
+    // Nobody else can register as an agent.
+    mesos::ACL::RegisterAgent* acl = acls.add_register_agents();
+    acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
+    acl->mutable_agent()->set_type(mesos::ACL::Entity::NONE);
+  }
+
+  Try<Authorizer*> create = TypeParam::create(parameterize(acls));
+  ASSERT_SOME(create);
+  Owned<Authorizer> authorizer(create.get());
+
+  {
+    // "foo" is in the "whitelist".
+    authorization::Request request;
+    request.set_action(authorization::REGISTER_AGENT);
+    request.mutable_subject()->set_value("foo");
+
+    AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
+  }
+
+  {
+    // "bar" is not in the "whitelist".
+    authorization::Request request;
+    request.set_action(authorization::REGISTER_AGENT);
+    request.mutable_subject()->set_value("bar");
+
+    AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
+  }
+
+  {
+    // Test that no authorizer is created with invalid ACLs.
+    ACLs invalid;
+
+    mesos::ACL::RegisterAgent* acl = invalid.add_register_agents();
+    acl->mutable_principals()->add_values("foo");
+    acl->mutable_agent()->add_values("yoda");
+
+    Try<Authorizer*> create = TypeParam::create(parameterize(invalid));
+    EXPECT_ERROR(create);
+  }
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

Reply via email to