Added validation for UUID's to master/agent validation helpers.

This change adds logic to the master/agent validation helpers
to see if the status update acknowledgments have a valid UUID
set conforming to one of the supported versions.

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


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

Branch: refs/heads/master
Commit: e3a825a5c172fb75227909b964db924543c83f75
Parents: d260aeb
Author: Deshna Jain <deshna...@gmail.com>
Authored: Mon Jun 20 15:47:09 2016 -0700
Committer: Vinod Kone <vinodk...@gmail.com>
Committed: Mon Jun 20 15:47:09 2016 -0700

----------------------------------------------------------------------
 src/master/validation.cpp              |  8 ++-
 src/slave/validation.cpp               |  6 ++
 src/tests/scheduler_http_api_tests.cpp | 87 +++++++++++++++++++++++++++++
 3 files changed, 100 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/e3a825a5/src/master/validation.cpp
----------------------------------------------------------------------
diff --git a/src/master/validation.cpp b/src/master/validation.cpp
index 7f139fb..9120b71 100644
--- a/src/master/validation.cpp
+++ b/src/master/validation.cpp
@@ -301,11 +301,17 @@ Option<Error> validate(
       }
       return None();
 
-    case mesos::scheduler::Call::ACKNOWLEDGE:
+    case mesos::scheduler::Call::ACKNOWLEDGE: {
       if (!call.has_acknowledge()) {
         return Error("Expecting 'acknowledge' to be present");
       }
+
+      Try<UUID> uuid = UUID::fromBytes(call.acknowledge().uuid());
+      if (uuid.isError()) {
+        return uuid.error();
+      }
       return None();
+    }
 
     case mesos::scheduler::Call::RECONCILE:
       if (!call.has_reconcile()) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/e3a825a5/src/slave/validation.cpp
----------------------------------------------------------------------
diff --git a/src/slave/validation.cpp b/src/slave/validation.cpp
index 86e95a2..610829e 100644
--- a/src/slave/validation.cpp
+++ b/src/slave/validation.cpp
@@ -19,6 +19,7 @@
 #include <mesos/agent/agent.hpp>
 
 #include <stout/unreachable.hpp>
+#include <stout/uuid.hpp>
 
 #include "slave/validation.hpp"
 
@@ -142,6 +143,11 @@ Option<Error> validate(const mesos::executor::Call& call)
         return Error("Expecting 'uuid' to be present");
       }
 
+      Try<UUID> uuid = UUID::fromBytes(status.uuid()).get();
+      if (uuid.isError()) {
+        return uuid.error();
+      }
+
       if (status.has_executor_id() &&
           status.executor_id().value()
           != call.executor_id().value()) {

http://git-wip-us.apache.org/repos/asf/mesos/blob/e3a825a5/src/tests/scheduler_http_api_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/scheduler_http_api_tests.cpp 
b/src/tests/scheduler_http_api_tests.cpp
index c12205f..80a2ef0 100644
--- a/src/tests/scheduler_http_api_tests.cpp
+++ b/src/tests/scheduler_http_api_tests.cpp
@@ -935,6 +935,93 @@ TEST_P(SchedulerHttpApiTest, TeardownWrongStreamId)
   }
 }
 
+
+// This test verifies that the scheduler will receive a `BadRequest` response
+// when it tries to acknowledge a status update with a malformed UUID.
+TEST_P(SchedulerHttpApiTest, MalformedUUID)
+{
+  Try<Owned<cluster::Master>> master = StartMaster();
+  ASSERT_SOME(master);
+
+  // Retrieve the parameter passed as content type to this test.
+  const string contentType = GetParam();
+
+  process::http::Headers headers = createBasicAuthHeaders(DEFAULT_CREDENTIAL);
+  headers["Accept"] = contentType;
+  v1::FrameworkID frameworkId;
+  string streamId;
+
+  // Subscribe once to get a valid stream ID.
+  {
+    Call call;
+    call.set_type(Call::SUBSCRIBE);
+
+    Call::Subscribe* subscribe = call.mutable_subscribe();
+    subscribe->mutable_framework_info()->CopyFrom(DEFAULT_V1_FRAMEWORK_INFO);
+
+    Future<Response> response = process::http::streaming::post(
+        master.get()->pid,
+        "api/v1/scheduler",
+        headers,
+        serialize(call, contentType),
+        contentType);
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(OK().status, response);
+    ASSERT_EQ(Response::PIPE, response.get().type);
+    ASSERT_TRUE(response.get().headers.contains("Mesos-Stream-Id"));
+
+    streamId = response.get().headers.at("Mesos-Stream-Id");
+
+    Option<Pipe::Reader> reader = response.get().reader;
+    ASSERT_SOME(reader);
+
+    auto deserializer = lambda::bind(
+        &SchedulerHttpApiTest::deserialize, this, contentType, lambda::_1);
+
+    Reader<Event> responseDecoder(Decoder<Event>(deserializer), reader.get());
+
+    Future<Result<Event>> event = responseDecoder.read();
+    AWAIT_READY(event);
+    ASSERT_SOME(event.get());
+
+    // Check that the event type is subscribed and the framework ID is set.
+    ASSERT_EQ(Event::SUBSCRIBED, event.get().get().type());
+
+    frameworkId = event.get().get().subscribed().framework_id();
+    EXPECT_NE("", frameworkId.value());
+  }
+
+  // Make an acknowledge call with a malformed UUID. This should result in a
+  // `BadResponse`.
+  {
+    headers["Mesos-Stream-Id"] = streamId;
+
+    Call call;
+    call.set_type(Call::ACKNOWLEDGE);
+
+    // Set the framework ID in the subscribe call.
+    call.mutable_framework_id()->CopyFrom(frameworkId);
+
+    Call::Acknowledge* acknowledge = call.mutable_acknowledge();
+    acknowledge->mutable_task_id()->set_value("task-id");
+    acknowledge->mutable_agent_id()->set_value("agent-id");
+
+    // Set a malformed uuid.
+    acknowledge->set_uuid("bad-uuid");
+
+    Future<Response> response = process::http::post(
+        master.get()->pid,
+        "api/v1/scheduler",
+        headers,
+        serialize(call, contentType),
+        contentType);
+
+    AWAIT_EXPECT_RESPONSE_STATUS_EQ(BadRequest().status, response);
+    AWAIT_EXPECT_RESPONSE_BODY_EQ(
+        "Failed to validate scheduler::Call: Not a valid UUID", response);
+  }
+}
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

Reply via email to