curl --request PUT \
--url https://use.hoop.dev/api/sidecars/{nameOrID} \
--header 'Content-Type: application/json' \
--data '
{
"configuration": {}
}
'import requests
url = "https://use.hoop.dev/api/sidecars/{nameOrID}"
payload = { "configuration": {} }
headers = {"Content-Type": "application/json"}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({configuration: {}})
};
fetch('https://use.hoop.dev/api/sidecars/{nameOrID}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://use.hoop.dev/api/sidecars/{nameOrID}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'configuration' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://use.hoop.dev/api/sidecars/{nameOrID}"
payload := strings.NewReader("{\n \"configuration\": {}\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://use.hoop.dev/api/sidecars/{nameOrID}")
.header("Content-Type", "application/json")
.body("{\n \"configuration\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://use.hoop.dev/api/sidecars/{nameOrID}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"configuration\": {}\n}"
response = http.request(request)
puts response.read_body{
"applied_revision": "8f14e45fceea167a5a36dedd4bea2543",
"bound_rules": [
{
"kind": "guardrail",
"listener_name": "appdb",
"rule_name": "no-destructive-sql"
}
],
"bound_rules_unavailable": true,
"config_state": "applied",
"configuration": {},
"created_at": "<string>",
"created_by": "<string>",
"deprecations": [
"<string>"
],
"detached_rules": {
"deleted": {
"analyzers": [
"<string>"
],
"data_masking": [
"<string>"
],
"guardrails": [
"<string>"
]
},
"unbound": {
"analyzers": [
"<string>"
],
"data_masking": [
"<string>"
],
"guardrails": [
"<string>"
]
}
},
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"last_error": "the control plane sent a config this build refuses: parse config: json: unknown field \"future_key\"",
"last_outcome": "applied",
"last_seen_at": "<string>",
"name": "payments-sidecar",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"served_revision": "8f14e45fceea167a5a36dedd4bea2543",
"version": "1.0.0"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "invalid config: ...",
"problems": [
"newdb: ssh.destinations_allowed: \"10.30.10:1234\" is not a network"
]
}{
"message": "the error description"
}Update Sidecar
Replace the configuration a sidecar serves. The sidecar picks it up on its next heartbeat. A change of load_from_disk is refused: use PATCH.
curl --request PUT \
--url https://use.hoop.dev/api/sidecars/{nameOrID} \
--header 'Content-Type: application/json' \
--data '
{
"configuration": {}
}
'import requests
url = "https://use.hoop.dev/api/sidecars/{nameOrID}"
payload = { "configuration": {} }
headers = {"Content-Type": "application/json"}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({configuration: {}})
};
fetch('https://use.hoop.dev/api/sidecars/{nameOrID}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://use.hoop.dev/api/sidecars/{nameOrID}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'configuration' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://use.hoop.dev/api/sidecars/{nameOrID}"
payload := strings.NewReader("{\n \"configuration\": {}\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://use.hoop.dev/api/sidecars/{nameOrID}")
.header("Content-Type", "application/json")
.body("{\n \"configuration\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://use.hoop.dev/api/sidecars/{nameOrID}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"configuration\": {}\n}"
response = http.request(request)
puts response.read_body{
"applied_revision": "8f14e45fceea167a5a36dedd4bea2543",
"bound_rules": [
{
"kind": "guardrail",
"listener_name": "appdb",
"rule_name": "no-destructive-sql"
}
],
"bound_rules_unavailable": true,
"config_state": "applied",
"configuration": {},
"created_at": "<string>",
"created_by": "<string>",
"deprecations": [
"<string>"
],
"detached_rules": {
"deleted": {
"analyzers": [
"<string>"
],
"data_masking": [
"<string>"
],
"guardrails": [
"<string>"
]
},
"unbound": {
"analyzers": [
"<string>"
],
"data_masking": [
"<string>"
],
"guardrails": [
"<string>"
]
}
},
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"last_error": "the control plane sent a config this build refuses: parse config: json: unknown field \"future_key\"",
"last_outcome": "applied",
"last_seen_at": "<string>",
"name": "payments-sidecar",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"served_revision": "8f14e45fceea167a5a36dedd4bea2543",
"version": "1.0.0"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "the error description"
}{
"message": "invalid config: ...",
"problems": [
"newdb: ssh.destinations_allowed: \"10.30.10:1234\" is not a network"
]
}{
"message": "the error description"
}Path Parameters
Name or UUID of the sidecar
Body
The request body resource
The daemon configuration this sidecar serves. Replaces the stored document entirely.
Response
OK
"8f14e45fceea167a5a36dedd4bea2543"
BoundRules names the rules the control plane distributes to this sidecar, and the listener each one lands on.
They are NOT inside Configuration and never will be: a bound rule is folded into the SERVED document on every handshake and nothing is stored, so one row update reaches a fleet. That is also why this field has to exist — a page reading Configuration alone shows a listener enforcing nothing while the sidecar enforces the rule.
Show child attributes
Show child attributes
BoundRulesUnavailable is true when the bindings could not be read. BoundRules is then empty because it is unknown, not because nothing is bound, and a page must not read it as "no rules".
ConfigState is what the sidecar runs, read from the fields above and the clock: applied, applying (served under a heartbeat ago, not reported yet), not_applied (served longer ago and never reported, the shape of a sidecar that exits at boot on it), refused (by the sidecar), not_served (the control plane refused to serve this build, LastError says why), restart, or unknown (a build too old to report). Empty while nothing was served, before the first handshake, and for a sidecar running its own file; a refusal shows even then.
"applied"
The stored daemon configuration.
Creation timestamp
Subject of the admin who created it
Deprecations lists the deprecated spellings the stored configuration still uses, phrased for an operator. The sidecar folds them on load, where nobody reads the warning.
DetachedRules names the rules an owner switch removed, on the PATCH that switched. Deleted rules came from this sidecar's file; unbound rules stay for their other targets.
Show child attributes
Show child attributes
Unique identifier
LastError is the reason the sidecar gave with a refused or restart outcome. Empty otherwise.
"the control plane sent a config this build refuses: parse config: json: unknown field \"future_key\""
LastOutcome is what the sidecar did with the last configuration it handled: applied, unchanged, restart, refused or retry.
It is the field that separates a sidecar enforcing the current rules from one that refused them and kept the old ones. A refusal, or a document needing a restart, leaves the sidecar handshaking on time with stale rules, and nothing else tells the two apart.
Empty for a sidecar that has handled nothing yet, or one too old to report. Empty must read as unknown, never as converged.
"applied"
Last time the sidecar handshook. Empty until it does.
Human-readable name
"payments-sidecar"
Organization ID
ServedRevision names the configuration last answered to this sidecar, and AppliedRevision the one it says it is running. Equal means the sidecar is enforcing what the control plane holds.
Both are opaque: the control plane issues them and compares them to itself. Nothing parses them.
"8f14e45fceea167a5a36dedd4bea2543"
Version reported at the last handshake. Empty until the sidecar calls.
"1.0.0"
Was this page helpful?