You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2017/11/30 00:04:14 UTC
[03/13] mesos git commit: Generated authentication tokens for local
resource providers.
Generated authentication tokens for local resource providers.
`LocalResourceProviderDaemon` now uses `Slave::secretGenerater` to
generate an authentication token for each local resource provider. The
authentication token can then be used to call the V1 agent API. In order
to generate the tokens, `LocalResourceProviderDaemon::load()` is now an
asynchronous function.
Review: https://reviews.apache.org/r/62636/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/9bee2c30
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/9bee2c30
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/9bee2c30
Branch: refs/heads/master
Commit: 9bee2c300e2443e875a26858453563cedf438234
Parents: 957b0c0
Author: Chun-Hung Hsiao <ch...@mesosphere.io>
Authored: Wed Nov 29 15:30:33 2017 -0800
Committer: Jie Yu <yu...@gmail.com>
Committed: Wed Nov 29 15:30:33 2017 -0800
----------------------------------------------------------------------
src/resource_provider/daemon.cpp | 91 +++++++++++++++++++++----
src/resource_provider/daemon.hpp | 8 ++-
src/resource_provider/local.cpp | 5 +-
src/resource_provider/local.hpp | 3 +-
src/resource_provider/storage/provider.cpp | 21 +++---
src/resource_provider/storage/provider.hpp | 6 +-
src/slave/slave.cpp | 15 ++--
7 files changed, 115 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/resource_provider/daemon.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/daemon.cpp b/src/resource_provider/daemon.cpp
index 80b5c71..339216b 100644
--- a/src/resource_provider/daemon.cpp
+++ b/src/resource_provider/daemon.cpp
@@ -22,6 +22,7 @@
#include <mesos/type_utils.hpp>
+#include <process/defer.hpp>
#include <process/dispatch.hpp>
#include <process/id.hpp>
#include <process/process.hpp>
@@ -36,6 +37,8 @@
#include <stout/protobuf.hpp>
#include <stout/try.hpp>
+#include "common/validation.hpp"
+
#include "resource_provider/local.hpp"
namespace http = process::http;
@@ -49,11 +52,14 @@ using process::Owned;
using process::Process;
using process::ProcessBase;
+using process::defer;
using process::dispatch;
using process::spawn;
using process::terminate;
using process::wait;
+using process::http::authentication::Principal;
+
namespace mesos {
namespace internal {
@@ -64,11 +70,13 @@ public:
LocalResourceProviderDaemonProcess(
const http::URL& _url,
const string& _workDir,
- const Option<string>& _configDir)
+ const Option<string>& _configDir,
+ SecretGenerator* _secretGenerator)
: ProcessBase(process::ID::generate("local-resource-provider-daemon")),
url(_url),
workDir(_workDir),
- configDir(_configDir) {}
+ configDir(_configDir),
+ secretGenerator(_secretGenerator) {}
LocalResourceProviderDaemonProcess(
const LocalResourceProviderDaemonProcess& other) = delete;
@@ -95,9 +103,12 @@ private:
Future<Nothing> launch(const string& type, const string& name);
+ Future<Option<string>> generateAuthToken(const ResourceProviderInfo& info);
+
const http::URL url;
const string workDir;
const Option<string> configDir;
+ SecretGenerator* const secretGenerator;
Option<SlaveID> slaveId;
hashmap<string, hashmap<string, ProviderData>> providers;
@@ -203,26 +214,69 @@ Future<Nothing> LocalResourceProviderDaemonProcess::launch(
CHECK_SOME(slaveId);
CHECK(providers[type].contains(name));
- ProviderData& data = providers[type].at(name);
+ return generateAuthToken(providers[type].at(name).info)
+ .then(defer(self(), [=](
+ const Option<string>& authToken) -> Future<Nothing> {
+ ProviderData& data = providers[type].at(name);
+
+ Try<Owned<LocalResourceProvider>> provider =
+ LocalResourceProvider::create(url, data.info, authToken);
+
+ if (provider.isError()) {
+ return Failure(
+ "Failed to create resource provider with type '" + type +
+ "' and name '" + name + "': " + provider.error());
+ }
+
+ data.provider = provider.get();
+
+ return Nothing();
+ }));
+}
- Try<Owned<LocalResourceProvider>> provider =
- LocalResourceProvider::create(url, data.info);
- if (provider.isError()) {
+// Generates a secret for local resource provider authentication if needed.
+Future<Option<string>> LocalResourceProviderDaemonProcess::generateAuthToken(
+ const ResourceProviderInfo& info)
+{
+ if (secretGenerator == nullptr) {
+ return None();
+ }
+
+ Try<Principal> principal = LocalResourceProvider::principal(info);
+
+ if (principal.isError()) {
return Failure(
- "Failed to create resource provider with type '" + type +
- "' and name '" + name + "': " + provider.error());
+ "Failed to generate resource provider principal with type '" +
+ info.type() + "' and name '" + info.name() + "': " +
+ principal.error());
}
- data.provider = provider.get();
+ return secretGenerator->generate(principal.get())
+ .then(defer(self(), [](const Secret& secret) -> Future<Option<string>> {
+ Option<Error> error = common::validation::validateSecret(secret);
- return Nothing();
+ if (error.isSome()) {
+ return Failure(
+ "Failed to validate generated secret: " + error->message);
+ } else if (secret.type() != Secret::VALUE) {
+ return Failure(
+ "Expecting generated secret to be of VALUE type instead of " +
+ stringify(secret.type()) + " type; " +
+ "only VALUE type secrets are supported at this time");
+ }
+
+ CHECK(secret.has_value());
+
+ return secret.value().data();
+ }));
}
Try<Owned<LocalResourceProviderDaemon>> LocalResourceProviderDaemon::create(
const http::URL& url,
- const slave::Flags& flags)
+ const slave::Flags& flags,
+ SecretGenerator* secretGenerator)
{
// We require that the config directory exists to create a daemon.
Option<string> configDir = flags.resource_provider_config_dir;
@@ -230,15 +284,24 @@ Try<Owned<LocalResourceProviderDaemon>> LocalResourceProviderDaemon::create(
return Error("Config directory '" + configDir.get() + "' does not exist");
}
- return new LocalResourceProviderDaemon(url, flags.work_dir, configDir);
+ return new LocalResourceProviderDaemon(
+ url,
+ flags.work_dir,
+ configDir,
+ secretGenerator);
}
LocalResourceProviderDaemon::LocalResourceProviderDaemon(
const http::URL& url,
const string& workDir,
- const Option<string>& configDir)
- : process(new LocalResourceProviderDaemonProcess(url, workDir, configDir))
+ const Option<string>& configDir,
+ SecretGenerator* secretGenerator)
+ : process(new LocalResourceProviderDaemonProcess(
+ url,
+ workDir,
+ configDir,
+ secretGenerator))
{
spawn(CHECK_NOTNULL(process.get()));
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/resource_provider/daemon.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/daemon.hpp b/src/resource_provider/daemon.hpp
index 8668cd1..14bc41f 100644
--- a/src/resource_provider/daemon.hpp
+++ b/src/resource_provider/daemon.hpp
@@ -21,6 +21,8 @@
#include <mesos/mesos.hpp>
+#include <mesos/authentication/secret_generator.hpp>
+
#include <process/http.hpp>
#include <process/owned.hpp>
@@ -44,7 +46,8 @@ class LocalResourceProviderDaemon
public:
static Try<process::Owned<LocalResourceProviderDaemon>> create(
const process::http::URL& url,
- const slave::Flags& flags);
+ const slave::Flags& flags,
+ SecretGenerator* secretGenerator);
~LocalResourceProviderDaemon();
@@ -60,7 +63,8 @@ private:
LocalResourceProviderDaemon(
const process::http::URL& url,
const std::string& workDir,
- const Option<std::string>& configDir);
+ const Option<std::string>& configDir,
+ SecretGenerator* secretGenerator);
process::Owned<LocalResourceProviderDaemonProcess> process;
};
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/resource_provider/local.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/local.cpp b/src/resource_provider/local.cpp
index ff9819e..42b6b62 100644
--- a/src/resource_provider/local.cpp
+++ b/src/resource_provider/local.cpp
@@ -34,7 +34,8 @@ namespace internal {
Try<Owned<LocalResourceProvider>> LocalResourceProvider::create(
const http::URL& url,
- const ResourceProviderInfo& info)
+ const ResourceProviderInfo& info,
+ const Option<string>& authToken)
{
// TODO(jieyu): Document the built-in local resource providers.
const hashmap<string, lambda::function<decltype(create)>> creators = {
@@ -44,7 +45,7 @@ Try<Owned<LocalResourceProvider>> LocalResourceProvider::create(
};
if (creators.contains(info.type())) {
- return creators.at(info.type())(url, info);
+ return creators.at(info.type())(url, info, authToken);
}
return Error("Unknown local resource provider type '" + info.type() + "'");
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/resource_provider/local.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/local.hpp b/src/resource_provider/local.hpp
index 40c8f98..d1dfc90 100644
--- a/src/resource_provider/local.hpp
+++ b/src/resource_provider/local.hpp
@@ -33,7 +33,8 @@ class LocalResourceProvider
public:
static Try<process::Owned<LocalResourceProvider>> create(
const process::http::URL& url,
- const ResourceProviderInfo& info);
+ const ResourceProviderInfo& info,
+ const Option<std::string>& authToken);
static Try<process::http::authentication::Principal> principal(
const ResourceProviderInfo& info);
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/resource_provider/storage/provider.cpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/provider.cpp b/src/resource_provider/storage/provider.cpp
index 6817df5..14d824c 100644
--- a/src/resource_provider/storage/provider.cpp
+++ b/src/resource_provider/storage/provider.cpp
@@ -94,12 +94,14 @@ class StorageLocalResourceProviderProcess
{
public:
explicit StorageLocalResourceProviderProcess(
- const process::http::URL& _url,
- const ResourceProviderInfo& _info)
+ const http::URL& _url,
+ const ResourceProviderInfo& _info,
+ const Option<string>& _authToken)
: ProcessBase(process::ID::generate("storage-local-resource-provider")),
url(_url),
contentType(ContentType::PROTOBUF),
- info(_info) {}
+ info(_info),
+ authToken(_authToken) {}
StorageLocalResourceProviderProcess(
const StorageLocalResourceProviderProcess& other) = delete;
@@ -118,6 +120,7 @@ private:
const ContentType contentType;
ResourceProviderInfo info;
Owned<v1::resource_provider::Driver> driver;
+ Option<string> authToken;
};
@@ -165,7 +168,7 @@ void StorageLocalResourceProviderProcess::initialize()
defer(self(), &Self::disconnected),
defer(self(), [this](queue<v1::resource_provider::Event> events) {
while(!events.empty()) {
- const v1::resource_provider::Event& event = events.front();
+ const v1::resource_provider::Event& event = events.front();
received(devolve(event));
events.pop();
}
@@ -176,7 +179,8 @@ void StorageLocalResourceProviderProcess::initialize()
Try<Owned<LocalResourceProvider>> StorageLocalResourceProvider::create(
const process::http::URL& url,
- const ResourceProviderInfo& info)
+ const ResourceProviderInfo& info,
+ const Option<string>& authToken)
{
// Verify that the name follows Java package naming convention.
// TODO(chhsiao): We should move this check to a validation function
@@ -188,7 +192,7 @@ Try<Owned<LocalResourceProvider>> StorageLocalResourceProvider::create(
}
return Owned<LocalResourceProvider>(
- new StorageLocalResourceProvider(url, info));
+ new StorageLocalResourceProvider(url, info, authToken));
}
@@ -203,8 +207,9 @@ Try<Principal> StorageLocalResourceProvider::principal(
StorageLocalResourceProvider::StorageLocalResourceProvider(
const process::http::URL& url,
- const ResourceProviderInfo& info)
- : process(new StorageLocalResourceProviderProcess(url, info))
+ const ResourceProviderInfo& info,
+ const Option<string>& authToken)
+ : process(new StorageLocalResourceProviderProcess(url, info, authToken))
{
spawn(CHECK_NOTNULL(process.get()));
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/resource_provider/storage/provider.hpp
----------------------------------------------------------------------
diff --git a/src/resource_provider/storage/provider.hpp b/src/resource_provider/storage/provider.hpp
index b61b41b..720b061 100644
--- a/src/resource_provider/storage/provider.hpp
+++ b/src/resource_provider/storage/provider.hpp
@@ -38,7 +38,8 @@ class StorageLocalResourceProvider : public LocalResourceProvider
public:
static Try<process::Owned<LocalResourceProvider>> create(
const process::http::URL& url,
- const mesos::ResourceProviderInfo& info);
+ const mesos::ResourceProviderInfo& info,
+ const Option<std::string>& authToken);
static Try<process::http::authentication::Principal> principal(
const mesos::ResourceProviderInfo& info);
@@ -54,7 +55,8 @@ public:
private:
explicit StorageLocalResourceProvider(
const process::http::URL& url,
- const mesos::ResourceProviderInfo& info);
+ const mesos::ResourceProviderInfo& info,
+ const Option<std::string>& authToken);
process::Owned<StorageLocalResourceProviderProcess> process;
};
http://git-wip-us.apache.org/repos/asf/mesos/blob/9bee2c30/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index e156683..554a2da 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -429,7 +429,10 @@ void Slave::initialize()
self().id + "/api/v1/resource_provider");
Try<Owned<LocalResourceProviderDaemon>> _localResourceProviderDaemon =
- LocalResourceProviderDaemon::create(localResourceProviderURL, flags);
+ LocalResourceProviderDaemon::create(
+ localResourceProviderURL,
+ flags,
+ secretGenerator);
if (_localResourceProviderDaemon.isError()) {
EXIT(EXIT_FAILURE)
@@ -1227,7 +1230,8 @@ void Slave::registered(
CHECK_SOME(state::checkpoint(path, info_));
}
- // Start the local resource providers daemon once we have the slave id.
+ // We start the local resource providers daemon once the agent is
+ // running, so the resource providers can use the agent API.
localResourceProviderDaemon->start(info.id());
// Setup a timer so that the agent attempts to re-register if it
@@ -1333,6 +1337,10 @@ void Slave::reregistered(
state = RUNNING;
taskStatusUpdateManager->resume(); // Resume status updates.
+ // We start the local resource providers daemon once the agent is
+ // running, so the resource providers can use the agent API.
+ localResourceProviderDaemon->start(info.id());
+
// Setup a timer so that the agent attempts to re-register if it
// doesn't receive a ping from the master for an extended period
// of time. This needs to be done once re-registered, in case we
@@ -6328,9 +6336,6 @@ Future<Nothing> Slave::recover(const Try<state::State>& state)
} else {
info = slaveState->info.get(); // Recover the slave info.
- // Start the local resource providers daemon once we have the slave id.
- localResourceProviderDaemon->start(info.id());
-
// Recover the frameworks.
foreachvalue (const FrameworkState& frameworkState,
slaveState->frameworks) {