Appearance
ts routing-rule
Show and manage a proxy routing rule — the entity that decides which sites' traffic goes through which proxy.
Usage
text
ts routing-rules
ts routing-rule <id>
ts routing-rule <id> <property>
ts routing-rule new --file=<path>
ts routing-rule set <id> <property> <value>
ts routing-rule set <id> --file=<path>
ts routing-rule delete <id> [--force]Description
Routing rules are the third of the three infrastructure entities behind the served launch policy, and the one that joins the other two: a rule lists sites in siteRefs and names one proxy in action.proxyRef. Create the proxy and the sites first — a rule that references either one before it exists is refused.
A rule carries typed fields plus an open extra bag, so you administer it as a JSON document rather than through a flag per field. ts routing-rules lists the key, whether the rule is enabled, its priority, the sites it covers, and the id. Every other action takes the id — the opaque GUID in the ID column — not the key.
ts routing-rule <id> prints the document exactly as the server stores it, and set consumes that same shape, so redirecting to a file, editing, and writing it back is a faithful round trip. new and set read the document from --file; pass - to read standard input instead. The entityKey is immutable after create, so a set that changes it is rejected, whether it arrives in a document or through the accessor.
For a single field there is a shorter path. ts routing-rule <id> <property> reads one field, and ts routing-rule set <id> <property> <value> writes one. The two write forms are complementary rather than alternatives: the accessor changes one field and leaves the rest of the document as it was, while --file replaces the whole document. Reach for the accessor for a one-field change — most of what you do to a live rule is toggling enabled or nudging priority — and for --file when you are editing structure or several fields at once.
Property names are kebab-case and map to the document's camelCase key, so site-refs addresses siteRefs. Values are typed from the field being replaced — enabled stays a boolean, priority stays a number — so you never have to know a field's wire type. A field that is currently null is the exception: there is nothing to infer a type from, so the value goes in as a string. Use --file for a field like extra that holds an object once it is populated.
A structured field has no accessor form. The two fields that carry a rule's shape, siteRefs and action, are an array and an object, so both are refused with a pointer at --file. An unknown property is refused too. Both refusals happen before anything is written, so a typo cannot half-apply.
The accessor is a read-modify-write: it fetches the document, changes the one field, and sends the whole document back. That is safe here because the document round-trips untyped, so a field this version of ts does not know about is preserved rather than dropped.
Every rule needs an action, and its type must be "proxy" — the only action the launcher understands. Rules default to enabled: true and priority: 200 when the document omits them, and the launcher evaluates lower numbers first, so leave the default in place for the broad rules and give the overrides a smaller number. Setting enabled to false is the reversible way to take a rule out of service; deleting it is not.
ts routing-rule delete prompts unless you pass --force. Unlike sites and proxies, nothing references a rule, so the delete always goes through. Reading rules works for any signed-in account; creating, changing, and deleting them require a Server Administrator.
Options
| Flag | Description | Default/Values | Notes |
|---|---|---|---|
--file | JSON document to send. | PATH, or - for standard input | Required by new. set needs it only for the whole-document form. |
--force, -f | Delete without confirming. | delete only. |
Output
print writes the document and nothing else, so it pipes cleanly:
json
{
"id": "6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43",
"entityKey": "hq-via-hq-socks",
"enabled": true,
"priority": 200,
"siteRefs": ["hq", "branch-west"],
"action": { "type": "proxy", "proxyRef": "hq-socks" },
"extra": null
}Under --format=json the document is wrapped in the standard result envelope as result.entity, which is not what set consumes. Use the default text output for round trips.
A single-field read prints the bare value — true, 200 — so it drops straight into a shell variable or an if. Under --format=json that value comes back in the envelope under the document's own key, result.priority.
Examples
bash
# Every rule, with its priority and the sites it covers
ts routing-rules
# One rule as stored
ts routing-rule 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43
# Just one field — is this rule live, and where does it sit in the order?
ts routing-rule 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43 enabled
ts routing-rule 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43 priority
# Changing which sites the rule covers means editing siteRefs, an array,
# so it goes through the document round trip
ts routing-rule 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43 > rule.json
$EDITOR rule.json
ts routing-rule set 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43 --file=rule.json
# Create one from standard input
cat <<'JSON' | ts routing-rule new --file=-
{ "entityKey": "west-via-west-socks", "priority": 100,
"siteRefs": ["branch-west"],
"action": { "type": "proxy", "proxyRef": "west-socks" } }
JSON
# Take a rule out of service without losing it
ts routing-rule set 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43 enabled false
# Move an override ahead of the broad rules — priority stays a number
ts routing-rule set 6b0e5a91-3d4c-4f28-8a77-c1e2b9d05f43 priority 100
# Gotcha: a rule listed here is not necessarily a rule clients act on. A rule
# with no action is kept in this list so you can repair it, but it is left out
# of the policy the server serves. Check 'ts policy' if a rule seems inert.Exit Codes
0 on success. -1 when the server rejects the document — a duplicate or changed entityKey, a missing action or one whose type is not proxy, or a siteRefs entry or action.proxyRef naming something that does not exist; the message lists what is missing. -1 also covers the accessor's own refusals: a property that is not a field of the rule, and a property holding an object or array, which is how siteRefs and action come back. A single-field read of a property the document does not carry is -6 instead, the same code as an id that does not exist. -4 when no account is signed in. -5 when the account is not a Server Administrator, which affects new, set, and delete but not reads. -6 when the id is not a GUID or no rule has it.
