User story #9707
closedAdd a Relay API: share files between nodes, launch run on remote run behind relay
Description
One of Rudder 4.1 new features will be relay APIs. This is the first attempt to describe it.
There are currently 2 API entries we want to add: remote-run and share-files.
They will both be under /rudder/relay-api itself under https://<server>:<port>/ like the current api is.
/rudder is the common root for all rudder service
/relay-api is different from existing api to avoid conflicts with them when it will be installed on the server
1. Remote-run:
The goal is to make a given relay call "rudder remote run" on one of its attached node
The API will be under /rudder/relay-api/remote-run
GET remote-run/node/<node-uuid>
GET remote-run/all
GET remote-run/nodes
Parameters:
- output = keep / discard : to keep the output of the remote-run call or discard its content
- 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
- classes = XXX : list of cfengine classes to set during the remote call
- nodes = uuid,... : list of uuid to call in the "/nodes" case
Behavior:
- Loop on all nodes
- Find its hostname from its uuid in a matching file created by promise generation on the server
- The call is descending, so we don't care about host that do not exist
- The call is descending, so we will only accept calls from the policy server
- Call rudder remote
- prefix the remote output lines with <uuid>: to make sure the caller can parse output during async call on multiple nodes
- 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)
2. Share Files
The goal is to share files between an agent and another one via their policy server.
The API will be under /rudder/relay-api/shared-files
POST shared-files/node/<target_uuid>/<file_id> (share a file content with the target uuid using a given file id)
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)
Parameters:
- source-uuid: the uuid of the node sharing a file with the target uuid
- signature: the file's signature in case of a POST, to authenticate the source node
- hash: the file's hash in case of a HEAD to know is the version already present matches
POST Behavior:
- if the target is known by the local relay
> validate the signature
> store the file in /var/rudder/shared-files-nodes/[..<relay-uuid>..]/<target_uuid>/<source_uuid>/<file_id>
> store the metadata (including, date, hash and signature) in <the same path>.medata
- if the target in not known and we are not the root server
> store the file in a temporary directory
> try to send the file to the relay server
> do nt remove the file and try again as long as there is a fatal error (code >= 500, network error)
- if the target in not known and we are the root server
> ignore the file and return 404
HEAD behavior:
- If the file exists in /var/rudder/shared-files-nodes... with the same hash, return 200
- If it doesn't, return 404
3. Using this API from ncf
We will create 2 new generic methods in ncf:
- sharedfile_to_node(target_uuid, file_id, file_path, ttl) where ttl is infinite by default
- sharedfile_from_node(source_uuid, file_id, file_path)
The first one will call HEAD on the shared-files API and if is gets a 404, call POST to send the content.
The second one will just download the file using regular cfengine protocol.