# Argumentos, salida y códigos de salida

> Cómo nombrar zonas y registros, pasar ajustes clave=valor y JSON, leer la salida con --json y qué significa cada código de salida.

## Sintaxis

```text
openwaf-cloud ctl <familia> <orden> [argumentos] [opciones]
```

Las opciones pueden ir en cualquier posición entre los argumentos, con uno o dos guiones (`--json` o `-json`). Tras `--`, todo es argumento. `-h` o `--help` detrás de cualquier orden imprime su uso y sus opciones; `openwaf-cloud ctl help` imprime la lista completa.

## Cómo se nombra cada cosa

| Argumento | Admite |
|---|---|
| `<zona>` | El dominio (`example.com`) o el id de la zona. El historial de una zona borrada necesita el id. |
| `<registro>` | El id del registro o su nombre: completo (`www.example.com`), relativo (`www`) o `@` para la raíz, con el tipo (`www/A`) si el nombre tiene varios registros. |
| `<certificado>` | El id del certificado o su nombre. |
| `<cliente>` | El id del cliente o su nombre (sin distinguir mayúsculas). |

## Argumentos `clave=valor`

Las órdenes que envían ajustes o campos (`zones set`, `records add`, `rules add`…) reciben argumentos `clave=valor`:

| Forma | Envía | Ejemplo |
|---|---|---|
| `clave=valor` | Enteros y `true`/`false` como tales; el resto, como texto. | `ttl=300`, `proxied=true`, `content=203.0.113.10` |
| `clave.anidada=valor` | Un objeto anidado. | `hsts.max_age=300` → `{"hsts": {"max_age": 300}}` |
| `clave:=<json>` | JSON literal: listas, objetos, `null` o texto que si no se convertiría. | `tags:='["web","prod"]'`, `note:='"42"'` |

Entrecomilla los valores con espacios o caracteres especiales de la shell. Una clave repetida, o una clave anidada que choca con otra simple, es un error de uso.

## Salida

Las consultas imprimen tablas alineadas en español. Añade `--json` a cualquier consulta (y a `cache purge` y `origin-certs`) para imprimir la respuesta de la API tal cual, lista para `jq`:

```sh
openwaf-cloud ctl zones list --json | jq -r '.items[] | [.name, .status, .config_version] | @tsv'
```

Los errores van a la salida de error como `error: <mensaje>`. Si un mensaje pudiera contener tu token, el token se sustituye por `[token]`.

## Códigos de salida

| Código | Significado |
|---|---|
| `0` | Bien, incluido un cambio que resultó no cambiar nada y una simulación con `--dry-run`. |
| `1` | Error: la API rechazó la petición (datos no válidos, permiso denegado, no encontrado…), no se pudo contactar con la API, se rechazó la confirmación, o no había terminal para confirmar ni `--yes`. |
| `2` | Uso: orden desconocida, número de argumentos incorrecto, opción o valor no válidos, falta `--reason`. No se ha enviado nada. |
| `3` | Conflicto de versión: la zona cambió después de la simulación (HTTP 412) y no se aplicó nada; o, durante `--wait`, la zona volvió a cambiar. |
| `4` | El cambio se aplicó, pero algún nodo de borde no lo había confirmado cuando se agotó el plazo de `--wait`. |

## Mensajes de error habituales

| Mensaje | Significado |
|---|---|
| `falta el token: define OPENWAF_TOKEN o OPENWAF_TOKEN_FILE` | No hay token configurado. |
| `no autorizado (401)` | El token no es válido, ha caducado o se ha revocado. |
| `permiso denegado (403)` | El rol o el alcance del token no permiten esta orden. |
| `no encontrado (404)` | El objeto no existe o está fuera de tu organización o del alcance del token. |
| `conflicto de versión (412)` | La zona cambió después de la simulación; no se ha aplicado nada. |
| `datos no válidos (422)` | La API ha rechazado un valor; el mensaje indica el campo. |
| `no se puede hablar con la API en …` | La dirección de la API es incorrecta o no responde; revisa `OPENWAF_API_URL`. |
| `sin terminal para confirmar` | Añade `--yes`, o `--dry-run` para solo simular. |
