Repository: mesos
Updated Branches:
  refs/heads/master 2f14af542 -> da60d1c4e


Added the 'Secret' protobuf message.

This patch adds a new `Secret` protobuf message which
is designed to serve as a generic mechanism for passing
priviledged information within Mesos.

Review: https://reviews.apache.org/r/56052/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c74ab59c
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c74ab59c
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c74ab59c

Branch: refs/heads/master
Commit: c74ab59c5e7df2213739567b8b9e5fccdef37754
Parents: 2f14af5
Author: Greg Mann <[email protected]>
Authored: Fri Feb 17 11:47:36 2017 -0800
Committer: Vinod Kone <[email protected]>
Committed: Fri Feb 17 11:47:36 2017 -0800

----------------------------------------------------------------------
 include/mesos/mesos.proto            | 47 ++++++++++++++++++++++++
 include/mesos/v1/mesos.proto         | 47 ++++++++++++++++++++++++
 src/common/validation.cpp            | 38 +++++++++++++++++++
 src/common/validation.hpp            |  2 +
 src/tests/slave_validation_tests.cpp | 61 +++++++++++++++++++++++++++++++
 5 files changed, 195 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/c74ab59c/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index b3c022f..c2b2e6e 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -1956,6 +1956,53 @@ message Credentials {
 
 
 /**
+ * Secret used to pass privileged information. It is designed to provide
+ * pass-by-value or pass-by-reference semantics, where the REFERENCE type can 
be
+ * used by custom modules which interact with a secure back-end.
+ */
+message Secret
+{
+  enum Type {
+    UNKNOWN = 0;
+    REFERENCE = 1;
+    VALUE = 2;
+  }
+
+  // Can be used by modules to refer to a secret stored in a secure back-end.
+  // The `key` field is provided to permit reference to a single value within a
+  // secret containing arbitrary key-value pairs.
+  //
+  // For example, given a back-end secret store with a secret named
+  // "my-secret" containing the following key-value pairs:
+  //
+  //   {
+  //     "username": "my-user",
+  //     "password": "my-password
+  //   }
+  //
+  // the username could be referred to in a `Secret` by specifying
+  // "my-secret" for the `name` and "username" for the `key`.
+  message Reference
+  {
+    required string name = 1;
+    optional string key = 2;
+  }
+
+  // Used to pass the value of a secret.
+  message Value
+  {
+    required bytes data = 1;
+  }
+
+  optional Type type = 1;
+
+  // Only one of `reference` and `value` must be set.
+  optional Reference reference = 2;
+  optional Value value = 3;
+}
+
+
+/**
  * Rate (queries per second, QPS) limit for messages from a framework to 
master.
  * Strictly speaking they are the combined rate from all frameworks of the same
  * principal.

http://git-wip-us.apache.org/repos/asf/mesos/blob/c74ab59c/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index 1019902..c5b4897 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1955,6 +1955,53 @@ message Credentials {
 
 
 /**
+ * Secret used to pass privileged information. It is designed to provide
+ * pass-by-value or pass-by-reference semantics, where the REFERENCE type can 
be
+ * used by custom modules which interact with a secure back-end.
+ */
+message Secret
+{
+  enum Type {
+    UNKNOWN = 0;
+    REFERENCE = 1;
+    VALUE = 2;
+  }
+
+  // Can be used by modules to refer to a secret stored in a secure back-end.
+  // The `key` field is provided to permit reference to a single value within a
+  // secret containing arbitrary key-value pairs.
+  //
+  // For example, given a back-end secret store with a secret named
+  // "my-secret" containing the following key-value pairs:
+  //
+  //   {
+  //     "username": "my-user",
+  //     "password": "my-password
+  //   }
+  //
+  // the username could be referred to in a `Secret` by specifying
+  // "my-secret" for the `name` and "username" for the `key`.
+  message Reference
+  {
+    required string name = 1;
+    optional string key = 2;
+  }
+
+  // Used to pass the value of a secret.
+  message Value
+  {
+    required bytes data = 1;
+  }
+
+  optional Type type = 1;
+
+  // Only one of `reference` and `value` must be set.
+  optional Reference reference = 2;
+  optional Value value = 3;
+}
+
+
+/**
  * Rate (queries per second, QPS) limit for messages from a framework to 
master.
  * Strictly speaking they are the combined rate from all frameworks of the same
  * principal.

http://git-wip-us.apache.org/repos/asf/mesos/blob/c74ab59c/src/common/validation.cpp
----------------------------------------------------------------------
diff --git a/src/common/validation.cpp b/src/common/validation.cpp
index 0f1a022..2818261 100644
--- a/src/common/validation.cpp
+++ b/src/common/validation.cpp
@@ -20,6 +20,7 @@
 #include <cctype>
 
 #include <stout/foreach.hpp>
+#include <stout/unreachable.hpp>
 
 #include <stout/os/constants.hpp>
 
@@ -80,6 +81,43 @@ Option<Error> validateFrameworkID(const FrameworkID& 
frameworkId)
 }
 
 
+Option<Error> validateSecret(const Secret& secret)
+{
+  switch (secret.type()) {
+    case Secret::REFERENCE:
+      if (!secret.has_reference()) {
+        return Error(
+            "Secret of type REFERENCE must have the 'reference' field set");
+      }
+
+      if (secret.has_value()) {
+        return Error(
+            "Secret '" + secret.reference().name() + "' of type REFERENCE "
+            "must not have the 'value' field set");
+      }
+      break;
+
+    case Secret::VALUE:
+      if (!secret.has_value()) {
+        return Error("Secret of type VALUE must have the 'value' field set");
+      }
+
+      if (secret.has_reference()) {
+        return Error(
+            "Secret of type VALUE must not have the 'reference' field set");
+      }
+      break;
+
+    case Secret::UNKNOWN:
+      break;
+
+    UNREACHABLE();
+  }
+
+  return None();
+}
+
+
 // TODO(greggomann): Do more than just validate the `Environment`.
 Option<Error> validateCommandInfo(const CommandInfo& command)
 {

http://git-wip-us.apache.org/repos/asf/mesos/blob/c74ab59c/src/common/validation.hpp
----------------------------------------------------------------------
diff --git a/src/common/validation.hpp b/src/common/validation.hpp
index 7946f06..caba07b 100644
--- a/src/common/validation.hpp
+++ b/src/common/validation.hpp
@@ -41,6 +41,8 @@ Option<Error> validateSlaveID(const SlaveID& slaveId);
 
 Option<Error> validateFrameworkID(const FrameworkID& frameworkId);
 
+Option<Error> validateSecret(const Secret& secret);
+
 Option<Error> validateCommandInfo(const CommandInfo& command);
 
 } // namespace validation {

http://git-wip-us.apache.org/repos/asf/mesos/blob/c74ab59c/src/tests/slave_validation_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/slave_validation_tests.cpp 
b/src/tests/slave_validation_tests.cpp
index 3d17799..96218e8 100644
--- a/src/tests/slave_validation_tests.cpp
+++ b/src/tests/slave_validation_tests.cpp
@@ -32,6 +32,8 @@
 
 namespace validation = mesos::internal::slave::validation;
 
+using mesos::internal::common::validation::validateSecret;
+
 using mesos::internal::slave::Slave;
 
 namespace mesos {
@@ -86,6 +88,65 @@ TEST(AgentValidationTest, ContainerID)
 }
 
 
+// Tests that the common validation code for the
+// `Secret` message works as expected.
+TEST(AgentValidationTest, Secret)
+{
+  // Test a secret of VALUE type.
+  {
+    Secret secret;
+    secret.set_type(Secret::VALUE);
+
+    Option<Error> error = validateSecret(secret);
+    EXPECT_SOME(error);
+    EXPECT_EQ(
+        "Secret of type VALUE must have the 'value' field set",
+        error->message);
+
+    secret.mutable_value()->set_data("SECRET_VALUE");
+    secret.mutable_reference()->set_name("SECRET_NAME");
+
+    error = validateSecret(secret);
+    EXPECT_SOME(error);
+    EXPECT_EQ(
+        "Secret of type VALUE must not have the 'reference' field set",
+        error->message);
+
+    // Test the valid case.
+    secret.clear_reference();
+    error = validateSecret(secret);
+    EXPECT_NONE(error);
+  }
+
+  // Test a secret of REFERENCE type.
+  {
+    Secret secret;
+    secret.set_type(Secret::REFERENCE);
+
+    Option<Error> error = validateSecret(secret);
+    EXPECT_SOME(error);
+    EXPECT_EQ(
+        "Secret of type REFERENCE must have the 'reference' field set",
+        error->message);
+
+    secret.mutable_reference()->set_name("SECRET_NAME");
+    secret.mutable_value()->set_data("SECRET_VALUE");
+
+    error = validateSecret(secret);
+    EXPECT_SOME(error);
+    EXPECT_EQ(
+        "Secret 'SECRET_NAME' of type REFERENCE "
+        "must not have the 'value' field set",
+        error->message);
+
+    // Test the valid case.
+    secret.clear_value();
+    error = validateSecret(secret);
+    EXPECT_NONE(error);
+  }
+}
+
+
 TEST(AgentCallValidationTest, LaunchNestedContainer)
 {
   // Missing `launch_nested_container`.

Reply via email to