You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by sa...@apache.org on 2017/06/20 21:45:35 UTC

aurora git commit: Allow custom Thrift method interceptors to be injected via Guice modules

Repository: aurora
Updated Branches:
  refs/heads/master 58ee6e485 -> e80002abe


Allow custom Thrift method interceptors to be injected via Guice modules

Allow for custom Thrift method interceptors to be injected via Guice modules. Cluster operators might use this feature to inject interceptors that only allow certain roles to call certain endpoints, or to dynamically check if a job should be able to use a constraint.

Testing Done:
Unit + integration tests pass.

Injected a custom module on a Vagrant box -- added a simple class and included the module when starting up the scheduler:
```
diff --git a/examples/vagrant/upstart/aurora-scheduler.conf b/examples/vagrant/upstart/aurora-scheduler.conf
index 63fcc87..18521af 100644
--- a/examples/vagrant/upstart/aurora-scheduler.conf
+++ b/examples/vagrant/upstart/aurora-scheduler.conf
@@ -56,4 +56,5 @@ exec bin/aurora-scheduler \
   -allow_container_volumes=true \
   -offer_filter_duration=0secs \
   -mesos_driver=V1_DRIVER \
-  -unavailability_threshold=1mins
+  -unavailability_threshold=1mins \
+  -thrift_method_interceptor_modules=org.apache.aurora.scheduler.thrift.aop.ThriftWhitelistInterceptorModule
diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/aop/ThriftWhitelistInterceptorModule.java b/src/main/java/org/apache/aurora/scheduler/thrift/aop/ThriftWhitelistInterceptorModule.java
new file mode 100644
index 0000000..4296f81
--- /dev/null
+++ b/src/main/java/org/apache/aurora/scheduler/thrift/aop/ThriftWhitelistInterceptorModule.java
@@ -0,0 +1,46 @@
+package org.apache.aurora.scheduler.thrift.aop;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.inject.AbstractModule;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.apache.aurora.gen.JobConfiguration;
+import org.apache.aurora.gen.Response;
+import org.apache.aurora.gen.ResponseCode;
+import org.apache.aurora.gen.ResponseDetail;
+import org.apache.aurora.gen.TaskConfig;
+
+/** Module that checks if a role is allowed to do a specific action */
+public class ThriftWhitelistInterceptorModule extends AbstractModule {
+
+  @Override
+  protected void configure() {
+    AopModule.bindThriftDecorator(binder(), AopModule.THRIFT_IFACE_MATCHER,
+        new ThriftWhitelistInterceptor());
+  }
+
+  private class ThriftWhitelistInterceptor implements MethodInterceptor {
+
+    @Override
+    public Object invoke(MethodInvocation invocation) throws Throwable {
+      Object[] args = invocation.getArguments();
+      switch(invocation.getMethod().getName()) {
+        case "createJob":
+          JobConfiguration config = (JobConfiguration) args[0];
+          TaskConfig task = config.getTaskConfig();
+          String role = task.getJob().getRole();
+          if (role.equals("vagrant")) {
+            ResponseDetail detail = new ResponseDetail("Test response.");
+            List<ResponseDetail> details = new ArrayList<>();
+            details.add(detail);
+            return new Response(ResponseCode.ERROR, null, details);
+          }
+      }
+
+      return (Response) invocation.proceed();
+    }
+  }
+}
```

Tried to create a job with two different roles:
```
vagrant@aurora:~$ aurora job create devcluster/vagrant/test/http_example /vagrant/src/test/sh/org/apache/aurora/e2e/http/http_example.aurora
 INFO] Creating job http_example
Job creation failed due to error:
	Test response.

vagrant@aurora:~$ aurora job create devcluster/www-data/test/http_example /vagrant/src/test/sh/org/apache/aurora/e2e/http/http_example.aurora
 INFO] Creating job http_example
 INFO] Checking status of devcluster/www-data/test/http_example
Job create succeeded: job url=http://aurora.local:8081/scheduler/www-data/test/http_example
```

Reviewed at https://reviews.apache.org/r/60173/


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

Branch: refs/heads/master
Commit: e80002abe48ce633be45943b99dbb9ee25ea2939
Parents: 58ee6e4
Author: Jordan Ly <jo...@gmail.com>
Authored: Tue Jun 20 14:45:19 2017 -0700
Committer: Santhosh Kumar <ss...@twitter.com>
Committed: Tue Jun 20 14:45:19 2017 -0700

----------------------------------------------------------------------
 RELEASE-NOTES.md                                |  2 ++
 docs/reference/scheduler-configuration.md       |  2 ++
 .../aurora/scheduler/thrift/aop/AopModule.java  | 23 +++++++++++++++-----
 3 files changed, 22 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/e80002ab/RELEASE-NOTES.md
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index e032f79..fd2618f 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -13,6 +13,8 @@
   steps (adding up to a total of 10 seconds as there are 2 steps). The overall waiting period is
   bounded by the executor's stop timeout, which can be configured using the executor's
   `stop_timeout_in_secs` flag.
+- Added the `thrift_method_interceptor_modules` scheduler flag that lets cluster operators inject
+  custom Thrift method interceptors.
 
 0.18.0
 ======

http://git-wip-us.apache.org/repos/asf/aurora/blob/e80002ab/docs/reference/scheduler-configuration.md
----------------------------------------------------------------------
diff --git a/docs/reference/scheduler-configuration.md b/docs/reference/scheduler-configuration.md
index 3d53c5a..4e3f907 100644
--- a/docs/reference/scheduler-configuration.md
+++ b/docs/reference/scheduler-configuration.md
@@ -248,6 +248,8 @@ Optional flags:
 	A comma separated list of additional resources to copy into the sandbox.Note: if thermos_executor_path is not the thermos_executor.pex file itself, this must include it.
 -thermos_home_in_sandbox (default false)
 	If true, changes HOME to the sandbox before running the executor. This primarily has the effect of causing the executor and runner to extract themselves into the sandbox.
+-thrift_method_interceptor_modules (default [])
+	Additional Guice modules for intercepting Thrift method calls.
 -transient_task_state_timeout (default (5, mins))
 	The amount of time after which to treat a task stuck in a transient state as LOST.
 -use_beta_db_task_store (default false)

http://git-wip-us.apache.org/repos/asf/aurora/blob/e80002ab/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java b/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
index f59ee1a..ef5edf6 100644
--- a/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
@@ -13,13 +13,18 @@
  */
 package org.apache.aurora.scheduler.thrift.aop;
 
-import com.google.common.annotations.VisibleForTesting;
+import java.util.Set;
+
+import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
+import com.google.inject.Module;
 import com.google.inject.matcher.Matcher;
 import com.google.inject.matcher.Matchers;
 
 import org.aopalliance.intercept.MethodInterceptor;
+import org.apache.aurora.common.args.Arg;
+import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.gen.Response;
 import org.apache.aurora.scheduler.thrift.auth.DecoratedThrift;
 
@@ -28,14 +33,18 @@ import org.apache.aurora.scheduler.thrift.auth.DecoratedThrift;
  */
 public class AopModule extends AbstractModule {
 
-  private static final Matcher<? super Class<?>> THRIFT_IFACE_MATCHER =
+  @CmdLine(name = "thrift_method_interceptor_modules",
+      help = "Custom Guice module(s) to provide additional Thrift method interceptors.")
+  private static final Arg<Set<Module>> METHOD_INTERCEPTOR_MODULES = Arg.create(ImmutableSet.of());
+
+  public static final Matcher<? super Class<?>> THRIFT_IFACE_MATCHER =
       Matchers.subclassesOf(AnnotatedAuroraAdmin.class)
           .and(Matchers.annotatedWith(DecoratedThrift.class));
 
   @Override
   protected void configure() {
     // Layer ordering:
-    // APIVersion -> Log -> StatsExporter -> SchedulerThriftInterface
+    // APIVersion -> Log -> StatsExporter -> custom interceptors -> SchedulerThriftInterface
 
     // It's important for this interceptor to be registered first to ensure it's at the 'top' of
     // the stack and the standard message is always applied.
@@ -43,14 +52,18 @@ public class AopModule extends AbstractModule {
 
     bindThriftDecorator(new LoggingInterceptor());
     bindThriftDecorator(new ThriftStatsExporterInterceptor());
+
+    // Install custom interceptor modules
+    for (Module module : METHOD_INTERCEPTOR_MODULES.get()) {
+      install(module);
+    }
   }
 
   private void bindThriftDecorator(MethodInterceptor interceptor) {
     bindThriftDecorator(binder(), THRIFT_IFACE_MATCHER, interceptor);
   }
 
-  @VisibleForTesting
-  static void bindThriftDecorator(
+  public static void bindThriftDecorator(
       Binder binder,
       Matcher<? super Class<?>> classMatcher,
       MethodInterceptor interceptor) {