aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wfar...@apache.org
Subject svn commit: r1719807 [2/3] - in /aurora/site: ./ publish/ publish/documentation/0.10.0/design/ publish/documentation/0.10.0/design/command-hooks/ publish/documentation/0.5.0-incubating/design/ publish/documentation/0.5.0-incubating/design/command-hooks...
Date Sun, 13 Dec 2015 17:04:12 GMT
Added: aurora/site/publish/documentation/0.7.0-incubating/design/command-hooks/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/0.7.0-incubating/design/command-hooks/index.html?rev=1719807&view=auto
==============================================================================
--- aurora/site/publish/documentation/0.7.0-incubating/design/command-hooks/index.html (added)
+++ aurora/site/publish/documentation/0.7.0-incubating/design/command-hooks/index.html Sun Dec 13 17:04:12 2015
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+	<title>Apache Aurora</title>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
+    <link href="/assets/css/main.css" rel="stylesheet">
+	<!-- Analytics -->
+	<script type="text/javascript">
+		  var _gaq = _gaq || [];
+		  _gaq.push(['_setAccount', 'UA-45879646-1']);
+		  _gaq.push(['_setDomainName', 'apache.org']);
+		  _gaq.push(['_trackPageview']);
+
+		  (function() {
+		    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+		    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+		    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+		  })();
+	</script>
+  </head>
+  <body>
+    <div class="container-fluid section-header">
+  <div class="container">
+    <div class="nav nav-bar">
+    <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
+    <ul class="nav navbar-nav navbar-right">
+      <li><a href="/documentation/latest/">Documentation</a></li>
+      <li><a href="/community/">Community</a></li>
+      <li><a href="/downloads/">Downloads</a></li>
+      <li><a href="/blog/">Blog</a></li>
+    </ul>
+    </div>
+  </div>
+</div>
+	
+    <div class="container-fluid">
+      <div class="container content">
+        <div class="col-md-12 documentation">
+<h5 class="page-header text-uppercase">Documentation</h5>
+<select onChange="window.location.href='/documentation/' + this.value">
+  <option value="0.10.0">
+    0.10.0
+      (latest)
+  </option>
+  <option value="0.9.0">
+    0.9.0
+  </option>
+  <option value="0.8.0">
+    0.8.0
+  </option>
+  <option value="0.7.0-incubating">
+    0.7.0-incubating
+  </option>
+  <option value="0.6.0-incubating">
+    0.6.0-incubating
+  </option>
+  <option value="0.5.0-incubating">
+    0.5.0-incubating
+  </option>
+</select>
+
+<h1 id="command-hooks-for-the-aurora-client">Command Hooks for the Aurora Client</h1>
+
+<h2 id="introduction-motivation">Introduction/Motivation</h2>
+
+<p>We&rsquo;ve got hooks in the client that surround API calls. These are
+pretty awkward, because they don&rsquo;t correlate with user actions. For
+example, suppose we wanted a policy that said users weren&rsquo;t allowed to
+kill all instances of a production job at once.</p>
+
+<p>Right now, all that we could hook would be the &ldquo;killJob&rdquo; api call. But
+kill (at least in newer versions of the client) normally runs in
+batches. If a user called killall, what we would see on the API level
+is a series of &ldquo;killJob&rdquo; calls, each of which specified a batch of
+instances. We woudn&rsquo;t be able to distinguish between really killing
+all instances of a job (which is forbidden under this policy), and
+carefully killing in batches (which is permitted.) In each case, the
+hook would just see a series of API calls, and couldn&rsquo;t find out what
+the actual command being executed was!</p>
+
+<p>For most policy enforcement, what we really want to be able to do is
+look at and vet the commands that a user is performing, not the API
+calls that the client uses to implement those commands.</p>
+
+<p>So I propose that we add a new kind of hooks, which surround noun/verb
+commands. A hook will register itself to handle a collection of (noun,
+verb) pairs. Whenever any of those noun/verb commands are invoked, the
+hooks methods will be called around the execution of the verb. A
+pre-hook will have the ability to reject a command, preventing the
+verb from being executed.</p>
+
+<h2 id="registering-hooks">Registering Hooks</h2>
+
+<p>These hooks will be registered via configuration plugins. A configuration plugin
+can register hooks using an API. Hooks registered this way are, effectively,
+hardwired into the client executable.</p>
+
+<p>The order of execution of hooks is unspecified: they may be called in
+any order. There is no way to guarantee that one hook will execute
+before some other hook.</p>
+
+<h3 id="global-hooks">Global Hooks</h3>
+
+<p>Commands registered by the python call are called <em>global</em> hooks,
+because they will run for all configurations, whether or not they
+specify any hooks in the configuration file.</p>
+
+<p>In the implementation, hooks are registered in the module
+<code>apache.aurora.client.cli.command_hooks</code>, using the class
+<code>GlobalCommandHookRegistry</code>. A global hook can be registered by calling
+<code>GlobalCommandHookRegistry.register_command_hook</code> in a configuration plugin.</p>
+
+<h3 id="the-api">The API</h3>
+<pre class="highlight objective_c"><code><span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">CommandHook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span>
+  <span style="color: #000000;font-weight: bold">@property</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">name</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Returns a name for the hook."</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_nouns</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the nouns that have verbs that should invoke this hook."""</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_verbs</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the verbs for a particular noun that should invoke his hook."""</span>
+
+  <span style="color: #a61717;background-color: #e3d2d2">@abstractmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">pre_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook before invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: True if the command should be allowed to proceed; False if the command</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    should be rejected.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">post_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">result</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook after invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * result: the result code returned by the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: nothing</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+<span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">GlobalCommandHookRegistry</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+  <span style="color: #a61717;background-color: #e3d2d2">@classmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">register_command_hook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">hook</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="background-color: #f8f8f8">pass</span>
+</code></pre>
+
+<h3 id="skipping-hooks">Skipping Hooks</h3>
+
+<p>To skip a hook, a user uses a command-line option, <code>--skip-hooks</code>. The option can either
+specify specific hooks to skip, or &ldquo;all&rdquo;:</p>
+
+<ul>
+<li><code>aurora --skip-hooks=all job create east/bozo/devel/myjob</code> will create a job
+without running any hooks.</li>
+<li><code>aurora --skip-hooks=test,iq create east/bozo/devel/myjob</code> will create a job,
+and will skip only the hooks named &ldquo;test&rdquo; and &ldquo;iq&rdquo;.</li>
+</ul>
+
+</div>
+
+      </div>
+    </div>
+  	<div class="container-fluid section-footer buffer">
+      <div class="container">
+        <div class="row">
+		  <div class="col-md-2 col-md-offset-1"><h3>Quick Links</h3>
+		  <ul>
+		    <li><a href="/downloads/">Downloads</a></li>
+            <li><a href="/community/">Mailing Lists</a></li>
+			<li><a href="http://issues.apache.org/jira/browse/AURORA">Issue Tracking</a></li>
+			<li><a href="/documentation/latest/contributing/">How To Contribute</a></li>     
+		  </ul>
+	      </div>
+		  <div class="col-md-2"><h3>The ASF</h3>
+          <ul>
+            <li><a href="http://www.apache.org/licenses/">License</a></li>
+            <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>  
+            <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+            <li><a href="http://www.apache.org/security/">Security</a></li>
+          </ul>
+		  </div>
+		  <div class="col-md-6">
+			<p class="disclaimer">Copyright 2014 <a href="http://www.apache.org/">Apache Software Foundation</a>. Licensed under the <a href="http://www.apache.org/licenses/">Apache License v2.0</a>. The <a href="https://www.flickr.com/photos/trondk/12706051375/">Aurora Borealis IX photo</a> displayed on the homepage is available under a <a href="https://creativecommons.org/licenses/by-nc-nd/2.0/">Creative Commons BY-NC-ND 2.0 license</a>. Apache, Apache Aurora, and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
+        </div>
+      </div>
+    </div>
+
+  </body>
+</html>

Added: aurora/site/publish/documentation/0.8.0/design/command-hooks/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/0.8.0/design/command-hooks/index.html?rev=1719807&view=auto
==============================================================================
--- aurora/site/publish/documentation/0.8.0/design/command-hooks/index.html (added)
+++ aurora/site/publish/documentation/0.8.0/design/command-hooks/index.html Sun Dec 13 17:04:12 2015
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+	<title>Apache Aurora</title>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
+    <link href="/assets/css/main.css" rel="stylesheet">
+	<!-- Analytics -->
+	<script type="text/javascript">
+		  var _gaq = _gaq || [];
+		  _gaq.push(['_setAccount', 'UA-45879646-1']);
+		  _gaq.push(['_setDomainName', 'apache.org']);
+		  _gaq.push(['_trackPageview']);
+
+		  (function() {
+		    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+		    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+		    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+		  })();
+	</script>
+  </head>
+  <body>
+    <div class="container-fluid section-header">
+  <div class="container">
+    <div class="nav nav-bar">
+    <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
+    <ul class="nav navbar-nav navbar-right">
+      <li><a href="/documentation/latest/">Documentation</a></li>
+      <li><a href="/community/">Community</a></li>
+      <li><a href="/downloads/">Downloads</a></li>
+      <li><a href="/blog/">Blog</a></li>
+    </ul>
+    </div>
+  </div>
+</div>
+	
+    <div class="container-fluid">
+      <div class="container content">
+        <div class="col-md-12 documentation">
+<h5 class="page-header text-uppercase">Documentation</h5>
+<select onChange="window.location.href='/documentation/' + this.value">
+  <option value="0.10.0">
+    0.10.0
+      (latest)
+  </option>
+  <option value="0.9.0">
+    0.9.0
+  </option>
+  <option value="0.8.0">
+    0.8.0
+  </option>
+  <option value="0.7.0-incubating">
+    0.7.0-incubating
+  </option>
+  <option value="0.6.0-incubating">
+    0.6.0-incubating
+  </option>
+  <option value="0.5.0-incubating">
+    0.5.0-incubating
+  </option>
+</select>
+
+<h1 id="command-hooks-for-the-aurora-client">Command Hooks for the Aurora Client</h1>
+
+<h2 id="introduction-motivation">Introduction/Motivation</h2>
+
+<p>We&rsquo;ve got hooks in the client that surround API calls. These are
+pretty awkward, because they don&rsquo;t correlate with user actions. For
+example, suppose we wanted a policy that said users weren&rsquo;t allowed to
+kill all instances of a production job at once.</p>
+
+<p>Right now, all that we could hook would be the &ldquo;killJob&rdquo; api call. But
+kill (at least in newer versions of the client) normally runs in
+batches. If a user called killall, what we would see on the API level
+is a series of &ldquo;killJob&rdquo; calls, each of which specified a batch of
+instances. We woudn&rsquo;t be able to distinguish between really killing
+all instances of a job (which is forbidden under this policy), and
+carefully killing in batches (which is permitted.) In each case, the
+hook would just see a series of API calls, and couldn&rsquo;t find out what
+the actual command being executed was!</p>
+
+<p>For most policy enforcement, what we really want to be able to do is
+look at and vet the commands that a user is performing, not the API
+calls that the client uses to implement those commands.</p>
+
+<p>So I propose that we add a new kind of hooks, which surround noun/verb
+commands. A hook will register itself to handle a collection of (noun,
+verb) pairs. Whenever any of those noun/verb commands are invoked, the
+hooks methods will be called around the execution of the verb. A
+pre-hook will have the ability to reject a command, preventing the
+verb from being executed.</p>
+
+<h2 id="registering-hooks">Registering Hooks</h2>
+
+<p>These hooks will be registered via configuration plugins. A configuration plugin
+can register hooks using an API. Hooks registered this way are, effectively,
+hardwired into the client executable.</p>
+
+<p>The order of execution of hooks is unspecified: they may be called in
+any order. There is no way to guarantee that one hook will execute
+before some other hook.</p>
+
+<h3 id="global-hooks">Global Hooks</h3>
+
+<p>Commands registered by the python call are called <em>global</em> hooks,
+because they will run for all configurations, whether or not they
+specify any hooks in the configuration file.</p>
+
+<p>In the implementation, hooks are registered in the module
+<code>apache.aurora.client.cli.command_hooks</code>, using the class
+<code>GlobalCommandHookRegistry</code>. A global hook can be registered by calling
+<code>GlobalCommandHookRegistry.register_command_hook</code> in a configuration plugin.</p>
+
+<h3 id="the-api">The API</h3>
+<pre class="highlight objective_c"><code><span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">CommandHook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span>
+  <span style="color: #000000;font-weight: bold">@property</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">name</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Returns a name for the hook."</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_nouns</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the nouns that have verbs that should invoke this hook."""</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_verbs</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the verbs for a particular noun that should invoke his hook."""</span>
+
+  <span style="color: #a61717;background-color: #e3d2d2">@abstractmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">pre_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook before invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: True if the command should be allowed to proceed; False if the command</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    should be rejected.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">post_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">result</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook after invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * result: the result code returned by the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: nothing</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+<span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">GlobalCommandHookRegistry</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+  <span style="color: #a61717;background-color: #e3d2d2">@classmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">register_command_hook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">hook</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="background-color: #f8f8f8">pass</span>
+</code></pre>
+
+<h3 id="skipping-hooks">Skipping Hooks</h3>
+
+<p>To skip a hook, a user uses a command-line option, <code>--skip-hooks</code>. The option can either
+specify specific hooks to skip, or &ldquo;all&rdquo;:</p>
+
+<ul>
+<li><code>aurora --skip-hooks=all job create east/bozo/devel/myjob</code> will create a job
+without running any hooks.</li>
+<li><code>aurora --skip-hooks=test,iq create east/bozo/devel/myjob</code> will create a job,
+and will skip only the hooks named &ldquo;test&rdquo; and &ldquo;iq&rdquo;.</li>
+</ul>
+
+</div>
+
+      </div>
+    </div>
+  	<div class="container-fluid section-footer buffer">
+      <div class="container">
+        <div class="row">
+		  <div class="col-md-2 col-md-offset-1"><h3>Quick Links</h3>
+		  <ul>
+		    <li><a href="/downloads/">Downloads</a></li>
+            <li><a href="/community/">Mailing Lists</a></li>
+			<li><a href="http://issues.apache.org/jira/browse/AURORA">Issue Tracking</a></li>
+			<li><a href="/documentation/latest/contributing/">How To Contribute</a></li>     
+		  </ul>
+	      </div>
+		  <div class="col-md-2"><h3>The ASF</h3>
+          <ul>
+            <li><a href="http://www.apache.org/licenses/">License</a></li>
+            <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>  
+            <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+            <li><a href="http://www.apache.org/security/">Security</a></li>
+          </ul>
+		  </div>
+		  <div class="col-md-6">
+			<p class="disclaimer">Copyright 2014 <a href="http://www.apache.org/">Apache Software Foundation</a>. Licensed under the <a href="http://www.apache.org/licenses/">Apache License v2.0</a>. The <a href="https://www.flickr.com/photos/trondk/12706051375/">Aurora Borealis IX photo</a> displayed on the homepage is available under a <a href="https://creativecommons.org/licenses/by-nc-nd/2.0/">Creative Commons BY-NC-ND 2.0 license</a>. Apache, Apache Aurora, and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
+        </div>
+      </div>
+    </div>
+
+  </body>
+</html>

Added: aurora/site/publish/documentation/0.9.0/design/command-hooks/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/0.9.0/design/command-hooks/index.html?rev=1719807&view=auto
==============================================================================
--- aurora/site/publish/documentation/0.9.0/design/command-hooks/index.html (added)
+++ aurora/site/publish/documentation/0.9.0/design/command-hooks/index.html Sun Dec 13 17:04:12 2015
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+	<title>Apache Aurora</title>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
+    <link href="/assets/css/main.css" rel="stylesheet">
+	<!-- Analytics -->
+	<script type="text/javascript">
+		  var _gaq = _gaq || [];
+		  _gaq.push(['_setAccount', 'UA-45879646-1']);
+		  _gaq.push(['_setDomainName', 'apache.org']);
+		  _gaq.push(['_trackPageview']);
+
+		  (function() {
+		    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+		    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+		    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+		  })();
+	</script>
+  </head>
+  <body>
+    <div class="container-fluid section-header">
+  <div class="container">
+    <div class="nav nav-bar">
+    <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
+    <ul class="nav navbar-nav navbar-right">
+      <li><a href="/documentation/latest/">Documentation</a></li>
+      <li><a href="/community/">Community</a></li>
+      <li><a href="/downloads/">Downloads</a></li>
+      <li><a href="/blog/">Blog</a></li>
+    </ul>
+    </div>
+  </div>
+</div>
+	
+    <div class="container-fluid">
+      <div class="container content">
+        <div class="col-md-12 documentation">
+<h5 class="page-header text-uppercase">Documentation</h5>
+<select onChange="window.location.href='/documentation/' + this.value">
+  <option value="0.10.0">
+    0.10.0
+      (latest)
+  </option>
+  <option value="0.9.0">
+    0.9.0
+  </option>
+  <option value="0.8.0">
+    0.8.0
+  </option>
+  <option value="0.7.0-incubating">
+    0.7.0-incubating
+  </option>
+  <option value="0.6.0-incubating">
+    0.6.0-incubating
+  </option>
+  <option value="0.5.0-incubating">
+    0.5.0-incubating
+  </option>
+</select>
+
+<h1 id="command-hooks-for-the-aurora-client">Command Hooks for the Aurora Client</h1>
+
+<h2 id="introduction-motivation">Introduction/Motivation</h2>
+
+<p>We&rsquo;ve got hooks in the client that surround API calls. These are
+pretty awkward, because they don&rsquo;t correlate with user actions. For
+example, suppose we wanted a policy that said users weren&rsquo;t allowed to
+kill all instances of a production job at once.</p>
+
+<p>Right now, all that we could hook would be the &ldquo;killJob&rdquo; api call. But
+kill (at least in newer versions of the client) normally runs in
+batches. If a user called killall, what we would see on the API level
+is a series of &ldquo;killJob&rdquo; calls, each of which specified a batch of
+instances. We woudn&rsquo;t be able to distinguish between really killing
+all instances of a job (which is forbidden under this policy), and
+carefully killing in batches (which is permitted.) In each case, the
+hook would just see a series of API calls, and couldn&rsquo;t find out what
+the actual command being executed was!</p>
+
+<p>For most policy enforcement, what we really want to be able to do is
+look at and vet the commands that a user is performing, not the API
+calls that the client uses to implement those commands.</p>
+
+<p>So I propose that we add a new kind of hooks, which surround noun/verb
+commands. A hook will register itself to handle a collection of (noun,
+verb) pairs. Whenever any of those noun/verb commands are invoked, the
+hooks methods will be called around the execution of the verb. A
+pre-hook will have the ability to reject a command, preventing the
+verb from being executed.</p>
+
+<h2 id="registering-hooks">Registering Hooks</h2>
+
+<p>These hooks will be registered via configuration plugins. A configuration plugin
+can register hooks using an API. Hooks registered this way are, effectively,
+hardwired into the client executable.</p>
+
+<p>The order of execution of hooks is unspecified: they may be called in
+any order. There is no way to guarantee that one hook will execute
+before some other hook.</p>
+
+<h3 id="global-hooks">Global Hooks</h3>
+
+<p>Commands registered by the python call are called <em>global</em> hooks,
+because they will run for all configurations, whether or not they
+specify any hooks in the configuration file.</p>
+
+<p>In the implementation, hooks are registered in the module
+<code>apache.aurora.client.cli.command_hooks</code>, using the class
+<code>GlobalCommandHookRegistry</code>. A global hook can be registered by calling
+<code>GlobalCommandHookRegistry.register_command_hook</code> in a configuration plugin.</p>
+
+<h3 id="the-api">The API</h3>
+<pre class="highlight objective_c"><code><span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">CommandHook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span>
+  <span style="color: #000000;font-weight: bold">@property</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">name</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Returns a name for the hook."</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_nouns</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the nouns that have verbs that should invoke this hook."""</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_verbs</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the verbs for a particular noun that should invoke his hook."""</span>
+
+  <span style="color: #a61717;background-color: #e3d2d2">@abstractmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">pre_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook before invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: True if the command should be allowed to proceed; False if the command</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    should be rejected.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">post_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">result</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook after invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * result: the result code returned by the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: nothing</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+<span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">GlobalCommandHookRegistry</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+  <span style="color: #a61717;background-color: #e3d2d2">@classmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">register_command_hook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">hook</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="background-color: #f8f8f8">pass</span>
+</code></pre>
+
+<h3 id="skipping-hooks">Skipping Hooks</h3>
+
+<p>To skip a hook, a user uses a command-line option, <code>--skip-hooks</code>. The option can either
+specify specific hooks to skip, or &ldquo;all&rdquo;:</p>
+
+<ul>
+<li><code>aurora --skip-hooks=all job create east/bozo/devel/myjob</code> will create a job
+without running any hooks.</li>
+<li><code>aurora --skip-hooks=test,iq create east/bozo/devel/myjob</code> will create a job,
+and will skip only the hooks named &ldquo;test&rdquo; and &ldquo;iq&rdquo;.</li>
+</ul>
+
+</div>
+
+      </div>
+    </div>
+  	<div class="container-fluid section-footer buffer">
+      <div class="container">
+        <div class="row">
+		  <div class="col-md-2 col-md-offset-1"><h3>Quick Links</h3>
+		  <ul>
+		    <li><a href="/downloads/">Downloads</a></li>
+            <li><a href="/community/">Mailing Lists</a></li>
+			<li><a href="http://issues.apache.org/jira/browse/AURORA">Issue Tracking</a></li>
+			<li><a href="/documentation/latest/contributing/">How To Contribute</a></li>     
+		  </ul>
+	      </div>
+		  <div class="col-md-2"><h3>The ASF</h3>
+          <ul>
+            <li><a href="http://www.apache.org/licenses/">License</a></li>
+            <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>  
+            <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+            <li><a href="http://www.apache.org/security/">Security</a></li>
+          </ul>
+		  </div>
+		  <div class="col-md-6">
+			<p class="disclaimer">Copyright 2014 <a href="http://www.apache.org/">Apache Software Foundation</a>. Licensed under the <a href="http://www.apache.org/licenses/">Apache License v2.0</a>. The <a href="https://www.flickr.com/photos/trondk/12706051375/">Aurora Borealis IX photo</a> displayed on the homepage is available under a <a href="https://creativecommons.org/licenses/by-nc-nd/2.0/">Creative Commons BY-NC-ND 2.0 license</a>. Apache, Apache Aurora, and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
+        </div>
+      </div>
+    </div>
+
+  </body>
+</html>

Added: aurora/site/publish/documentation/latest/design/command-hooks/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/design/command-hooks/index.html?rev=1719807&view=auto
==============================================================================
--- aurora/site/publish/documentation/latest/design/command-hooks/index.html (added)
+++ aurora/site/publish/documentation/latest/design/command-hooks/index.html Sun Dec 13 17:04:12 2015
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+	<title>Apache Aurora</title>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
+    <link href="/assets/css/main.css" rel="stylesheet">
+	<!-- Analytics -->
+	<script type="text/javascript">
+		  var _gaq = _gaq || [];
+		  _gaq.push(['_setAccount', 'UA-45879646-1']);
+		  _gaq.push(['_setDomainName', 'apache.org']);
+		  _gaq.push(['_trackPageview']);
+
+		  (function() {
+		    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+		    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+		    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+		  })();
+	</script>
+  </head>
+  <body>
+    <div class="container-fluid section-header">
+  <div class="container">
+    <div class="nav nav-bar">
+    <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
+    <ul class="nav navbar-nav navbar-right">
+      <li><a href="/documentation/latest/">Documentation</a></li>
+      <li><a href="/community/">Community</a></li>
+      <li><a href="/downloads/">Downloads</a></li>
+      <li><a href="/blog/">Blog</a></li>
+    </ul>
+    </div>
+  </div>
+</div>
+	
+    <div class="container-fluid">
+      <div class="container content">
+        <div class="col-md-12 documentation">
+<h5 class="page-header text-uppercase">Documentation</h5>
+<select onChange="window.location.href='/documentation/' + this.value">
+  <option value="0.10.0">
+    0.10.0
+      (latest)
+  </option>
+  <option value="0.9.0">
+    0.9.0
+  </option>
+  <option value="0.8.0">
+    0.8.0
+  </option>
+  <option value="0.7.0-incubating">
+    0.7.0-incubating
+  </option>
+  <option value="0.6.0-incubating">
+    0.6.0-incubating
+  </option>
+  <option value="0.5.0-incubating">
+    0.5.0-incubating
+  </option>
+</select>
+
+<h1 id="command-hooks-for-the-aurora-client">Command Hooks for the Aurora Client</h1>
+
+<h2 id="introduction-motivation">Introduction/Motivation</h2>
+
+<p>We&rsquo;ve got hooks in the client that surround API calls. These are
+pretty awkward, because they don&rsquo;t correlate with user actions. For
+example, suppose we wanted a policy that said users weren&rsquo;t allowed to
+kill all instances of a production job at once.</p>
+
+<p>Right now, all that we could hook would be the &ldquo;killJob&rdquo; api call. But
+kill (at least in newer versions of the client) normally runs in
+batches. If a user called killall, what we would see on the API level
+is a series of &ldquo;killJob&rdquo; calls, each of which specified a batch of
+instances. We woudn&rsquo;t be able to distinguish between really killing
+all instances of a job (which is forbidden under this policy), and
+carefully killing in batches (which is permitted.) In each case, the
+hook would just see a series of API calls, and couldn&rsquo;t find out what
+the actual command being executed was!</p>
+
+<p>For most policy enforcement, what we really want to be able to do is
+look at and vet the commands that a user is performing, not the API
+calls that the client uses to implement those commands.</p>
+
+<p>So I propose that we add a new kind of hooks, which surround noun/verb
+commands. A hook will register itself to handle a collection of (noun,
+verb) pairs. Whenever any of those noun/verb commands are invoked, the
+hooks methods will be called around the execution of the verb. A
+pre-hook will have the ability to reject a command, preventing the
+verb from being executed.</p>
+
+<h2 id="registering-hooks">Registering Hooks</h2>
+
+<p>These hooks will be registered via configuration plugins. A configuration plugin
+can register hooks using an API. Hooks registered this way are, effectively,
+hardwired into the client executable.</p>
+
+<p>The order of execution of hooks is unspecified: they may be called in
+any order. There is no way to guarantee that one hook will execute
+before some other hook.</p>
+
+<h3 id="global-hooks">Global Hooks</h3>
+
+<p>Commands registered by the python call are called <em>global</em> hooks,
+because they will run for all configurations, whether or not they
+specify any hooks in the configuration file.</p>
+
+<p>In the implementation, hooks are registered in the module
+<code>apache.aurora.client.cli.command_hooks</code>, using the class
+<code>GlobalCommandHookRegistry</code>. A global hook can be registered by calling
+<code>GlobalCommandHookRegistry.register_command_hook</code> in a configuration plugin.</p>
+
+<h3 id="the-api">The API</h3>
+<pre class="highlight objective_c"><code><span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">CommandHook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span>
+  <span style="color: #000000;font-weight: bold">@property</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">name</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Returns a name for the hook."</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_nouns</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the nouns that have verbs that should invoke this hook."""</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_verbs</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Return the verbs for a particular noun that should invoke his hook."""</span>
+
+  <span style="color: #a61717;background-color: #e3d2d2">@abstractmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">pre_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook before invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: True if the command should be allowed to proceed; False if the command</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    should be rejected.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">post_command</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">verb</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">context</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">commandline</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">result</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="color: #d14">"""Execute a hook after invoking a verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * noun: the noun being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * verb: the verb being invoked.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * context: the context object that will be used to invoke the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">      The options object will be initialized before calling the hook</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * commandline: the original argv collection used to invoke the client.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    * result: the result code returned by the verb.</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    Returns: nothing</span><span style="color: #a61717;background-color: #e3d2d2">
+</span><span style="color: #d14">    """</span>
+
+<span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">GlobalCommandHookRegistry</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+  <span style="color: #a61717;background-color: #e3d2d2">@classmethod</span>
+  <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">register_command_hook</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">hook</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span>
+    <span style="background-color: #f8f8f8">pass</span>
+</code></pre>
+
+<h3 id="skipping-hooks">Skipping Hooks</h3>
+
+<p>To skip a hook, a user uses a command-line option, <code>--skip-hooks</code>. The option can either
+specify specific hooks to skip, or &ldquo;all&rdquo;:</p>
+
+<ul>
+<li><code>aurora --skip-hooks=all job create east/bozo/devel/myjob</code> will create a job
+without running any hooks.</li>
+<li><code>aurora --skip-hooks=test,iq create east/bozo/devel/myjob</code> will create a job,
+and will skip only the hooks named &ldquo;test&rdquo; and &ldquo;iq&rdquo;.</li>
+</ul>
+
+</div>
+
+      </div>
+    </div>
+  	<div class="container-fluid section-footer buffer">
+      <div class="container">
+        <div class="row">
+		  <div class="col-md-2 col-md-offset-1"><h3>Quick Links</h3>
+		  <ul>
+		    <li><a href="/downloads/">Downloads</a></li>
+            <li><a href="/community/">Mailing Lists</a></li>
+			<li><a href="http://issues.apache.org/jira/browse/AURORA">Issue Tracking</a></li>
+			<li><a href="/documentation/latest/contributing/">How To Contribute</a></li>     
+		  </ul>
+	      </div>
+		  <div class="col-md-2"><h3>The ASF</h3>
+          <ul>
+            <li><a href="http://www.apache.org/licenses/">License</a></li>
+            <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>  
+            <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
+            <li><a href="http://www.apache.org/security/">Security</a></li>
+          </ul>
+		  </div>
+		  <div class="col-md-6">
+			<p class="disclaimer">Copyright 2014 <a href="http://www.apache.org/">Apache Software Foundation</a>. Licensed under the <a href="http://www.apache.org/licenses/">Apache License v2.0</a>. The <a href="https://www.flickr.com/photos/trondk/12706051375/">Aurora Borealis IX photo</a> displayed on the homepage is available under a <a href="https://creativecommons.org/licenses/by-nc-nd/2.0/">Creative Commons BY-NC-ND 2.0 license</a>. Apache, Apache Aurora, and the Apache feather logo are trademarks of The Apache Software Foundation.</p>
+        </div>
+      </div>
+    </div>
+
+  </body>
+</html>

Modified: aurora/site/publish/sitemap.xml
URL: http://svn.apache.org/viewvc/aurora/site/publish/sitemap.xml?rev=1719807&r1=1719806&r2=1719807&view=diff
==============================================================================
--- aurora/site/publish/sitemap.xml (original)
+++ aurora/site/publish/sitemap.xml Sun Dec 13 17:04:12 2015
@@ -85,6 +85,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/0.10.0/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/0.10.0/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -181,6 +185,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/0.5.0-incubating/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/0.5.0-incubating/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -253,6 +261,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/0.6.0-incubating/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/0.6.0-incubating/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -341,6 +353,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/0.7.0-incubating/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/0.7.0-incubating/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -433,6 +449,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/0.8.0/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/0.8.0/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -529,6 +549,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/0.9.0/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/0.9.0/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -633,6 +657,10 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/latest/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/latest/developing-aurora-client/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
@@ -641,6 +669,110 @@
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>
   <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/build-system/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/client-cluster-configuration/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/client-commands/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/committers/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/configuration-reference/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/configuration-tutorial/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/cron-jobs/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/deploying-aurora-scheduler/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/design/command-hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/developing-aurora-client/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/developing-aurora-scheduler/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/hooks/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/monitoring/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/presentations/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/README/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/resources/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/scheduler-storage/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/security/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/sla/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/storage-config/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/storage/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/test-resource-generation/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/thrift-deprecation/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/tutorial/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/user-guide/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
+    <loc>http://aurora.apache.org/documentation/latest/docs/vagrant/</loc>
+    <lastmod>2015-12-13T00:00:00+00:00</lastmod>
+  </url>
+  <url>
     <loc>http://aurora.apache.org/documentation/latest/hooks/</loc>
     <lastmod>2015-12-13T00:00:00+00:00</lastmod>
   </url>

Added: aurora/site/source/documentation/0.10.0/design/command-hooks.md
URL: http://svn.apache.org/viewvc/aurora/site/source/documentation/0.10.0/design/command-hooks.md?rev=1719807&view=auto
==============================================================================
--- aurora/site/source/documentation/0.10.0/design/command-hooks.md (added)
+++ aurora/site/source/documentation/0.10.0/design/command-hooks.md Sun Dec 13 17:04:12 2015
@@ -0,0 +1,102 @@
+# Command Hooks for the Aurora Client
+
+## Introduction/Motivation
+
+We've got hooks in the client that surround API calls. These are
+pretty awkward, because they don't correlate with user actions. For
+example, suppose we wanted a policy that said users weren't allowed to
+kill all instances of a production job at once.
+
+Right now, all that we could hook would be the "killJob" api call. But
+kill (at least in newer versions of the client) normally runs in
+batches. If a user called killall, what we would see on the API level
+is a series of "killJob" calls, each of which specified a batch of
+instances. We woudn't be able to distinguish between really killing
+all instances of a job (which is forbidden under this policy), and
+carefully killing in batches (which is permitted.) In each case, the
+hook would just see a series of API calls, and couldn't find out what
+the actual command being executed was!
+
+For most policy enforcement, what we really want to be able to do is
+look at and vet the commands that a user is performing, not the API
+calls that the client uses to implement those commands.
+
+So I propose that we add a new kind of hooks, which surround noun/verb
+commands. A hook will register itself to handle a collection of (noun,
+verb) pairs. Whenever any of those noun/verb commands are invoked, the
+hooks methods will be called around the execution of the verb. A
+pre-hook will have the ability to reject a command, preventing the
+verb from being executed.
+
+## Registering Hooks
+
+These hooks will be registered via configuration plugins. A configuration plugin
+can register hooks using an API. Hooks registered this way are, effectively,
+hardwired into the client executable.
+
+The order of execution of hooks is unspecified: they may be called in
+any order. There is no way to guarantee that one hook will execute
+before some other hook.
+
+
+### Global Hooks
+
+Commands registered by the python call are called _global_ hooks,
+because they will run for all configurations, whether or not they
+specify any hooks in the configuration file.
+
+In the implementation, hooks are registered in the module
+`apache.aurora.client.cli.command_hooks`, using the class
+`GlobalCommandHookRegistry`. A global hook can be registered by calling
+`GlobalCommandHookRegistry.register_command_hook` in a configuration plugin.
+
+### The API
+
+    class CommandHook(object)
+      @property
+      def name(self):
+        """Returns a name for the hook."
+
+      def get_nouns(self):
+        """Return the nouns that have verbs that should invoke this hook."""
+
+      def get_verbs(self, noun):
+        """Return the verbs for a particular noun that should invoke his hook."""
+
+      @abstractmethod
+      def pre_command(self, noun, verb, context, commandline):
+        """Execute a hook before invoking a verb.
+        * noun: the noun being invoked.
+        * verb: the verb being invoked.
+        * context: the context object that will be used to invoke the verb.
+          The options object will be initialized before calling the hook
+        * commandline: the original argv collection used to invoke the client.
+        Returns: True if the command should be allowed to proceed; False if the command
+        should be rejected.
+        """
+
+      def post_command(self, noun, verb, context, commandline, result):
+        """Execute a hook after invoking a verb.
+        * noun: the noun being invoked.
+        * verb: the verb being invoked.
+        * context: the context object that will be used to invoke the verb.
+          The options object will be initialized before calling the hook
+        * commandline: the original argv collection used to invoke the client.
+        * result: the result code returned by the verb.
+        Returns: nothing
+        """
+
+    class GlobalCommandHookRegistry(object):
+      @classmethod
+      def register_command_hook(self, hook):
+        pass
+
+### Skipping Hooks
+
+To skip a hook, a user uses a command-line option, `--skip-hooks`. The option can either
+specify specific hooks to skip, or "all":
+
+* `aurora --skip-hooks=all job create east/bozo/devel/myjob` will create a job
+  without running any hooks.
+* `aurora --skip-hooks=test,iq create east/bozo/devel/myjob` will create a job,
+  and will skip only the hooks named "test" and "iq".

Added: aurora/site/source/documentation/0.5.0-incubating/design/command-hooks.md
URL: http://svn.apache.org/viewvc/aurora/site/source/documentation/0.5.0-incubating/design/command-hooks.md?rev=1719807&view=auto
==============================================================================
--- aurora/site/source/documentation/0.5.0-incubating/design/command-hooks.md (added)
+++ aurora/site/source/documentation/0.5.0-incubating/design/command-hooks.md Sun Dec 13 17:04:12 2015
@@ -0,0 +1,263 @@
+# Command Hooks for the Aurora Client
+
+## Introduction/Motivation
+
+We've got hooks in the client that surround API calls. These are
+pretty awkward, because they don't correlate with user actions. For
+example, suppose we wanted a policy that said users weren't allowed to
+kill all instances of a production job at once.
+
+Right now, all that we could hook would be the "killJob" api call. But
+kill (at least in newer versions of the client) normally runs in
+batches. If a user called killall, what we would see on the API level
+is a series of "killJob" calls, each of which specified a batch of
+instances. We woudn't be able to distinguish between really killing
+all instances of a job (which is forbidden under this policy), and
+carefully killing in batches (which is permitted.) In each case, the
+hook would just see a series of API calls, and couldn't find out what
+the actual command being executed was!
+
+For most policy enforcement, what we really want to be able to do is
+look at and vet the commands that a user is performing, not the API
+calls that the client uses to implement those commands.
+
+So I propose that we add a new kind of hooks, which surround noun/verb
+commands. A hook will register itself to handle a collection of (noun,
+verb) pairs. Whenever any of those noun/verb commands are invoked, the
+hooks methods will be called around the execution of the verb. A
+pre-hook will have the ability to reject a command, preventing the
+verb from being executed.
+
+## Registering Hooks
+
+These hooks will be registered two ways:
+* Project hooks file. If a file named `AuroraHooks` is in the project directory
+  where an aurora command is being executed, that file will be read,
+  and its hooks will be registered.
+* Configuration plugins. A configuration plugin can register hooks using an API.
+  Hooks registered this way are, effectively, hardwired into the client executable.
+
+The order of execution of hooks is unspecified: they may be called in
+any order. There is no way to guarantee that one hook will execute
+before some other hook.
+
+
+### Global Hooks
+
+Commands registered by the python call are called _global_ hooks,
+because they will run for all configurations, whether or not they
+specify any hooks in the configuration file.
+
+In the implementation, hooks are registered in the module
+`apache.aurora.client.cli.command_hooks`, using the class `GlobalCommandHookRegistry`.  A
+global hook can be registered by calling `GlobalCommandHookRegistry.register_command_hook`
+in a configuration plugin.
+
+### Hook Files
+
+A hook file is a file containing Python source code. It will be
+dynamically loaded by the Aurora command line executable. After
+loading, the client will check the module for a global variable named
+"hooks", which contains a list of hook objects, which will be added to
+the hook registry.
+
+A project hooks file will be named `AuroraHooks`,
+and will be located in either the directory where the command is being
+executed, or one of its parent directories, up to the nearest git/mercurial
+repository base.
+
+### The API
+
+    class CommandHook(object)
+      @property
+      def name(self):
+        """Returns a name for the hook."
+
+      def get_nouns(self):
+        """Return the nouns that have verbs that should invoke this hook."""
+
+      def get_verbs(self, noun):
+        """Return the verbs for a particular noun that should invoke his hook."""
+
+      @abstractmethod
+      def pre_command(self, noun, verb, context, commandline):
+        """Execute a hook before invoking a verb.
+        * noun: the noun being invoked.
+        * verb: the verb being invoked.
+        * context: the context object that will be used to invoke the verb.
+          The options object will be initialized before calling the hook
+        * commandline: the original argv collection used to invoke the client.
+        Returns: True if the command should be allowed to proceed; False if the command
+        should be rejected.
+        """
+
+      def post_command(self, noun, verb, context, commandline, result):
+        """Execute a hook after invoking a verb.
+        * noun: the noun being invoked.
+        * verb: the verb being invoked.
+        * context: the context object that will be used to invoke the verb.
+          The options object will be initialized before calling the hook
+        * commandline: the original argv collection used to invoke the client.
+        * result: the result code returned by the verb.
+        Returns: nothing
+        """
+
+    class GlobalCommandHookRegistry(object):
+      @classmethod
+      def register_command_hook(self, hook):
+        pass
+
+## Skipping Hooks
+
+In a perfect world, hooks would represent a global property or policy
+that should always be enforced. Unfortunately, we don't live in a
+perfect world, which means that sometimes, every rule needs to get
+broken.
+
+For example, an organization could decide that every configuration
+must be checked in to source control before it could be
+deployed. That's an entirely reasonable policy. It would be easy to
+implement it using a hook. But what if there's a problem, and the
+source repos is down?
+
+The easiest solution is just to allow a user to add a `--skip-hooks`
+flag to the command-line. But doing that means that an organization
+can't actually use hooks to enforce policy, because users can skip
+them whenever they want.
+
+Instead, we'd like to have a system where it's possible to create
+hooks to enforce policy, and then include a way of building policy
+about when hooks can be skipped.
+
+I'm using sudo as a rough model for this. Many organizations need to
+give people the ability to run privileged commands, but they still
+want to have some control. Sudo allows them to specify who is allowed
+to run a privileged command; where they're allowed to run it; and what
+command(s) they're allowed to run.  All of that is specified in a
+special system file located in `/etc/sudoers` on a typical unix
+machine.
+
+In a world of distributed systems, this approach has one grave
+weakness. An aurora client can be located on any machine that has
+network access to a Mesos/Aurora cluster. It can be run by a user in
+pretty much any way they want - from a machine they control, from a
+special chroot they created, etc. Relying an a file being in a special
+location on their machine isn't sufficient - it's too easy to
+maliciously or erroneously run a command in an environment with an
+invalid hooks exceptions file.
+
+Instead, we've got two basic choices: hook exception rules can be
+baked into the client executable, or they can be provided in a
+network location.
+
+### Specifying when hooks can be skipped
+
+#### Hooks File
+
+The module `apache.aurora.client.cli` contains a variable named
+`GLOBAL_HOOK_SKIP_RULES_URL`. In the default distribution of Aurora, tihs variable contains
+`None`. Users can modify this value for their local environments, providing
+a site specific URL. If users attempt to bypass command hooks, and this
+URL is not `None`, then the client will fetch the contents of that URL, and
+attempt to interpret it as a hooks exception file.
+
+The hooks exception file is written in JSON, with the following structure:
+
+    { "rulename":
+      {
+      "hooks": [ "hook-name ", ... ],
+      "users": [ string, ...],
+      "commands": { "job": ["kill", "killall", ...], ... },
+      "arg-patterns": [ "regexp-str", ... ]
+      },
+	  ...
+    }
+
+* `hooks` is a list of hook identifiers which can be skipped by a user
+  that satisfies this rule. If omitted, then this rule applies to _all hooks_.
+  (Omitting the `hooks` field is equivalent to giving it the value `['*']`.)
+* `users` is a list of user names, or glob expressions that range over user
+  names. This rule gives permission to those users to skip hooks. If omitted,
+  then this rule allows _any user_ to skip hooks that satisfy the rest of this rule.
+  Note that this is _user_ names, not
+  _role_ names: the rules specify users that are allowed to skip commands.
+  Some users that are allowed to work with a role account may be allowed to
+  skip, while others cannot.
+* `commands` is a map from nouns to lists of verbs. If a command `aurora n v`
+  is being executed, this rule allows the hooks to be skipped if
+  `v` is in `commands[n]`. If this is omitted, then it allows hooks to be skipped for all
+  commands that satisfy the rest of the rule.
+* `arg_patterns` is a list of glob patterns ranging over parameters.
+  If any of the parameters of the command match the parameters in this list,
+  the hook can be skipped. If ommitted, then this applies regardless of arguments.
+
+For example, the following is a hook rules file which allows:
+* The user "root" to skip any hook.
+* Any user to skip hooks for test jobs.
+* A specific group of users to skip hooks for jobs in cluster `east`
+* Another group of users to skip hooks for `job kill` in cluster `west`.
+
+    {
+      "allow-admin": { "users": ["root"] },
+	  "allow-test": { "users": ["\*"], "arg-patterns": ["\*/\*/test/\*"] },
+	  "allow-east-users": { "users"=['john', 'mary', 'mike', 'sue'],
+          "arg-patterns": ["east/\*/\*/\*"] },
+	  "allow-west-kills": { "users": ["anne", "bill", "chris"],
+          "commands": { "job": ["kill"]}, "arg-patterns" = ["west/\*/\*/\*"] }
+    }
+
+#### Programmatic Hooks Exceptions
+
+The `GlobalHooksRegistry` contains the method `add_hooks_exception`, which allows
+users to register local hooks exceptions using the `ConfigurationPlugin` mechanism.
+A hooks exception object implements the following interface:
+
+    class HooksException(object):
+	  def allow_exception(self, hooks, role, noun, verb, args):
+	    """Params:
+        - hooks: a list of hook-names that the user wants to skip. If this
+		  is ommitted, then this applies to all hooks.
+		- role: the role requesting that hooks be skipped.
+		- noun, verb: the noun and verb being executed.
+		- the other command-line arguments.
+		Returns: True if the user should be allowed to skip the requested hooks.
+		"""
+	    return False
+
+When a user supplies the `--skip-hooks` argument, `allow_exception` is invoked on
+each of the `HooksException` arguments. If _any_ of the hooks exception objects
+returns `True`, then the user will be permitted to skip the hooks.
+
+### Skipping Hooks
+
+To skip a hook, a user uses a command-line option, `--skip-hooks`. The option can either
+specify specific hooks to skip, or "all":
+
+* `aurora --skip-hooks=all job create east/bozo/devel/myjob` will create a job
+  without running any hooks.
+* `aurora --skip-hooks=test,iq create east/bozo/devel/myjob` will create a job,
+  and will skip only the hooks named "test" and "iq".
+
+
+## Changes
+
+4/30:
+* Rule exceptions are defined in JSON, and they are specified to be loaded from
+  a URL, not from a local file.
+* Rule exceptions specify users, not roles.
+
+4/27:
+Major changes between this and the last version of this proposal.
+* Command hooks can't be declared in a configuration file. There's a simple
+  reason why: hooks run before a command's implementation is invoked.
+  Config files are read during the commands invocation if necessary. If the
+  hook is declared in the config file, by the time you know that it should
+  have been run, it's too late. So I've removed config-hooks from the
+  proposal. (API hooks defined by configs still work.)
+* Skipping hooks. We expect aurora to be used inside of large
+  organizations. One of the primary use-cases of hooks is to create
+  enforcable policy that are specific to an organization. If hooks
+  can just be skipped because a user wants to skip them, it means that
+  the policy can't be enforced, which defeats the purpose of having them.
+  So in this update, I propose a mechanism, loosely based on a `sudo`-like
+  mechanism for defining when hooks can be skipped.



Mime
View raw message