You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mz...@apache.org on 2019/06/05 01:34:03 UTC
[mesos] 02/02: Added `UPDATE_QUOTA_WITH_CONFIG` authorization in
the local authorizor.
This is an automated email from the ASF dual-hosted git repository.
mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git
commit 2ae1296c668686d234be92b00bd7abbc0a6194b0
Author: Meng Zhu <mz...@mesosphere.io>
AuthorDate: Thu Apr 25 16:03:36 2019 -0700
Added `UPDATE_QUOTA_WITH_CONFIG` authorization in the local authorizor.
Also added a test.
Review: https://reviews.apache.org/r/70550
---
include/mesos/authorizer/acls.proto | 2 +
src/authorizer/local/authorizer.cpp | 15 ++-
src/tests/authorization_tests.cpp | 196 ++++++++++++++++++++++++++++++++++++
3 files changed, 212 insertions(+), 1 deletion(-)
diff --git a/include/mesos/authorizer/acls.proto b/include/mesos/authorizer/acls.proto
index 85a3979..78acfe6 100644
--- a/include/mesos/authorizer/acls.proto
+++ b/include/mesos/authorizer/acls.proto
@@ -133,6 +133,8 @@ message ACL {
}
// Which principals are authorized to update quotas for the given roles.
+ // This ACL is currently used for two authorizatble actions:
+ // `UPDATE_QUOTA` and `UPDATE_QUOTA_WITH_CONFIG`.
message UpdateQuota {
// Subjects: Operator username.
required Entity principals = 1;
diff --git a/src/authorizer/local/authorizer.cpp b/src/authorizer/local/authorizer.cpp
index ec86f05..b89010d 100644
--- a/src/authorizer/local/authorizer.cpp
+++ b/src/authorizer/local/authorizer.cpp
@@ -424,6 +424,7 @@ public:
case authorization::GET_QUOTA:
case authorization::RESERVE_RESOURCES:
case authorization::UPDATE_QUOTA:
+ case authorization::UPDATE_QUOTA_WITH_CONFIG:
case authorization::UPDATE_WEIGHT:
case authorization::VIEW_ROLE:
case authorization::REGISTER_FRAMEWORK:
@@ -669,6 +670,15 @@ public:
break;
}
+ case authorization::UPDATE_QUOTA_WITH_CONFIG: {
+ // Check object has the required types set.
+ CHECK_NOTNULL(object->value);
+
+ entityObject.add_values(*(object->value));
+ entityObject.set_type(mesos::ACL::Entity::SOME);
+
+ break;
+ }
case authorization::REGISTER_FRAMEWORK: {
vector<ACL::Entity> objects;
if (object->framework_info) {
@@ -922,7 +932,8 @@ public:
createHierarchicalRoleACLs(acls.register_frameworks());
break;
}
- case authorization::UPDATE_QUOTA: {
+ case authorization::UPDATE_QUOTA:
+ case authorization::UPDATE_QUOTA_WITH_CONFIG: {
hierarchicalRoleACLs =
createHierarchicalRoleACLs(acls.update_quotas());
break;
@@ -1171,6 +1182,7 @@ public:
case authorization::GET_QUOTA:
case authorization::REGISTER_FRAMEWORK:
case authorization::UPDATE_QUOTA:
+ case authorization::UPDATE_QUOTA_WITH_CONFIG:
case authorization::CREATE_BLOCK_DISK:
case authorization::DESTROY_BLOCK_DISK:
case authorization::CREATE_MOUNT_DISK:
@@ -1608,6 +1620,7 @@ private:
case authorization::VIEW_ROLE:
case authorization::GET_QUOTA:
case authorization::UPDATE_QUOTA:
+ case authorization::UPDATE_QUOTA_WITH_CONFIG:
case authorization::LAUNCH_NESTED_CONTAINER_SESSION:
case authorization::LAUNCH_NESTED_CONTAINER:
case authorization::CREATE_BLOCK_DISK:
diff --git a/src/tests/authorization_tests.cpp b/src/tests/authorization_tests.cpp
index cad76f6..7bb0bd8 100644
--- a/src/tests/authorization_tests.cpp
+++ b/src/tests/authorization_tests.cpp
@@ -2466,6 +2466,202 @@ TYPED_TEST(AuthorizationTest, UpdateQuota)
}
+// This tests the authorization of requests to update quota configs.
+TYPED_TEST(AuthorizationTest, UpdateQuotaConfig)
+{
+ ACLs acls;
+
+ {
+ // "foo" principal can update quota configs for all roles.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->add_values("foo");
+ acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
+ }
+
+ {
+ // "bar" principal can update quota configs for "dev" role.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->add_values("bar");
+ acl->mutable_roles()->add_values("dev");
+ }
+
+ {
+ // Anyone can update quota configs for "test" role.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
+ acl->mutable_roles()->add_values("test");
+ }
+
+ {
+ // Principal "elizabeth-ii" can update quota configs for the "king" role
+ // and its nested ones.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->add_values("elizabeth-ii");
+ acl->mutable_roles()->add_values("king/%");
+ acl->mutable_roles()->add_values("king");
+ }
+
+ {
+ // Principal "charles" can update quota configs for any role below the
+ // "king/" role. Not in "king" itself.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->add_values("charles");
+ acl->mutable_roles()->add_values("king/%");
+ }
+
+ {
+ // Principal "j-welby" can update quota configs only for the "king" role
+ // but not in any nested one.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->add_values("j-welby");
+ acl->mutable_roles()->add_values("king");
+ }
+
+ {
+ // No other principal can update quota configs.
+ mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
+ acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
+ acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
+ }
+
+ // Create an `Authorizer` with the ACLs.
+ Try<Authorizer*> create = TypeParam::create(parameterize(acls));
+ ASSERT_SOME(create);
+ Owned<Authorizer> authorizer(create.get());
+
+ // Principal "foo" can update quota configs for all roles, so this will pass.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("foo");
+ request.mutable_object()->set_value("prod");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ // Principal "bar" can update quota configs for role "dev", so this will pass.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("bar");
+ request.mutable_object()->set_value("dev");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ // Principal "bar" can only update quota configs for role "dev",
+ // so this will fail.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("bar");
+ request.mutable_object()->set_value("prod");
+ AWAIT_EXPECT_FALSE(authorizer->authorized(request));
+ }
+
+ // Anyone can update quota configs for role "test", so this will pass.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_object()->set_value("test");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ // Principal "jeff" is not mentioned in the ACLs of the `Authorizer`, so it
+ // will be caught by the final ACL, which provides a default case that denies
+ // access for all other principals. This case will fail.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("jeff");
+ request.mutable_object()->set_value("prod");
+ AWAIT_EXPECT_FALSE(authorizer->authorized(request));
+ }
+
+ // `elizabeth-ii` has full permissions for the `king` role as well as all
+ // its nested roles. She should be able to update quota configs in the next
+ // three blocks.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("elizabeth-ii");
+ request.mutable_object()->set_value("king");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("elizabeth-ii");
+ request.mutable_object()->set_value("king/prince");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("elizabeth-ii");
+ request.mutable_object()
+ ->set_value("king/prince/duke");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ // `charles` doesn't have permissions for the `king` role, so the first
+ // test should fail. However he has permissions for `king`'s nested roles
+ // so the next two tests should succeed.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("charles");
+ request.mutable_object()->set_value("king");
+ AWAIT_EXPECT_FALSE(authorizer->authorized(request));
+ }
+
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("charles");
+ request.mutable_object()->set_value("king/prince");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("charles");
+ request.mutable_object()
+ ->set_value("king/prince/duke");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ // `j-welby` only has permissions for the role `king` itself, but not
+ // for its nested roles, therefore only the first of the following three
+ // tests should succeed.
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("j-welby");
+ request.mutable_object()->set_value("king");
+ AWAIT_EXPECT_TRUE(authorizer->authorized(request));
+ }
+
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("j-welby");
+ request.mutable_object()->set_value("king/prince");
+ AWAIT_EXPECT_FALSE(authorizer->authorized(request));
+ }
+
+ {
+ authorization::Request request;
+ request.set_action(authorization::UPDATE_QUOTA_WITH_CONFIG);
+ request.mutable_subject()->set_value("j-welby");
+ request.mutable_object()
+ ->set_value("king/prince/duke");
+ AWAIT_EXPECT_FALSE(authorizer->authorized(request));
+ }
+}
+
+
// This tests the authorization of requests to ViewFramework.
TYPED_TEST(AuthorizationTest, ViewFramework)
{