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 {
