You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ya...@apache.org on 2017/03/15 00:03:56 UTC
[2/2] mesos git commit: Test to ensure non-authorized users cannot
launch tasks on agents.
Test to ensure non-authorized users cannot launch tasks on agents.
Review: https://reviews.apache.org/r/55888/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c7817fb4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c7817fb4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c7817fb4
Branch: refs/heads/master
Commit: c7817fb461b21aa3eaca5721521e22dbab01df24
Parents: 9c3e4c7
Author: Anindya Sinha <an...@apple.com>
Authored: Tue Mar 14 17:00:43 2017 -0700
Committer: Jiang Yan Xu <xu...@apple.com>
Committed: Tue Mar 14 17:00:43 2017 -0700
----------------------------------------------------------------------
src/tests/slave_authorization_tests.cpp | 110 +++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/c7817fb4/src/tests/slave_authorization_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_authorization_tests.cpp b/src/tests/slave_authorization_tests.cpp
index 3657e0a..bf19336 100644
--- a/src/tests/slave_authorization_tests.cpp
+++ b/src/tests/slave_authorization_tests.cpp
@@ -479,6 +479,116 @@ TYPED_TEST(SlaveAuthorizerTest, AuthorizeRunTaskOnAgent)
}
+// This test verifies that a task is launched on the agent if the task
+// user is authorized based on `run_tasks` ACL configured on the agent
+// to only allow whitelisted users to run tasks on the agent.
+TYPED_TEST(SlaveAuthorizerTest, AuthorizeRunTaskOnAgent)
+{
+ // Get the current user.
+ Result<string> user = os::user();
+ ASSERT_SOME(user) << "Failed to get the current user name"
+ << (user.isError() ? ": " + user.error() : "");
+
+ Try<Owned<cluster::Master>> master = this->StartMaster();
+ ASSERT_SOME(master);
+
+ // Start a slave with `bar` and the current user being the only authorized
+ // users to launch tasks on the agent.
+ ACLs acls;
+ acls.set_permissive(false); // Restrictive.
+ mesos::ACL::RunTask* acl = acls.add_run_tasks();
+ acl->mutable_principals()->set_type(ACL::Entity::ANY);
+ acl->mutable_users()->add_values("bar");
+ acl->mutable_users()->add_values(user.get());
+
+ slave::Flags slaveFlags = this->CreateSlaveFlags();
+ slaveFlags.acls = acls;
+
+ Owned<MasterDetector> detector = master.get()->createDetector();
+ Try<Owned<cluster::Slave>> slave = this->StartSlave(
+ detector.get(), slaveFlags);
+ ASSERT_SOME(slave);
+
+ // Create a framework with user `foo`.
+ FrameworkInfo frameworkInfo = DEFAULT_FRAMEWORK_INFO;
+ frameworkInfo.set_user("foo");
+
+ MockScheduler sched;
+ MesosSchedulerDriver driver(
+ &sched, frameworkInfo, master.get()->pid, DEFAULT_CREDENTIAL);
+
+ Future<FrameworkID> frameworkId;
+ EXPECT_CALL(sched, registered(&driver, _, _))
+ .WillOnce(FutureArg<1>(&frameworkId));
+
+ Future<vector<Offer>> offers;
+ EXPECT_CALL(sched, resourceOffers(&driver, _))
+ .WillOnce(FutureArg<1>(&offers))
+ .WillRepeatedly(Return()); // Ignore subsequent offers.
+
+ driver.start();
+
+ // Framework is registered since the master admits frameworks of any user.
+ AWAIT_READY(frameworkId);
+
+ AWAIT_READY(offers);
+ EXPECT_FALSE(offers.get().empty());
+
+ Offer offer = offers.get()[0];
+
+ // Launch the first task with no user, so it defaults to the
+ // framework user `foo`.
+ TaskInfo task1 = createTask(
+ offer.slave_id(),
+ Resources::parse("cpus:1;mem:32").get(),
+ "sleep 1000");
+
+ // Launch the second task as the current user.
+ TaskInfo task2 = createTask(
+ offer.slave_id(),
+ Resources::parse("cpus:1;mem:32").get(),
+ "sleep 1000");
+ task2.mutable_command()->set_user(user.get());
+
+ // The first task should fail since the task user `foo` is not an
+ // authorized user that can launch a task. However, the second task
+ // should succeed.
+ Future<TaskStatus> status1;
+ Future<TaskStatus> status2;
+
+ EXPECT_CALL(sched, statusUpdate(&driver, _))
+ .WillOnce(FutureArg<1>(&status1))
+ .WillOnce(FutureArg<1>(&status2));
+
+ driver.acceptOffers(
+ {offer.id()},
+ {LAUNCH({task1, task2})});
+
+ // Wait for TASK_FAILED for 1st task, and TASK_RUNNING for 2nd task.
+ AWAIT_READY(status1);
+ AWAIT_READY(status2);
+
+ // Validate both the statuses. Note that the order of receiving the
+ // status updates for the 2 tasks is not deterministic.
+ hashmap<TaskID, TaskStatus> statuses {
+ {status1->task_id(), status1.get()},
+ {status2->task_id(), status2.get()}
+ };
+
+ ASSERT_TRUE(statuses.contains(task1.task_id()));
+ EXPECT_EQ(TASK_ERROR, statuses.at(task1.task_id()).state());
+ EXPECT_EQ(TaskStatus::SOURCE_SLAVE, statuses.at(task1.task_id()).source());
+ EXPECT_EQ(TaskStatus::REASON_TASK_UNAUTHORIZED,
+ statuses.at(task1.task_id()).reason());
+
+ ASSERT_TRUE(statuses.contains(task2.task_id()));
+ EXPECT_EQ(TASK_RUNNING, statuses.at(task2.task_id()).state());
+
+ driver.stop();
+ driver.join();
+}
+
+
// Parameterized fixture for agent-specific authorization tests. The
// path of the tested endpoint is passed as the only parameter.
class SlaveEndpointTest: