Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doveadm: Simplify doveadm response display #1130

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions components/DoveadmComponent.vue
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ function httpClick(k) {
<a class="header-anchor" :href="'#' + k"></a>
</h3>

<table v-if="v.man_link || v.response || v.added || v.changed || v.deprecated || v.removed">
<table v-if="v.man_link || v.added || v.changed || v.deprecated || v.removed">
<tbody>
<tr v-if="v.man_link">
<th style="text-align: right;">Man Page</th>
@@ -79,28 +79,6 @@ function httpClick(k) {
</ul>
</td>
</tr>

<tr v-if="v.response">
<th style="text-align: right;">Response Values</th>
<td>
<table>
<thead>
<tr>
<th>Key</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr v-for="elem in v.response">
<td><code>{{ elem.key }}</code></td>
<td v-html="elem.type" />
<td v-html="elem.text" />
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>

23 changes: 7 additions & 16 deletions components/DoveadmHttpApiComponent.vue
Original file line number Diff line number Diff line change
@@ -21,21 +21,10 @@ const jsonReq =
]
]

const resp = {}
if (d.response) {
for (let elem of d.response) {
resp[elem.key] = elem.example
}
}
const jsonResp = d.response?.example
? [ [ "doveadmResponse", [ d.response.example ], "tag1" ] ]
: null

const jsonResp =
[
[
"doveadmResponse",
[ resp ],
"tag1"
]
]
</script>

<template>
@@ -105,10 +94,12 @@ const jsonResp =
<pre><code>wget --header="Content-Type: application/json" --user=doveadm --password=password --auth-no-challenge --post-data='{{ JSON.stringify(jsonReq) }}' --output-document - http://example.com:8080/doveadm/v1</code></pre>
</div>

<template v-if="d.response?.length">
<template v-if="d.response">
<p class="custom-block-title">Example Server Response</p>

<div class="language- vp-adaptive-theme">
<div v-html="d.response.text" />

<div class="language- vp-adaptive-theme" v-id="jsonResp">
<button class="copy" title="Copy" />
<span class="lang"></span>
<pre><code>{{ JSON.stringify(jsonResp, null, 4) }}</code></pre>
75 changes: 55 additions & 20 deletions data/doveadm.js
Original file line number Diff line number Diff line change
@@ -2,8 +2,7 @@
import { doveadm_arg_types,
doveadm_args_query,
doveadm_args_usermask,
doveadm_flag_types,
doveadm_response_types } from '../lib/doveadm.js'
doveadm_flag_types } from '../lib/doveadm.js'

export const doveadm = {

@@ -52,20 +51,21 @@ export const doveadm = {
// deprecated: {},
// removed: {},

// Response data.
// KEY = identifier
// response: {
// key: {
// // An example value to be used in documentation.
// example: 0,
// Response data. (HTTP API)
//
// Since doveadm responses are so variable, it is difficult to create
// an abstracted system to document the format.
//
// // The description of the response data type.
// // Rendered w/Markdown.
// text: `Description`,
// Thus, (for now) simply provide a place to describe HTTP API
// responses.
// response: {
// // This is the JSON data returned from the server. Do NOT
// // include the enclosing array, as this will be added
// // automatically when displaying.
// example: {},
//
// // The response data type
// type: doveadm_response_types.INTEGER,
// }
// // A description of the response. Rendered w/Markdown.
// text: ``,
// },

// What doveadm flags does this command support (bit field)
@@ -252,10 +252,14 @@ Applicable to [[link,mdbox]] and [[link,sdbox]] mailbox formats only.
},
},
response: {
entries: {
type: doveadm_response_types.INTEGER,
text: `The number of cache entries flushed.`
example: {
entries: 1
},
text: `
| Key | Description |
| --- | ----------- |
| \`entries\` | The number of cache entries flushed. |
`
},
man: 'doveadm-auth',
text: `Flush authentication cache.`,
@@ -1372,7 +1376,7 @@ to secure it.
text: `Mailbox mask.`
},
},
response: {},
response: null,
flags: doveadm_flag_types.USER,
plugin: 'mail-crypt',
man: 'doveadm-mailbox-cryptokey',
@@ -1392,7 +1396,7 @@ to secure it.
text: `Mailbox mask.`
},
},
response: {},
response: null,
flags: doveadm_flag_types.USER,
plugin: 'mail-crypt',
man: 'doveadm-mailbox-cryptokey',
@@ -1427,7 +1431,7 @@ to secure it.
text: `Old password.`
},
},
response: {},
response: null,
flags: doveadm_flag_types.USER,
plugin: 'mail-crypt',
man: 'doveadm-mailbox-cryptokey',
@@ -2269,6 +2273,37 @@ returned.`,
text: `UID -or- IP Address mask.`,
},
},
response: {
example: [
{
username: "foo",
connections: "1",
service: "imap",
pid: "(47)",
ip: "(10.0.2.100)"
}
],
text: `
Returns an array of objects.

If \`separate-connections\` is \`false\`, each object represents a single
username/service combination, and the \`pid\` and \`ip\` fields will include
all entries for that combination.

If \`separate-connections\` is \`true\`, each object will contain a single
connection.

Object fields:

| Key | Description |
| --- | ----------- |
| \`connections\` | The total number of connections for the user. This is only returned if \`separate-connections\` is \`false\`. |
| \`ip\` | IP addresses where the user's connections are originating. |
| \`pid\` | Process IDs of the session. |
| \`service\` | The Dovecot service. |
| \`username\` | Username |
`
},
man: 'doveadm-who',
text: `Show who is logged into the Dovecot server.`,
},
109 changes: 80 additions & 29 deletions docs/core/admin/doveadm.md
Original file line number Diff line number Diff line change
@@ -101,27 +101,54 @@ service doveadm {
Connecting to the endpoint can be done by using standard HTTP protocol and
authentication headers.

To get list the commands supported by the endpoint, the following example
commands can be used:
::: info
There is also https://github.com/dovecot/doveadm-http-cli that can be
used for accessing the API.
:::

All doveadm commands are accessed under the `/doveadm/v1` path.

#### Command List

#### `X-Dovecot-API` Auth
To get the list of commands supported by the endpoint, send an authenticated
GET request to the root of the endpoint (for all endpoint commands), or to
`/doveadm/v1` path (for doveadm API commands).

For example, using [[setting,doveadm_password]] authentication:

```console
$ curl -H "Authorization: X-Dovecot-API <base64 dovecot_api_key>" \
http://host:port/doveadm/v1
curl -X GET –u doveadm:password http://host:port/
```

#### Basic Auth
#### Authentication

##### Basic Auth

Use password as configured in [[setting,doveadm_password]]. User name is
`doveadm`.

```
curl -H "Authorization: Basic <base64 doveadm:doveadm_password>" http://host:port/doveadm/v1
```

or

```console
curl –u doveadm:password http://host:port/doveadm/v1
```

There is also https://github.com/dovecot/doveadm-http-cli that can be
used for accessing the API.
##### `X-Dovecot-API` Auth

Use API Key as configured in [[setting,doveadm_api_key]].

### API overview
```console
$ curl -H "Authorization: X-Dovecot-API <base64 dovecot_api_key>" \
http://host:port/doveadm/v1
```

### API Overview

#### Request

All commands sent to the API needs to be posted in json format using
`Content-Type: application/json` in headers for the request type and the
@@ -176,30 +203,28 @@ Also it is not guaranteed that the commands will be processed in order.
All commands are case sensitive.
:::

### Example Session

Reload Dovecot configuration:
#### Response

```json
[
[
"reload",
{},
"tag1"
]
]
```
Requests that fail *before* the doveadm command is run returns 400/500
HTTP response codes:

Then we execute it with curl:
| Code | Reason |
| ---- | ------ |
| 400 | Invalid request. Response body contains error message in text/plain. |
| 401 | Unauthorized (missing authentication). |
| 403 | Forbidden (authentication failed). |
| 404 | Unknown doveadm command. |
| 500 | Internal server error (see Dovecot logs for more information). |

```console
$ curl -v -u doveadm:secretpassword -X POST http://localhost:8080/doveadm/v1 \
-H "Content-Type: application/json" -d '[["reload",{},"tag1"]]'
```
Otherwise, the response will be a 200 code, Content-Type `application/json`,
and the body will be a JSON object.

This is equivalent to the command [[doveadm,reload]].
##### Success

Successful Response:
::: info Note
All data returned in the JSON object will be strings (e.g., counting fields
will be strings, not numbers/integers).
:::

```json
[
@@ -211,7 +236,10 @@ Successful Response:
]
```

Failure Response:
##### Failure

`exitCode` are the [[link,doveadm_error_codes]].

```json
[
[
@@ -225,6 +253,29 @@ Failure Response:
]
```

### Example Session

Reload Dovecot configuration:

```json
[
[
"reload",
{},
"tag1"
]
]
```

Then we execute it with curl:

```console
$ curl -v -u doveadm:secretpassword -X POST http://localhost:8080/doveadm/v1 \
-H "Content-Type: application/json" -d '[["reload",{},"tag1"]]'
```

This is equivalent to the command [[doveadm,reload]].

## Mailbox Commands

These commands should be run on one of the Dovecot proxies. The proxy is then
Loading