TEST_F(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* acl2 = acls.add_register_frameworks(); acl2->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl2->mutable_roles()->add_values("analytics"); // Create an Authorizer with the ACLs. Try<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principal "foo" can be offered "analytics" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); // Principal "bar" cannot be offered "analytics" role's resources. mesos::ACL::RegisterFramework request2; request2.mutable_principals()->add_values("bar"); request2.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request2)); }
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* acl2 = acls.add_register_frameworks(); acl2->mutable_principals()->set_type(mesos::ACL::Entity::NONE); acl2->mutable_roles()->add_values("analytics"); // 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 be offered "analytics" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request)); // Principal "bar" cannot be offered "analytics" role's resources. mesos::ACL::RegisterFramework request2; request2.mutable_principals()->add_values("bar"); request2.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request2)); }
TYPED_TEST(AuthorizationTest, PrincipalNotOfferedAnyRoleRestrictive) { // A principal "foo" can be offered "analytics" role's resources. ACLs acls; acls.set_permissive(false); 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(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // Principal "foo" can be offered "analytics" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_TRUE(authorizer.get()->authorize(request)); // Principal "bar" cannot be offered "analytics" role's resources. mesos::ACL::RegisterFramework request2; request2.mutable_principals()->add_values("bar"); request2.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request2)); // Principal "bar" cannot be offered "ads" role's resources because no ACL. mesos::ACL::RegisterFramework request3; request3.mutable_principals()->add_values("bar"); request3.mutable_roles()->add_values("ads"); AWAIT_EXPECT_FALSE(authorizer.get()->authorize(request3)); }
TYPED_TEST(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<Authorizer*> create = TypeParam::create(); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); Try<Nothing> initialized = authorizer.get()->initialize(acls); ASSERT_SOME(initialized); // 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_TRUE(authorizer.get()->authorize(request)); }
TEST_F(AuthorizationTest, PrincipalNotOfferedAnyRoleRestrictive) { // A principal "foo" can be offered "analytics" role's resources. ACLs acls; acls.set_permissive(false); 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<Owned<LocalAuthorizer> > authorizer = LocalAuthorizer::create(acls); ASSERT_SOME(authorizer); // Principal "foo" can be offered "analytics" role's resources. mesos::ACL::RegisterFramework request; request.mutable_principals()->add_values("foo"); request.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_EQ(true, authorizer.get()->authorize(request)); // Principal "bar" cannot be offered "analytics" role's resources. mesos::ACL::RegisterFramework request2; request2.mutable_principals()->add_values("bar"); request2.mutable_roles()->add_values("analytics"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request2)); // Principal "bar" cannot be offered "ads" role's resources because no ACL. mesos::ACL::RegisterFramework request3; request3.mutable_principals()->add_values("bar"); request3.mutable_roles()->add_values("ads"); AWAIT_EXPECT_EQ(false, authorizer.get()->authorize(request3)); }
TYPED_TEST(AuthorizationTest, AnyPrincipalOfferedRole) { ACLs acls; { // Any principal can be offered "*" role's resources. 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(parameterize(acls)); ASSERT_SOME(create); Owned<Authorizer> authorizer(create.get()); // Principals "foo" and "bar" can be offered "*" 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("*"); 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("*"); AWAIT_EXPECT_TRUE(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, 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)); }
// 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::RegisterFramework* acl = acls.add_register_frameworks(); 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_EQ(true, authorizer.get()->authorize(request)); }
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(); } }
int main(int argc, char** argv) { Flags flags; Try<flags::Warnings> load = flags.load("MESOS_EXAMPLE_", argc, argv); if (load.isError()) { std::cerr << flags.usage(load.error()) << std::endl; return EXIT_FAILURE; } if (flags.help) { std::cout << flags.usage() << std::endl; return EXIT_SUCCESS; } mesos::internal::logging::initialize(argv[0], false); // Log any flag warnings (after logging is initialized). foreach (const flags::Warning& warning, load->warnings) { LOG(WARNING) << warning.message; } if (flags.qps <= 0.0) { EXIT(EXIT_FAILURE) << "Flag '--qps' needs to be greater than zero"; } LoadGeneratorScheduler scheduler(flags.qps, flags.duration); FrameworkInfo framework; framework.set_user(""); // Have Mesos fill in the current user. framework.set_principal(flags.principal); framework.set_name(FRAMEWORK_NAME); framework.set_checkpoint(flags.checkpoint); framework.add_roles(flags.role); framework.add_capabilities()->set_type( FrameworkInfo::Capability::RESERVATION_REFINEMENT); framework.set_checkpoint(flags.checkpoint); if (flags.master == "local") { // Configure master. os::setenv("MESOS_ROLES", flags.role); os::setenv("MESOS_AUTHENTICATE_FRAMEWORKS", stringify(flags.authenticate)); ACLs acls; ACL::RegisterFramework* acl = acls.add_register_frameworks(); acl->mutable_principals()->set_type(ACL::Entity::ANY); acl->mutable_roles()->add_values("*"); os::setenv("MESOS_ACLS", stringify(JSON::protobuf(acls))); } MesosSchedulerDriver* driver; if (flags.authenticate) { LOG(INFO) << "Enabling authentication for the framework"; Credential credential; credential.set_principal(flags.principal); if (flags.secret.isSome()) { credential.set_secret(flags.secret.get()); } driver = new MesosSchedulerDriver( &scheduler, framework, flags.master, credential); } else { driver = new MesosSchedulerDriver( &scheduler, framework, flags.master); } int status = driver->run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE; // Ensure that the driver process terminates. driver->stop(); delete driver; return status; }