// Testing route with good ACLs. TEST_F(TeardownTest, TeardownEndpointGoodACLs) { // Setup ACLs so that the default principal can teardown the // framework. ACLs acls; mesos::ACL::ShutdownFramework* acl = acls.add_shutdown_frameworks(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_framework_principals()->add_values( DEFAULT_CREDENTIAL.principal()); master::Flags flags = CreateMasterFlags(); flags.acls = acls; Try<PID<Master> > master = StartMaster(flags); ASSERT_SOME(master); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId)); ASSERT_EQ(DRIVER_RUNNING, driver.start()); AWAIT_READY(frameworkId); process::http::Headers headers; headers["Authorization"] = "Basic " + base64::encode(DEFAULT_CREDENTIAL.principal() + ":" + DEFAULT_CREDENTIAL.secret()); Future<Response> response = process::http::post( master.get(), "teardown", headers, "frameworkId=" + frameworkId.get().value()); AWAIT_READY(response); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response); driver.stop(); driver.join(); Shutdown(); }
TYPED_TEST(AuthorizationTest, OnlySomePrincipalsRunAsSomeUsers) { // Only some principals can run as some users. ACLs acls; // ACL for some principals to run as some users. mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values("foo"); acl->mutable_principals()->add_values("bar"); acl->mutable_users()->add_values("user1"); acl->mutable_users()->add_values("user2"); // ACL for no one else to run as some users. mesos::ACL::RunTask* acl2 = acls.add_run_tasks(); acl2->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl2->mutable_users()->add_values("user1"); acl2->mutable_users()->add_values("user2"); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principals "foo" and "bar" can run as "user1" and "user2". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_principals()->add_values("bar"); request.mutable_users()->add_values("user1"); request.mutable_users()->add_values("user2"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); // Principal "baz" cannot run as "user1". mesos::ACL::RunTask request2; request2.mutable_principals()->add_values("baz"); request2.mutable_users()->add_values("user1"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request2)); // Principal "baz" cannot run as "user2". mesos::ACL::RunTask request3; request3.mutable_principals()->add_values("baz"); request3.mutable_users()->add_values("user1"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request3)); }
TEST_F(AuthorizationTest, NoPrincipalRunAsUser) { // No principal can run as "root" user. ACLs acls; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_users()->add_values("root"); // Create an Authorizer with the ACLs. Try<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principal "foo" cannot run as "root". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("root"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request)); }
TYPED_TEST(AuthorizationTest, PrincipalRunAsSomeUserRestrictive) { ACLs acls; acls.set_permissive(false); // Restrictive. { // A principal can run as "user1"; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values("foo"); acl->mutable_users()->add_values("user1"); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principal "foo" can run as "user1". { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("user1"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } // Principal "foo" cannot run as "user2". { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("user2"); AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); } // Principal "bar" cannot run as "user2" since no ACL is set. { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("bar"); request.mutable_object()->set_value("user2"); AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); } }
TYPED_TEST(AuthorizationTest, PrincipalNotOfferedAnyRoleRestrictive) { ACLs acls; acls.set_permissive(false); { // A principal "foo" can be offered "analytics" role's resources. mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->add_values("foo"); acl->mutable_roles()->add_values("analytics"); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principal "foo" can be offered "analytics" role's resources. { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("analytics"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } // Principal "bar" cannot be offered "analytics" role's resources. { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("bar"); request.mutable_object()->set_value("analytics"); AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); } // Principal "bar" cannot be offered "ads" role's resources because no ACL. { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("bar"); request.mutable_object()->set_value("ads"); AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); } }
TEST_F(AuthorizationTest, AnyPrincipalOfferedRole) { // Any principal can be offered "*" role's resources. ACLs acls; mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl->mutable_roles()->add_values("*"); // Create an Authorizer with the ACLs. Try<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principals "foo" and "bar" can be offered "*" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_principals()->add_values("bar"); request.mutable_roles()->add_values("*"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); }
TEST_F(AuthorizationTest, PrincipalRunAsAnyUser) { // A principal "foo" can run as any user. ACLs acls; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values("foo"); acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); // Create an Authorizer with the ACLs. Try<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principal "foo" can run as "user1" and "user2". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("user1"); request.mutable_users()->add_values("user2"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); }
TYPED_TEST(AuthorizationTest, SomePrincipalOnlySomeUser) { // Some principal can run as only some user. ACLs acls; // ACL for some principal to run as some user. mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values("foo"); acl->mutable_users()->add_values("user1"); // ACL for some principal to not run as any other user. mesos::ACL::RunTask* acl2 = acls.add_run_tasks(); acl2->mutable_principals()->add_values("foo"); acl2->mutable_users()->set_type(mesos::ACL::Entity::NONE); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can run as "user1". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("user1"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request)); // Principal "foo" cannot run as "user2". mesos::ACL::RunTask request2; request2.mutable_principals()->add_values("foo"); request2.mutable_users()->add_values("user2"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request2)); // Principal "bar" can run as "user1" and "user2". mesos::ACL::RunTask request3; request3.mutable_principals()->add_values("bar"); request3.mutable_users()->add_values("user1"); request3.mutable_users()->add_values("user2"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request3)); }
TYPED_TEST(AuthorizationTest, AnyPrincipalRunAsUser) { ACLs acls; { // Any principal can run as "guest" user. mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl->mutable_users()->add_values("guest"); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principals "foo" and "bar" can run as "guest". { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("guest"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("bar"); request.mutable_object()->set_value("guest"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } // Principal "foo" can run as "root" since the ACLs are permissive. { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("root"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } }
TYPED_TEST(AuthorizationTest, PrincipalOfferedRole) { // Only a principal can be offered "analytics" role's resources. ACLs acls; { // ACL for a principal to be offered "analytics" role's resources. mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->add_values("foo"); acl->mutable_roles()->add_values("analytics"); } { // ACL for no one else to be offered "analytics" role's resources. mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_roles()->add_values("analytics"); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principal "foo" can be offered "analytics" role's resources. { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("analytics"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } // Principal "bar" cannot be offered "analytics" role's resources. { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("bar"); request.mutable_object()->set_value("analytics"); AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); } }
TYPED_TEST(AuthorizationTest, SomePrincipalsOfferedRole) { ACLs acls; { // Some principals can be offered "ads" role's resources. mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->add_values("foo"); acl->mutable_principals()->add_values("bar"); acl->mutable_roles()->add_values("ads"); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principals "foo", "bar" and "baz" (no ACL) can be offered "ads" // role's resources. { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("ads"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("bar"); request.mutable_object()->set_value("ads"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } { authorization::Request request; request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE); request.mutable_subject()->set_value("baz"); request.mutable_object()->set_value("ads"); AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); } }
// This test verifies that only authorized principals // can access the '/flags' endpoint. TYPED_TEST(SlaveAuthorizerTest, AuthorizeFlagsEndpoint) { const string endpoint = "flags"; // Setup ACLs so that only the default principal // can access the '/flags' endpoint. ACLs acls; acls.set_permissive(false); mesos::ACL::GetEndpoint* acl = acls.add_get_endpoints(); acl->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); acl->mutable_paths()->add_values("/" + endpoint); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); StandaloneMasterDetector detector; Try<Owned<cluster::Slave>> agent = this->StartSlave(&detector, authorizer.get()); ASSERT_SOME(agent); Future<Response> response = http::get( agent.get()->pid, endpoint, None(), createBasicAuthHeaders(DEFAULT_CREDENTIAL)); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response) << response.get().body; response = http::get( agent.get()->pid, endpoint, None(), createBasicAuthHeaders(DEFAULT_CREDENTIAL_2)); AWAIT_EXPECT_RESPONSE_STATUS_EQ(Forbidden().status, response) << response.get().body; }
// This test verifies that access to the '/flags' endpoint can be authorized // without authentication if an authorization rule exists that applies to // anyone. The authorizer will map the absence of a principal to "ANY". TYPED_TEST(SlaveAuthorizerTest, AuthorizeFlagsEndpointWithoutPrincipal) { const string endpoint = "flags"; // Because the authenticators' lifetime is tied to libprocess's lifetime, // it may already be set by other tests. We have to unset it here to disable // HTTP authentication. // TODO(nfnt): Fix this behavior. The authenticator should be unset by // every test case that sets it, similar to how it's done for the master. http::authentication::unsetAuthenticator( slave::DEFAULT_HTTP_AUTHENTICATION_REALM); // Setup ACLs so that any principal can access the '/flags' endpoint. ACLs acls; acls.set_permissive(false); mesos::ACL::GetEndpoint* acl = acls.add_get_endpoints(); acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl->mutable_paths()->add_values("/" + endpoint); slave::Flags agentFlags = this->CreateSlaveFlags(); agentFlags.acls = acls; agentFlags.authenticate_http = false; agentFlags.http_credentials = None(); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); StandaloneMasterDetector detector; Try<Owned<cluster::Slave>> agent = this->StartSlave( &detector, authorizer.get(), agentFlags); ASSERT_SOME(agent); Future<Response> response = http::get(agent.get()->pid, endpoint); AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response) << response.get().body; }
// Testing route with bad ACLs. TEST_F(TeardownTest, BadACLs) { // Setup ACLs so that no principal can teardown the framework. ACLs acls; mesos::ACL::TeardownFramework* acl = acls.add_teardown_frameworks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_framework_principals()->add_values( DEFAULT_CREDENTIAL.principal()); master::Flags flags = CreateMasterFlags(); flags.acls = acls; Try<Owned<cluster::Master>> master = StartMaster(flags); ASSERT_SOME(master); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get()->pid, DEFAULT_CREDENTIAL); Future<FrameworkID> frameworkId; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureArg<1>(&frameworkId)); ASSERT_EQ(DRIVER_RUNNING, driver.start()); AWAIT_READY(frameworkId); Future<Response> response = process::http::post( master.get()->pid, "teardown", createBasicAuthHeaders(DEFAULT_CREDENTIAL), "frameworkId=" + frameworkId.get().value()); AWAIT_READY(response); AWAIT_EXPECT_RESPONSE_STATUS_EQ(Forbidden().status, response); driver.stop(); driver.join(); }
TEST_F(AuthorizationTest, SomePrincipalsOfferedRole) { // Some principals can be offered "ads" role's resources. ACLs acls; mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->add_values("foo"); acl->mutable_principals()->add_values("bar"); acl->mutable_roles()->add_values("ads"); // Create an Authorizer with the ACLs. Try<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principals "foo", "bar" and "baz" (no ACL) can be offered "ads" // role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_principals()->add_values("bar"); request.mutable_principals()->add_values("baz"); request.mutable_roles()->add_values("ads"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); }
TYPED_TEST(AuthorizationTest, NoPrincipalRunAsUser) { // No principal can run as "root" user. ACLs acls; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_users()->add_values("root"); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" cannot run as "root". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("root"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request)); }
TEST_F(AuthorizationTest, SomePrincipalOnlySomeUser) { // Some principal can run as only some user. ACLs acls; // ACL for some principal to run as some user. mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values("foo"); acl->mutable_users()->add_values("user1"); // ACL for some principal to not run as any other user. mesos::ACL::RunTask* acl2 = acls.add_run_tasks(); acl2->mutable_principals()->add_values("foo"); acl2->mutable_users()->set_type(mesos::ACL::Entity::NONE); // Create an Authorizer with the ACLs. Try<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principal "foo" can run as "user1". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("user1"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); // Principal "foo" cannot run as "user2". mesos::ACL::RunTask request2; request2.mutable_principals()->add_values("foo"); request2.mutable_users()->add_values("user2"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request2)); // Principal "bar" can run as "user1" and "user2". mesos::ACL::RunTask request3; request3.mutable_principals()->add_values("bar"); request3.mutable_users()->add_values("user1"); request3.mutable_users()->add_values("user2"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request3)); }
// This test verifies that a framework registration with unauthorized // role is denied. TEST_F(MasterAuthorizationTest, UnauthorizedRole) { // Setup ACLs so that no framework can receive offers for role // "foo". ACLs acls; mesos::ACL::ReceiveOffers* acl = acls.add_receive_offers(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_roles()->add_values("foo"); master::Flags flags = CreateMasterFlags(); flags.roles = "foo"; flags.acls = acls; Try<PID<Master> > master = StartMaster(flags); ASSERT_SOME(master); FrameworkInfo frameworkInfo; // Bug in gcc 4.1.*, must assign on next line. frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_role("foo"); MockScheduler sched; MesosSchedulerDriver driver( &sched, frameworkInfo, master.get(), DEFAULT_CREDENTIAL); Future<Nothing> error; EXPECT_CALL(sched, error(&driver, _)) .WillOnce(FutureSatisfy(&error)); driver.start(); // Framework should get error message from the master. AWAIT_READY(error); driver.stop(); driver.join(); Shutdown(); }
TYPED_TEST(AuthorizationTest, AnyPrincipalOfferedRole) { // Any principal can be offered "*" role's resources. ACLs acls; mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl->mutable_roles()->add_values("*"); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principals "foo" and "bar" can be offered "*" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_principals()->add_values("bar"); request.mutable_roles()->add_values("*"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request)); }
TYPED_TEST(AuthorizationTest, PrincipalRunAsAnyUser) { // A principal "foo" can run as any user. ACLs acls; mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values("foo"); acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can run as "user1" and "user2". mesos::ACL::RunTask request; request.mutable_principals()->add_values("foo"); request.mutable_users()->add_values("user1"); request.mutable_users()->add_values("user2"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); }
// This test verifies that a framework registration with authorized // role is successful. TEST_F(MasterAuthorizationTest, AuthorizedRole) { // Setup ACLs so that the framework can receive offers for role // "foo". ACLs acls; mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->add_values(DEFAULT_FRAMEWORK_INFO.principal()); acl->mutable_roles()->add_values("foo"); master::Flags flags = CreateMasterFlags(); flags.roles = "foo"; flags.acls = acls; Try<PID<Master> > master = StartMaster(flags); ASSERT_SOME(master); FrameworkInfo frameworkInfo; // Bug in gcc 4.1.*, must assign on next line. frameworkInfo = DEFAULT_FRAMEWORK_INFO; frameworkInfo.set_role("foo"); MockScheduler sched; MesosSchedulerDriver driver( &sched, frameworkInfo, master.get(), DEFAULT_CREDENTIAL); Future<Nothing> registered; EXPECT_CALL(sched, registered(&driver, _, _)) .WillOnce(FutureSatisfy(®istered)); driver.start(); AWAIT_READY(registered); driver.stop(); driver.join(); Shutdown(); }
TYPED_TEST(AuthorizationTest, NoPrincipalRunAsUser) { // No principal can run as "root" user. ACLs acls; { mesos::ACL::RunTask* acl = acls.add_run_tasks(); acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl->mutable_users()->add_values("root"); } // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principal "foo" cannot run as "root". { authorization::Request request; request.set_action(authorization::RUN_TASK_WITH_USER); request.mutable_subject()->set_value("foo"); request.mutable_object()->set_value("root"); AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); } }
// This tests that update_quotas and set_quotas/remove_quotas // cannot be used together. // TODO(zhitao): Remove this test case at the end of the deprecation // cycle started with 0.29. TYPED_TEST(AuthorizationTest, ConflictQuotaACLs) { { ACLs acls; { // Add an UpdateQuota ACL. mesos::ACL::UpdateQuota* acl = acls.add_update_quotas(); acl->mutable_principals()->add_values("foo"); acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY); } { // Add a SetQuota ACL. mesos::ACL::SetQuota* acl = acls.add_set_quotas(); acl->mutable_principals()->add_values("foo"); acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY); } // Create an `Authorizer` with the ACLs should error out. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_ERROR(create); } { ACLs acls; { // Add an UpdateQuota ACL. mesos::ACL::UpdateQuota* acl = acls.add_update_quotas(); acl->mutable_principals()->add_values("foo"); acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY); } { // Add a RemoveQuota ACL. mesos::ACL::RemoveQuota* acl = acls.add_remove_quotas(); acl->mutable_principals()->add_values("foo"); acl->mutable_quota_principals()->set_type(mesos::ACL::Entity::ANY); } // Create an `Authorizer` with the ACLs should error out. Try<Authorizer*> create = TypeParam::create(parameterize(acls)); ASSERT_ERROR(create); } }
// This test verifies that an authorized task launch is successful. TEST_F(MasterAuthorizationTest, AuthorizedTask) { // Setup ACLs so that the framework can launch tasks as "foo". ACLs acls; mesos::ACL::RunTasks* acl = acls.add_run_tasks(); acl->mutable_principals()->add_values(DEFAULT_FRAMEWORK_INFO.principal()); acl->mutable_users()->add_values("foo"); master::Flags flags = CreateMasterFlags(); flags.acls = acls; Try<PID<Master> > master = StartMaster(flags); ASSERT_SOME(master); // Create an authorized executor. ExecutorInfo executor; // Bug in gcc 4.1.*, must assign on next line. executor = CREATE_EXECUTOR_INFO("test-executor", "exit 1"); executor.mutable_command()->set_user("foo"); MockExecutor exec(executor.executor_id()); Try<PID<Slave> > slave = StartSlave(&exec); ASSERT_SOME(slave); MockScheduler sched; MesosSchedulerDriver driver( &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL); EXPECT_CALL(sched, registered(&driver, _, _)) .Times(1); Future<vector<Offer> > offers; EXPECT_CALL(sched, resourceOffers(&driver, _)) .WillOnce(FutureArg<1>(&offers)) .WillRepeatedly(Return()); // Ignore subsequent offers. driver.start(); AWAIT_READY(offers); EXPECT_NE(0u, offers.get().size()); // Create an authorized task. TaskInfo task; task.set_name("test"); task.mutable_task_id()->set_value("1"); task.mutable_slave_id()->MergeFrom(offers.get()[0].slave_id()); task.mutable_resources()->MergeFrom(offers.get()[0].resources()); task.mutable_executor()->MergeFrom(executor); vector<TaskInfo> tasks; tasks.push_back(task); EXPECT_CALL(exec, registered(_, _, _, _)) .Times(1); EXPECT_CALL(exec, launchTask(_, _)) .WillOnce(SendStatusUpdateFromTask(TASK_RUNNING)); Future<TaskStatus> status; EXPECT_CALL(sched, statusUpdate(&driver, _)) .WillOnce(FutureArg<1>(&status)); driver.launchTasks(offers.get()[0].id(), tasks); AWAIT_READY(status); EXPECT_EQ(TASK_RUNNING, status.get().state()); EXPECT_CALL(exec, shutdown(_)) .Times(AtMost(1)); driver.stop(); driver.join(); Shutdown(); // Must shutdown before 'containerizer' gets deallocated. }
void execute(const string& script) { // Create a temporary directory for the test. Try<string> directory = environment->mkdtemp(); CHECK_SOME(directory) << "Failed to create temporary directory"; if (flags.verbose) { std::cerr << "Using temporary directory '" << directory.get() << "'" << std::endl; } // Determine the path for the script. Result<string> path = os::realpath(path::join(flags.source_dir, "src", "tests", script)); if (!path.isSome()) { FAIL() << "Failed to locate script: " << (path.isError() ? path.error() : "No such file or directory"); } // Fork a process to change directory and run the test. pid_t pid; if ((pid = fork()) == -1) { FAIL() << "Failed to fork to launch script"; } if (pid > 0) { // In parent process. int status; while (wait(&status) != pid || WIFSTOPPED(status)); CHECK(WIFEXITED(status) || WIFSIGNALED(status)); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { FAIL() << script << " " << WSTRINGIFY(status); } } else { // In child process. DO NOT USE GLOG! // Start by cd'ing into the temporary directory. Try<Nothing> chdir = os::chdir(directory.get()); if (chdir.isError()) { std::cerr << "Failed to chdir to '" << directory.get() << "': " << chdir.error() << std::endl; abort(); } // Redirect output to /dev/null unless the test is verbose. if (!flags.verbose) { if (freopen("/dev/null", "w", stdout) == NULL || freopen("/dev/null", "w", stderr) == NULL) { std::cerr << "Failed to redirect stdout/stderr to /dev/null:" << os::strerror(errno) << std::endl; abort(); } } // Set up the environment for executing the script. os::setenv("MESOS_SOURCE_DIR", flags.source_dir); os::setenv("MESOS_BUILD_DIR", flags.build_dir); os::setenv("MESOS_WEBUI_DIR", path::join(flags.source_dir, "src", "webui")); os::setenv("MESOS_LAUNCHER_DIR", path::join(flags.build_dir, "src")); // Enable replicated log based registry. os::setenv("MESOS_REGISTRY", "replicated_log"); // Enable authentication. os::setenv("MESOS_AUTHENTICATE", "true"); // Create test credentials. const string& credentials = DEFAULT_CREDENTIAL.principal() + " " + DEFAULT_CREDENTIAL.secret(); const string& credentialsPath = path::join(directory.get(), "credentials"); CHECK_SOME(os::write(credentialsPath, credentials)) << "Failed to write credentials to '" << credentialsPath << "'"; os::setenv("MESOS_CREDENTIALS", "file://" + credentialsPath); // We set test credentials here for example frameworks to use. os::setenv("DEFAULT_PRINCIPAL", DEFAULT_CREDENTIAL.principal()); os::setenv("DEFAULT_SECRET", DEFAULT_CREDENTIAL.secret()); // TODO(bmahler): Update the example frameworks to use flags and // remove the special DEFAULT_* environment variables above. os::setenv("MESOS_PRINCIPAL", DEFAULT_CREDENTIAL.principal()); os::setenv("MESOS_SECRET", DEFAULT_CREDENTIAL.secret()); // Create test ACLs. ACLs acls; acls.set_permissive(false); mesos::ACL::RunTask* run = acls.add_run_tasks(); run->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); Result<string> user = os::user(); CHECK_SOME(user) << "Failed to get current user name"; run->mutable_users()->add_values(user.get()); mesos::ACL::RegisterFramework* register_ = acls.add_register_frameworks(); register_->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal()); register_->mutable_roles()->add_values("*"); const string& aclsPath = path::join(directory.get(), "acls"); CHECK_SOME(os::write(aclsPath, stringify(JSON::protobuf(acls)))) << "Failed to write ACLs to '" << aclsPath << "'"; os::setenv("MESOS_ACLS", "file://" + aclsPath); // Now execute the script. execl(path.get().c_str(), path.get().c_str(), (char*) NULL); std::cerr << "Failed to execute '" << script << "': " << os::strerror(errno) << std::endl; abort(); } }
// Tests the authorization of ACLs used for dynamic reservation of resources. TYPED_TEST(AuthorizationTest, Reserve) { ACLs acls; // Principals "foo" and "bar" can reserve resources for any role. mesos::ACL::ReserveResources* acl1 = acls.add_reserve_resources(); acl1->mutable_principals()->add_values("foo"); acl1->mutable_principals()->add_values("bar"); acl1->mutable_roles()->set_type(mesos::ACL::Entity::ANY); // Principal "baz" can only reserve resources for the "ads" role. mesos::ACL::ReserveResources* acl2 = acls.add_reserve_resources(); acl2->mutable_principals()->add_values("baz"); acl2->mutable_roles()->add_values("ads"); // No other principals can reserve resources. mesos::ACL::ReserveResources* acl3 = acls.add_reserve_resources(); acl3->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl3->mutable_roles()->set_type(mesos::ACL::Entity::NONE); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principals "foo" and "bar" can reserve resources for any role, // so requests 1 and 2 will pass. mesos::ACL::ReserveResources request1; request1.mutable_principals()->add_values("foo"); request1.mutable_principals()->add_values("bar"); request1.mutable_roles()->set_type(mesos::ACL::Entity::ANY); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request1)); mesos::ACL::ReserveResources request2; request2.mutable_principals()->add_values("foo"); request2.mutable_principals()->add_values("bar"); request2.mutable_roles()->add_values("awesome_role"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request2)); // Principal "baz" can only reserve resources for the "ads" role, so request 3 // will pass, but requests 4 and 5 will fail. mesos::ACL::ReserveResources request3; request3.mutable_principals()->add_values("baz"); request3.mutable_roles()->add_values("ads"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request3)); mesos::ACL::ReserveResources request4; request4.mutable_principals()->add_values("baz"); request4.mutable_roles()->add_values("awesome_role"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request4)); mesos::ACL::ReserveResources request5; request5.mutable_principals()->add_values("baz"); request5.mutable_roles()->set_type(mesos::ACL::Entity::ANY); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request5)); // Principal "zelda" 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 request will fail. mesos::ACL::ReserveResources request6; request6.mutable_principals()->add_values("zelda"); request6.mutable_roles()->add_values("ads"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request6)); }
// This tests the authorization of requests to remove quotas. TYPED_TEST(AuthorizationTest, RemoveQuota) { ACLs acls; // "foo" principal can remove its own quotas. mesos::ACL::RemoveQuota* acl1 = acls.add_remove_quotas(); acl1->mutable_principals()->add_values("foo"); acl1->mutable_quota_principals()->add_values("foo"); // "bar" principal cannot remove anyone's quotas. mesos::ACL::RemoveQuota* acl2 = acls.add_remove_quotas(); acl2->mutable_principals()->add_values("bar"); acl2->mutable_quota_principals()->set_type(mesos::ACL::Entity::NONE); // "ops" principal can remove anyone's quotas. mesos::ACL::RemoveQuota* acl3 = acls.add_remove_quotas(); acl3->mutable_principals()->add_values("ops"); acl3->mutable_quota_principals()->set_type(mesos::ACL::Entity::ANY); // No other principals can remove quotas. mesos::ACL::RemoveQuota* acl4 = acls.add_remove_quotas(); acl4->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl4->mutable_quota_principals()->set_type(mesos::ACL::Entity::NONE); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can remove its own quotas, so request 1 will pass. mesos::ACL::RemoveQuota request1; request1.mutable_principals()->add_values("foo"); request1.mutable_quota_principals()->add_values("foo"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request1)); // Principal "bar" cannot remove anyone's quotas, so requests 2 and 3 will // fail. mesos::ACL::RemoveQuota request2; request2.mutable_principals()->add_values("bar"); request2.mutable_quota_principals()->add_values("bar"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request2)); mesos::ACL::RemoveQuota request3; request3.mutable_principals()->add_values("bar"); request3.mutable_quota_principals()->add_values("foo"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request3)); // Principal "ops" can remove anyone's quotas, so requests 4 and 5 will pass. mesos::ACL::RemoveQuota request4; request4.mutable_principals()->add_values("ops"); request4.mutable_quota_principals()->add_values("foo"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request4)); mesos::ACL::RemoveQuota request5; request5.mutable_principals()->add_values("ops"); request5.mutable_quota_principals()->set_type(mesos::ACL::Entity::ANY); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request5)); // Principal "jeff" is not mentioned in the ACLs of the `Authorizer`, so it // will be caught by the final rule, which provides a default case that denies // access for all other principals. This case will fail. mesos::ACL::RemoveQuota request6; request6.mutable_principals()->add_values("jeff"); request6.mutable_quota_principals()->add_values("foo"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request6)); }
// Tests the authorization of ACLs used for the creation of persistent volumes. TYPED_TEST(AuthorizationTest, CreateVolume) { ACLs acls; // Principal "foo" can create volumes for any role. mesos::ACL::CreateVolume* acl1 = acls.add_create_volumes(); acl1->mutable_principals()->add_values("foo"); acl1->mutable_roles()->set_type(mesos::ACL::Entity::ANY); // Principal "bar" can only create volumes for the "panda" role. mesos::ACL::CreateVolume* acl2 = acls.add_create_volumes(); acl2->mutable_principals()->add_values("bar"); acl2->mutable_roles()->add_values("panda"); // Principal "baz" cannot create volumes. mesos::ACL::CreateVolume* acl3 = acls.add_create_volumes(); acl3->mutable_principals()->add_values("baz"); acl3->mutable_roles()->set_type(mesos::ACL::Entity::NONE); // No other principals can create volumes. mesos::ACL::CreateVolume* acl4 = acls.add_create_volumes(); acl4->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl4->mutable_roles()->set_type(mesos::ACL::Entity::NONE); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can create volumes for any role, so this request will pass. mesos::ACL::CreateVolume request1; request1.mutable_principals()->add_values("foo"); request1.mutable_roles()->add_values("awesome_role"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request1)); // Principal "bar" can create volumes for the "panda" role, // so this request will pass. mesos::ACL::CreateVolume request2; request2.mutable_principals()->add_values("bar"); request2.mutable_roles()->add_values("panda"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request2)); // Principal "bar" cannot create volumes for the "giraffe" role, // so this request will fail. mesos::ACL::CreateVolume request3; request3.mutable_principals()->add_values("bar"); request3.mutable_roles()->add_values("giraffe"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request3)); // Principal "baz" cannot create volumes for any role, // so this request will fail. mesos::ACL::CreateVolume request4; request4.mutable_principals()->add_values("baz"); request4.mutable_roles()->add_values("panda"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request4)); // Principal "zelda" 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 request will fail. mesos::ACL::CreateVolume request5; request5.mutable_principals()->add_values("zelda"); request5.mutable_roles()->add_values("panda"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request5)); }
// This tests the authorization of requests to set quotas. TYPED_TEST(AuthorizationTest, SetQuota) { ACLs acls; // "foo" principal can set quotas for all roles. mesos::ACL::SetQuota* acl1 = acls.add_set_quotas(); acl1->mutable_principals()->add_values("foo"); acl1->mutable_roles()->set_type(mesos::ACL::Entity::ANY); // "bar" principal can set quotas for "dev" role. mesos::ACL::SetQuota* acl2 = acls.add_set_quotas(); acl2->mutable_principals()->add_values("bar"); acl2->mutable_roles()->add_values("dev"); // Anyone can set quotas for "test" role. mesos::ACL::SetQuota* acl3 = acls.add_set_quotas(); acl3->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl3->mutable_roles()->add_values("test"); // No other principal can set quotas. mesos::ACL::SetQuota* acl4 = acls.add_set_quotas(); acl4->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl4->mutable_roles()->set_type(mesos::ACL::Entity::NONE); // Create an `Authorizer` with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can set quota for all roles, so requests 1 and 2 will pass. mesos::ACL::SetQuota request1; request1.mutable_principals()->add_values("foo"); request1.mutable_roles()->set_type(mesos::ACL::Entity::ANY); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request1)); mesos::ACL::SetQuota request2; request2.mutable_principals()->add_values("foo"); request2.mutable_roles()->add_values("prod"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request2)); // Principal "bar" can set quotas for role "dev", so this will pass. mesos::ACL::SetQuota request3; request3.mutable_principals()->add_values("bar"); request3.mutable_roles()->add_values("dev"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request3)); // Principal "bar" can only set quotas for role "dev", // so request 4 and 5 will fail. mesos::ACL::SetQuota request4; request4.mutable_principals()->add_values("bar"); request4.mutable_roles()->add_values("prod"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request4)); mesos::ACL::SetQuota request5; request5.mutable_principals()->add_values("bar"); request5.mutable_roles()->set_type(mesos::ACL::Entity::ANY); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request5)); // Anyone can set quotas for role "test", so request 6 will pass. mesos::ACL::SetQuota request6; request6.mutable_principals()->set_type(mesos::ACL::Entity::ANY); request6.mutable_roles()->add_values("test"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request6)); // 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. mesos::ACL::SetQuota request7; request7.mutable_principals()->add_values("jeff"); request7.mutable_roles()->set_type(mesos::ACL::Entity::ANY); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request7)); }
// This tests the authorization of ACLs used for destruction // operations on persistent volumes. TYPED_TEST(AuthorizationTest, DestroyVolume) { ACLs acls; // "foo" principal can destroy its own volumes. mesos::ACL::DestroyVolume* acl1 = acls.add_destroy_volumes(); acl1->mutable_principals()->add_values("foo"); acl1->mutable_creator_principals()->add_values("foo"); // "bar" principal cannot destroy anyone's volumes. mesos::ACL::DestroyVolume* acl2 = acls.add_destroy_volumes(); acl2->mutable_principals()->add_values("bar"); acl2->mutable_creator_principals()->set_type(mesos::ACL::Entity::NONE); // "ops" principal can destroy anyone's volumes. mesos::ACL::DestroyVolume* acl3 = acls.add_destroy_volumes(); acl3->mutable_principals()->add_values("ops"); acl3->mutable_creator_principals()->set_type(mesos::ACL::Entity::ANY); // No other principals can destroy volumes. mesos::ACL::DestroyVolume* acl4 = acls.add_destroy_volumes(); acl4->mutable_principals()->set_type(mesos::ACL::Entity::ANY); acl4->mutable_creator_principals()->set_type(mesos::ACL::Entity::NONE); // Create an Authorizer with the ACLs. Try<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can destroy its own volumes, so this will pass. mesos::ACL::DestroyVolume request1; request1.mutable_principals()->add_values("foo"); request1.mutable_creator_principals()->add_values("foo"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request1)); // Principal "bar" cannot destroy anyone's // volumes, so requests 2 and 3 will fail. mesos::ACL::DestroyVolume request2; request2.mutable_principals()->add_values("bar"); request2.mutable_creator_principals()->add_values("foo"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request2)); mesos::ACL::DestroyVolume request3; request3.mutable_principals()->add_values("bar"); request3.mutable_creator_principals()->add_values("bar"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request3)); // Principal "ops" can destroy anyone's volumes, // so requests 4 and 5 will succeed. mesos::ACL::DestroyVolume request4; request4.mutable_principals()->add_values("ops"); request4.mutable_creator_principals()->add_values("foo"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request4)); mesos::ACL::DestroyVolume request5; request5.mutable_principals()->add_values("ops"); request5.mutable_creator_principals()->add_values("bar"); request5.mutable_creator_principals()->add_values("ops"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request5)); // Principal "zelda" 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. mesos::ACL::DestroyVolume request6; request6.mutable_principals()->add_values("zelda"); request6.mutable_creator_principals()->add_values("foo"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request6)); }