<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Hello,</p>
    <p>One of Rudder 4.1 new features will be relay APIs. This is the
      first attempt to describe it.<br>
    </p>
    <p>There are currently 2 API entries we want to add: remote-run and
      share-files.<br>
      They will both be under /rudder/relay-api itself under
      <a class="moz-txt-link-freetext" href="https://">https://</a><server>:<port>/ like the current api is.<br>
      /rudder is the common root for all rudder service<br>
      /relay-api is different from existing api to avoid conflicts with
      them when it will be installed on the server</p>
    <p><br>
    </p>
    <p>1. Remote-run:</p>
    The goal is to make a given relay call "rudder remote run" on one of
    its attached node<br>
    The API will be under /rudder/relay-api/remote-run <br>
    GET remote-run/node/<node-uuid><br>
    GET remote-run/all<br>
    GET remote-run/nodes<br>
    <br>
    Parameters:<br>
    - output = keep / discard : to keep the output of the remote-run
    call or discard its content<br>
    - async = yes / no : yes to ignore the return code of the call and
    return immediately, no to wait until the end of the call and get the
    return code<br>
    - classes = XXX : list of cfengine classes to set during the remote
    call<br>
    - nodes = uuid,... : list of uuid to call in the "/nodes" case<br>
    <br>
    Behavior:<br>
    - Loop on all nodes<br>
    - Find its hostname from its uuid in a matching file created by
    promise generation on the server<br>
    - The call is descending, so we don't care about host that do not
    exist<br>
    - The call is descending, so we will only accept calls from the
    policy server<br>
    - Call rudder remote<br>
    - prefix the remote output lines with <uuid>: to make sure the
    caller can parse output during async call on multiple nodes<br>
    - surround the output with json format lines and include return
    code, duration and stderr (-> we should escape the output for use
    within a json string)<br>
     <br>
    <br>
    <p>2. Share Files<br>
    </p>
    <p>The goal is to share files between an agent and another one via
      their policy server.<br>
      The API will be under /rudder/relay-api/shared-files <br>
      POST shared-files/node/<target_uuid>/<file_id>  
      (share a file content with the target uuid using a given file id)<br>
      HEAD shared-files/node/<target_uuid>/<file_id>  (ask
      if a file with the given file id is already shared with the given
      target id)<br>
    </p>
    <p>Parameters:<br>
      - source-uuid: the uuid of the node sharing a file with the target
      uuid<br>
      - signature: the file's signature in case of a POST, to
      authenticate the source node<br>
      - hash: the file's hash in case of a HEAD to know is the version
      already present matches<br>
    </p>
    POST Behavior:<br>
    - if the target is known by the local relay<br>
     -> validate the signature<br>
     -> store the file in
/var/rudder/shared-files-nodes/[..<relay-uuid>..]/<target_uuid>/<source_uuid>/<file_id><br>
     -> store the metadata (including, date, hash and signature) in
    <the same path>.medata<br>
    - if the target in not known and we are not the root server<br>
     -> store the file in a temporary directory<br>
     -> try to send the file to the relay server<br>
     -> do nt remove the file and try again as long as there is a
    fatal error (code >= 500, network error)<br>
    - if the target in not known and we are the root server<br>
     -> ignore the file and return 404<br>
    <br>
    HEAD behavior:<br>
    - If the file exists in /var/rudder/shared-files-nodes... with the
    same hash, return 200<br>
    - If it doesn't, return 404<br>
    <br>
    3. Using this API from ncf<br>
    We will create 2 new generic methods in ncf:<br>
    - sharedfile_to_node(target_uuid, file_id, file_path, ttl)   where
    ttl is infinite by default<br>
    - sharedfile_from_node(source_uuid, file_id, file_path) <br>
    <br>
    The first one will call HEAD on the shared-files API and if is gets
    a 404, call POST to send the content.<br>
    <br>
    The second one will just download the file using regular cfengine
    protocol.<br>
    <br>
    <br>
    <br>
    That's all folks !<br>
    Any comment ?<br>
    <div class="moz-signature">-- <br>
      <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
      <style type="text/css">
<!--
a.redlink:link { color: #1782E6; }
a.redlink:visited { color: #1782E6; }
.sig { font-family: 'Century Gothic', CenturyGothic, AppleGothic, sans-serif; font-size: small; }
.sigsmall { font-family: 'Century Gothic', CenturyGothic, AppleGothic, sans-serif; font-size: x-small; }
-->
    </style>
      <table border="0" cellpadding="0" cellspacing="2" width="380">
        <tbody>
          <tr>
            <td colspan="2">
              <hr></td>
          </tr>
          <tr>
            <td colspan="2"><b><img alt="Logo Normation"
                  src="cid:part1.605096A1.65F1782B@normation.com"
                  align="left" height="50" hspace="10" width="50"> <span
                  class="sig">Benoît Peccatte</span></b><br>
              <span class="sig"><i>Architecte</i></span><br>
              <span class="sig"><a class="redlink"
                  href="http://www.normation.com">Normation</a></span> </td>
          </tr>
          <tr>
            <td colspan="2">
              <hr></td>
          </tr>
          <tr>
            <td colspan="2"><span class="sigsmall"><b>87, Rue de
                  Turbigo, 75003 Paris, France</b></span></td>
          </tr>
          <tr>
            <td><span class="sigsmall">Phone:</span></td>
            <td><span class="sigsmall">+33 (0)1 85 08 48 96</span></td>
          </tr>
          <tr>
            <td colspan="2">
              <hr> </td>
          </tr>
        </tbody>
      </table>
    </div>
  </body>
</html>