midpoint-cli 1.5.0.dev2__tar.gz → 1.6.0.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. midpoint_cli-1.6.0.dev2/PKG-INFO +1334 -0
  2. midpoint_cli-1.6.0.dev2/README.md +1301 -0
  3. {midpoint_cli-1.5.0.dev2 → midpoint_cli-1.6.0.dev2}/pyproject.toml +56 -17
  4. midpoint_cli-1.6.0.dev2/src/midpoint_cli/__init__.py +234 -0
  5. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/__init__.py +199 -0
  6. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/audit.py +178 -0
  7. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/audit_query.py +247 -0
  8. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/configuration.py +15 -0
  9. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/constants.py +37 -0
  10. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/errors.py +74 -0
  11. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/logging_config.py +122 -0
  12. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/midpoint_client.py +866 -0
  13. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/object_query.py +230 -0
  14. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/objects.py +814 -0
  15. {midpoint_cli-1.5.0.dev2 → midpoint_cli-1.6.0.dev2}/src/midpoint_cli/client/observer.py +3 -0
  16. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/patch.py +113 -0
  17. {midpoint_cli-1.5.0.dev2 → midpoint_cli-1.6.0.dev2}/src/midpoint_cli/client/progress.py +21 -3
  18. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/rest.py +490 -0
  19. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/safe_xml.py +24 -0
  20. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/server_info.py +130 -0
  21. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/server_version.py +74 -0
  22. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/session.py +142 -0
  23. midpoint_cli-1.6.0.dev2/src/midpoint_cli/client/task_definitions.py +110 -0
  24. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/__init__.py +196 -0
  25. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/audit.py +253 -0
  26. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/base.py +218 -0
  27. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/complete.py +291 -0
  28. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/configuration.py +258 -0
  29. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/connector.py +45 -0
  30. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/console.py +818 -0
  31. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/delete.py +89 -0
  32. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/get.py +66 -0
  33. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/info.py +53 -0
  34. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/log.py +98 -0
  35. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/org.py +122 -0
  36. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/output.py +33 -0
  37. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/put.py +71 -0
  38. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/report.py +69 -0
  39. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/resource.py +217 -0
  40. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/role.py +96 -0
  41. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/script.py +154 -0
  42. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/search.py +51 -0
  43. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/shadow.py +87 -0
  44. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/task.py +296 -0
  45. midpoint_cli-1.6.0.dev2/src/midpoint_cli/prompt/user.py +406 -0
  46. midpoint_cli-1.5.0.dev2/PKG-INFO +0 -797
  47. midpoint_cli-1.5.0.dev2/README.md +0 -764
  48. midpoint_cli-1.5.0.dev2/src/midpoint_cli/__init__.py +0 -83
  49. midpoint_cli-1.5.0.dev2/src/midpoint_cli/client/__init__.py +0 -267
  50. midpoint_cli-1.5.0.dev2/src/midpoint_cli/client/objects.py +0 -461
  51. midpoint_cli-1.5.0.dev2/src/midpoint_cli/client/patch.py +0 -30
  52. midpoint_cli-1.5.0.dev2/src/midpoint_cli/client/session.py +0 -35
  53. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/__init__.py +0 -225
  54. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/base.py +0 -13
  55. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/complete.py +0 -27
  56. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/configuration.py +0 -49
  57. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/console.py +0 -445
  58. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/delete.py +0 -46
  59. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/get.py +0 -50
  60. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/org.py +0 -87
  61. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/put.py +0 -34
  62. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/resource.py +0 -123
  63. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/script.py +0 -58
  64. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/task.py +0 -202
  65. midpoint_cli-1.5.0.dev2/src/midpoint_cli/prompt/user.py +0 -120
  66. {midpoint_cli-1.5.0.dev2 → midpoint_cli-1.6.0.dev2}/LICENSE +0 -0
@@ -0,0 +1,1334 @@
1
+ Metadata-Version: 2.4
2
+ Name: midpoint-cli
3
+ Version: 1.6.0.dev2
4
+ Summary: A command line client to Midpoint Identity Management system.
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Author: Yannick Kirschhoffer
8
+ Author-email: alcibiade@alcibiade.org
9
+ Maintainer: Yannick Kirschhoffer
10
+ Maintainer-email: alcibiade@alcibiade.org
11
+ Requires-Python: >=3.11,<4.0
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Programming Language :: Python :: 3.15
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
24
+ Requires-Dist: prompt-toolkit (>=3.0,<4.0)
25
+ Requires-Dist: pygments (>=2.21,<3.0)
26
+ Requires-Dist: requests (>=2.34,<3.0)
27
+ Requires-Dist: rich (>=13.0,<16.0)
28
+ Requires-Dist: unidecode (>=1.3,<2.0)
29
+ Requires-Dist: urllib3 (>=2.7,<3.0)
30
+ Project-URL: Repository, https://gitlab.com/alcibiade/midpoint-cli
31
+ Description-Content-Type: text/markdown
32
+
33
+ # Midpoint CLI
34
+
35
+ [![PyPI version](https://badge.fury.io/py/midpoint-cli.svg)](https://badge.fury.io/py/midpoint-cli)
36
+ [![Python Support](https://img.shields.io/pypi/pyversions/midpoint-cli.svg)](https://pypi.org/project/midpoint-cli/)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
38
+ [![GitLab CI/CD](https://gitlab.com/alcibiade/midpoint-cli/badges/master/pipeline.svg)](https://gitlab.com/alcibiade/midpoint-cli/-/pipelines)
39
+ [![Latest Release](https://gitlab.com/alcibiade/midpoint-cli/-/badges/release.svg)](https://gitlab.com/alcibiade/midpoint-cli/-/releases)
40
+ [![Coverage](https://gitlab.com/alcibiade/midpoint-cli/badges/master/coverage.svg)](https://gitlab.com/alcibiade/midpoint-cli/-/commits/master)
41
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
42
+ [![Midpoint](https://img.shields.io/badge/Midpoint-4.4%20--%204.11-1f75cb)](https://docs.evolveum.com/midpoint/reference/)
43
+
44
+ This project is a command line client interface used to drive an Evolveum Midpoint identity management server.
45
+
46
+ ## Table of Contents
47
+
48
+ - [Quick Start](#quick-start)
49
+ - [Features](#features)
50
+ - [Installation](#installation)
51
+ - [Through PyPI](#through-pypi)
52
+ - [Development build](#development-build)
53
+ - [Usage](#usage)
54
+ - [General syntax](#general-syntax)
55
+ - [Configuration files](#external-configuration-files-since-v12)
56
+ - [Environment variables](#environment-variables-since-v12)
57
+ - [Usage Examples](#usage-examples)
58
+ - [Interactive Mode](#interactive-mode)
59
+ - [User Management](#user-management)
60
+ - [Organization Management](#organization-management)
61
+ - [Task Management](#task-management)
62
+ - [Resource Management](#resource-management)
63
+ - [Server Information](#server-information)
64
+ - [Logger Levels](#logger-levels)
65
+ - [Reports](#reports)
66
+ - [Searching any object type](#searching-any-object-type)
67
+ - [Audit Log](#audit-log)
68
+ - [Scripting and Automation](#scripting-and-automation)
69
+ - [Working with XML Definitions](#working-with-xml-definitions)
70
+ - [Using Configuration Files](#using-configuration-files)
71
+ - [Setting up a sandbox environment](#setting-up-a-sandbox-environment)
72
+ - [Requirements](#requirements)
73
+
74
+ ## Features
75
+
76
+ The objectives of this tool are to enable:
77
+
78
+ * **Administrator access** to run tasks and review data
79
+ * **Scripting** for remote controlled automation
80
+ * **Test scenarios** implementation
81
+
82
+ ### Core Capabilities
83
+
84
+ The client currently supports:
85
+
86
+ * **User Management:** List, search, create, update, and delete users
87
+ * **Organizational Units:** Display and manage organizational structures
88
+ * **Task Operations:** List tasks with status and duration, run tasks synchronously with progress monitoring
89
+ * **Resource Management:** List resources, test connectivity, retrieve configurations
90
+ * **Object Operations:** Retrieve, create, update, and delete any Midpoint object type via XML
91
+ * **XML Patch Support:** Apply modifications to existing objects using XML patches
92
+
93
+ ### Task Duration Display
94
+
95
+ * **Running tasks** show real-time elapsed time since start
96
+ * **Completed tasks** display total execution time
97
+ * Human-readable format (e.g., "2h 35m 20s", "5m 30s", "45s")
98
+ * Automatic calculation from Midpoint timestamp fields
99
+
100
+ ### Interactive Mode Features
101
+
102
+ The strong points of this project are:
103
+
104
+ * **Dual Execution Modes:** Run commands directly from shell or use an interactive prompt session
105
+ * **Colorized Output:** Color-coded output when running in a terminal for improved readability
106
+ * **Command History:** Bash-compatible command line history with persistent storage across sessions
107
+ * **Tab Completion:** Auto-completion for commands, subcommands, options, object types, and task, user, role, organization and resource names, searched on the server
108
+ * **Interactive Help:** Full built-in help system with command-specific documentation
109
+ * **Standard CLI Syntax:** Classical `midpoint-cli [command] [options]` syntax
110
+
111
+ ### Configuration Flexibility
112
+
113
+ * **Multiple Auth Methods:** Command-line arguments, environment variables, or configuration files
114
+ * **Configuration Priority:** Command-line > Environment variables > Config files > Defaults
115
+ * **Secure Credential Storage:** Use config files, environment variables or the `-P` password prompt to avoid exposing passwords on the command line
116
+
117
+ ## Quick Start
118
+
119
+ ```bash
120
+ # Install via pip
121
+ pip3 install midpoint-cli
122
+
123
+ # Check version
124
+ midpoint-cli --version
125
+
126
+ # Start interactive session with credentials via command line
127
+ midpoint-cli -u administrator -p password -U https://localhost:8080/midpoint/
128
+
129
+ # Prompt for the password instead of exposing it in the process list and shell history
130
+ midpoint-cli -u administrator -P -U https://localhost:8080/midpoint/
131
+
132
+ # Or run a direct command
133
+ midpoint-cli -u administrator -p password -U https://localhost:8080/midpoint/ users
134
+
135
+ # Use environment variables for authentication (recommended)
136
+ export MIDPOINT_URL="https://localhost:8080/midpoint/"
137
+ export MIDPOINT_USERNAME="administrator"
138
+ export MIDPOINT_PASSWORD="password"
139
+
140
+ # Now you can run commands without specifying credentials
141
+ midpoint-cli
142
+ midpoint-cli users
143
+ midpoint-cli tasks
144
+ ```
145
+
146
+ ## Usage
147
+
148
+ ### General syntax
149
+
150
+ ```
151
+ usage: midpoint-cli [-h] [-v] [-u USERNAME] [-p PASSWORD] [-P] [-U URL]
152
+ [-t SECONDS] [--read-timeout SECONDS] [-c PATH]
153
+ [-o {table,json,csv,tsv}]
154
+ [command] ...
155
+
156
+ An interactive Midpoint command line client.
157
+
158
+ positional arguments:
159
+ command Optional command to be executed immediately.
160
+ arg Optional command arguments.
161
+
162
+ options:
163
+ -h, --help show this help message and exit
164
+ -v, --version Show version information and exit.
165
+ -u, --username USERNAME
166
+ Set the username to authenticate this session.
167
+ -p, --password PASSWORD
168
+ Set the password to authenticate this session.
169
+ -P, --ask-password Prompt for the password instead of passing it on the command line,
170
+ where it would be visible in the process list and the shell history.
171
+ -U, --url URL Midpoint base URL
172
+ -t, --timeout SECONDS
173
+ Keep retrying a request the server does not answer for up to SECONDS
174
+ (default: MIDPOINT_TIMEOUT, then the configuration file, then 120).
175
+ --read-timeout SECONDS
176
+ Wait up to SECONDS for the answer to each request; a read timeout is not retried
177
+ (default: MIDPOINT_READ_TIMEOUT, then the configuration file, then 300).
178
+ -c, --config PATH Read settings from this configuration file instead of ~/.midpoint-cli.cfg.
179
+ Defaults to the MIDPOINT_CLI_CONFIG environment variable when set.
180
+ -o, --output {table,json,csv,tsv}
181
+ Output format of list commands (ls, search, users, tasks, ...) and of the
182
+ user, role, org and task get details: a table, or json, csv or tsv for scripts.
183
+ Defaults to table on a terminal and to tsv when the output is redirected or piped.
184
+ The output command changes it during a session.
185
+
186
+ Available commands:
187
+ audit Query the Midpoint audit log (subcommands: ls, object, get).
188
+ connector Inspect connectors (subcommand: ls).
189
+ del Alias for delete.
190
+ delete Delete a server object by type and OID or name.
191
+ get Get an XML definition from the server by type and OID or name.
192
+ help List available commands with "help" or detailed help with "help cmd".
193
+ info Display server information (version, repository, subscription, nodes, account).
194
+ log Show and set server logger levels (subcommands: ls, set; or: log LOGGER LEVEL).
195
+ org Manage organizations (subcommands: ls, search, get).
196
+ orgs Shortcut for 'org ls' — list all organizations.
197
+ output Show or change the output format of this session (table, json, csv, tsv).
198
+ put Create or update a server object from an XML file.
199
+ report List and run reports (subcommands: ls, run).
200
+ resource Manage server resources (subcommands: ls, test, import, reconcile).
201
+ resources Shortcut for 'resource ls' — list all server resources.
202
+ rm Alias for delete.
203
+ role Manage roles (subcommands: ls, search, get).
204
+ roles Shortcut for 'role ls' — list all roles.
205
+ script Execute a local Python client script (subcommand: run).
206
+ search Search server objects of any type with a Midpoint Query Language filter.
207
+ shadow Inspect resource object shadows (subcommand: ls).
208
+ task Manage server tasks (subcommands: ls, run, suspend, resume, wait, get).
209
+ tasks Shortcut for 'task ls' — list all server tasks.
210
+ user Manage users (subcommands: ls, search, get, assign, unassign, enable, disable, passwd).
211
+ users Shortcut for 'user ls' — list all users.
212
+
213
+ Server URL and credentials can also be stored in ~/.midpoint-cli.cfg, or in a file
214
+ named with --config or MIDPOINT_CLI_CONFIG, or read from environment variables
215
+ MIDPOINT_URL, MIDPOINT_USERNAME and MIDPOINT_PASSWORD.
216
+ Prefer those, or -P, over -p: a password given on the command line is visible to other users.
217
+ The retry timeout (--timeout) can also be set with MIDPOINT_TIMEOUT or a timeout
218
+ key in the configuration file; it defaults to 120 seconds.
219
+ The read timeout (--read-timeout) can also be set with MIDPOINT_READ_TIMEOUT or a
220
+ read_timeout key in the configuration file; it defaults to 300 seconds.
221
+
222
+ Midpoint-cli version 1.6.0.dev2, created and maintained by Yannick Kirschhoffer alcibiade@alcibiade.org
223
+ ```
224
+
225
+ Global options must come before the command: everything after the command word is passed
226
+ to the command unchanged, so `midpoint-cli put -p patch.xml object.xml` uses `-p` as the
227
+ `put` patch flag, not as the password. Likewise write `midpoint-cli -o json users`, not
228
+ `midpoint-cli users -o json`.
229
+
230
+ ### Output formats and scripting (since v1.6)
231
+
232
+ Every list command (`user ls`/`search`, `role ls`/`search`, `org ls`/`search`, `task ls`,
233
+ `resource ls`, `shadow ls`, `connector ls`, `report ls`, `search`, `audit ls`/`object`/`get`,
234
+ `log ls` and the `users`, `roles`, `orgs`, `tasks` and `resources` shortcuts) prints its rows in
235
+ the format chosen with `-o`/`--output`, and so does `info`, as `Property`/`Value` rows:
236
+
237
+ * `table`: the colored, boxed table, followed by a `Total: N ...` line. This is the default
238
+ on a terminal.
239
+ * `tsv`: a header line, then one tab-separated line per row, with full values (OIDs are never
240
+ shortened). Backslash, tab and newline inside a value are written as `\\`, `\t` and `\n`.
241
+ This is the default when standard output is redirected or piped.
242
+ * `csv`: the same rows as RFC 4180 CSV, with a header line.
243
+ * `json`: an array of objects keyed by column name, e.g. `[{"OID": "...", "Name": "..."}]`.
244
+
245
+ Standard output carries data only: tables, rows, object details and XML. Errors, warnings,
246
+ status lines (`Waiting for task ...`, `Object uploaded: ...`), totals and task progress go to
247
+ standard error, so `midpoint-cli get user OID > user.xml` never writes an error into
248
+ `user.xml`, and `midpoint-cli tasks | grep ...` only sees task rows. With `audit ... --show-deltas`
249
+ and `audit get`, the machine formats carry the deltas as XML in an extra `Deltas` column instead
250
+ of the delta tree.
251
+
252
+ The audit listings end with an `EventIdentifier` column (before `Deltas`), the value
253
+ `audit get` takes:
254
+
255
+ ```bash
256
+ midpoint-cli -o tsv audit ls --since 1h | cut -f8 # event identifiers, after the header line
257
+ ```
258
+
259
+ The detail views `user get`, `role get`, `org get` and `task get` follow `-o` too. The table
260
+ format shows the same tables as before; the machine formats give:
261
+
262
+ * `json`: one object per object shown, or an array of objects when `task get` is given several
263
+ tasks. Every value is a string. Related records are arrays of objects keyed by the column
264
+ names of their table: a user has `Roles` and `Orgs` (`OID`, `Name`, `Status`) and
265
+ `Projections` (`Shadow OID`, `Resource`, `Account Name`, `Kind`, `Intent`); a task has
266
+ `Transitions` (`From State`, `To State`, `Count`) and `Actions` (`Type`, `Action`, `Success`,
267
+ `Failure`). A user's attributes keep their schema names (`name`, `fullName`, ...), and a
268
+ property present several times is an array of its values. Role and org objects carry all
269
+ their properties, empty ones included, so every object has the same keys.
270
+
271
+ ```bash
272
+ midpoint-cli -o json user get jdoe | jq -r '.Roles[].Name'
273
+ midpoint-cli -o json task get 'Recompute users' | jq '.Actions[] | select(.Failure != "0")'
274
+ ```
275
+
276
+ * `csv`, `tsv`: `Property`/`Value` rows, one per value, like `info`. Values of related records
277
+ are named by their path, e.g. `Roles[0].Name` or `Actions[1].Failure`; a repeated property is
278
+ `subtype[0]`, `subtype[1]`. With several tasks, their rows follow each other, each task
279
+ starting with its `OID` row.
280
+
281
+ `get` is not affected: it always prints the XML exactly as the server returned it.
282
+
283
+ In an interactive session or a piped command script, `output FORMAT` switches the format for
284
+ the commands that follow, and `output` alone shows the current one:
285
+
286
+ ```
287
+ midpoint> output json
288
+ ℹ Output format set to json
289
+ midpoint> user get jdoe
290
+ { ... }
291
+ midpoint> output table
292
+ ```
293
+
294
+ ### External configuration files (since v1.2)
295
+
296
+ Settings can be provided from an external configuration file. A single file is read:
297
+
298
+ * the file named with `--config PATH` (`-c PATH`), if given;
299
+ * otherwise the file named by the `MIDPOINT_CLI_CONFIG` environment variable, if set;
300
+ * otherwise `.midpoint-cli.cfg` in the home directory of the current user, if it exists.
301
+
302
+ A named file that does not exist or cannot be parsed is an error. A `midpoint-cli.cfg` in the
303
+ current working directory is **not** read implicitly (since v1.6): a file picked up from
304
+ whatever directory you happen to be in could redirect the server URL your credentials are
305
+ sent to. Name it explicitly instead, for example `midpoint-cli --config midpoint-cli.cfg`.
306
+
307
+ Values from the configuration file are overridden by environment variables, which are in
308
+ turn overridden by command-line options.
309
+
310
+ Without any setting, the URL defaults to `http://localhost:8080/midpoint/` and the user to
311
+ `administrator`. There is no default password (since v1.6): when none comes from `-p`/`-P`,
312
+ `MIDPOINT_PASSWORD` or the configuration file, midpoint-cli prompts for it if standard input is
313
+ a terminal, and otherwise stops with an error (exit code 2) instead of trying the Midpoint demo
314
+ password. Code that builds a `MidpointClientConfiguration` directly gets no default password
315
+ either: the client refuses to send a REST call until one is set.
316
+
317
+ A configuration file holding a password should be readable by you alone (`chmod 600`). When it
318
+ is accessible by group or other users, midpoint-cli prints an SSH-style warning on stderr,
319
+ unless the server URL is a loopback address such as the local sandbox.
320
+
321
+ An interactive session starts by naming the server URL, user, retry timeout and read timeout in effect and where each
322
+ setting came from (command-line option, environment variable, which configuration file, or
323
+ default), and points out a `midpoint-cli.cfg` in the working directory that is not being read.
324
+ The `info` command prints the same line before the server information, also in one-shot
325
+ and piped use, where there is no banner.
326
+
327
+ The syntax is as follows:
328
+
329
+ ```
330
+ [Midpoint]
331
+ url = https://localhost:8080/midpoint/
332
+ username = administrator
333
+ password = ...
334
+ # Optional: seconds to keep retrying a request the server does not answer (default 120)
335
+ timeout = 300
336
+ # Optional: seconds to wait for the answer to one request (default 300)
337
+ read_timeout = 900
338
+ ```
339
+
340
+ ### Environment variables (since v1.2)
341
+
342
+ The script will scan environment variables to read input parameters. This is
343
+ particularly useful for injection of password or in-container execution.
344
+
345
+ The variables are:
346
+
347
+ * MIDPOINT_URL
348
+ * MIDPOINT_USERNAME
349
+ * MIDPOINT_PASSWORD
350
+ * MIDPOINT_TIMEOUT: how long, in seconds, to keep retrying a request when the server
351
+ does not answer (refused connection, connect timeout), for example while it is still
352
+ booting. Defaults to 120. Scripts that start a Midpoint server and call the CLI straight
353
+ away should wait for the server first, or raise this value. The `-t SECONDS`
354
+ (`--timeout SECONDS`) option overrides it, and it overrides a `timeout` key in the
355
+ configuration file. A value that is not a positive number is a usage error (exit code 2)
356
+ on the command line and in the configuration file; in `MIDPOINT_TIMEOUT` it is ignored
357
+ with a warning.
358
+ * MIDPOINT_READ_TIMEOUT: how long, in seconds, to wait for the answer to one request once
359
+ the server has accepted it. Defaults to 300; raise it for calls that legitimately take
360
+ longer (large searches, slow resource tests, synchronous task runs). A read timeout is
361
+ reported at once and never retried, since the server may still be processing the request.
362
+ The `--read-timeout SECONDS` option overrides it, and it overrides a `read_timeout` key in
363
+ the configuration file, with the same validation as `MIDPOINT_TIMEOUT`.
364
+ * MIDPOINT_CLI_FOLLOW_SYMLINKS: set to `1` (or `true`, `yes`, `on`) to let `get ... FILE`
365
+ and `put -p ... -w` write through a symbolic link. By default they refuse (since v1.6):
366
+ see [Get user details](#get-user-details-xml-definition).
367
+
368
+ ## Usage Examples
369
+
370
+ ### Interactive Mode
371
+
372
+ The interactive mode is one of the strongest features of midpoint-cli. It provides a persistent session with command history, tab completion, colorized output, and a built-in help system. This is ideal for exploring your Midpoint server, troubleshooting, and performing multiple operations without re-authenticating.
373
+
374
+ #### Starting an Interactive Session
375
+
376
+ ```bash
377
+ # Start interactive session with authentication
378
+ midpoint-cli -u administrator -p mypassword -U https://midpoint.example.com/midpoint/
379
+
380
+ # Or use environment variables (recommended)
381
+ export MIDPOINT_URL="https://midpoint.example.com/midpoint/"
382
+ export MIDPOINT_USERNAME="administrator"
383
+ export MIDPOINT_PASSWORD="mypassword"
384
+ midpoint-cli
385
+
386
+ # Or use a configuration file
387
+ # Create ~/.midpoint-cli.cfg with your credentials
388
+ midpoint-cli
389
+ ```
390
+
391
+ #### Interactive Features
392
+
393
+ **Command History Navigation:**
394
+ - Use arrow keys (↑/↓) to navigate through command history
395
+ - History is persistent across sessions (bash-compatible)
396
+ - Search history with Ctrl+R
397
+
398
+ **Tab Completion:**
399
+ - Complete commands, subcommands and `--options` by pressing Tab
400
+ - Object types after `get` and `delete` (e.g. `get us<Tab>` → `user`), then names when the type
401
+ is a task, user, role, org or resource (e.g. `delete user jd<Tab>` → `jdoe`)
402
+ - Names for `task get/run/wait/suspend/resume`, `user get/assign/unassign`, `role get`, `org get`,
403
+ `resource test` and `audit ls --user`; names containing spaces are quoted for you
404
+ - Names are looked up on the server by prefix (case-insensitive), at most 50 at a time
405
+ - File paths for `put`, `script run` and the optional output file of `get`
406
+
407
+ **Colorized Output:**
408
+ - Automatic color-coded output when running in a terminal
409
+ - Improved readability for status indicators and tables
410
+
411
+ **Built-in Help System:**
412
+ ```bash
413
+ midpoint> help
414
+ # Shows all available commands
415
+
416
+ midpoint> help users
417
+ # Shows detailed help for the users command
418
+
419
+ midpoint> help task
420
+ # Shows task-related subcommands and usage
421
+ ```
422
+
423
+ #### Common Interactive Workflows
424
+
425
+ **Exploring Users and Organizations:**
426
+ ```bash
427
+ midpoint> users
428
+ # Lists all users with their details
429
+
430
+ midpoint> user search john
431
+ # Search for users matching "john" (in name, full name or email)
432
+
433
+ midpoint> user search +example.com Doe Smith
434
+ # Users at example.com who match Doe or Smith (mandatory + optional OR)
435
+
436
+ midpoint> org
437
+ # List all organizational units
438
+
439
+ midpoint> get user 12345678-abcd-1234-abcd-123456789012
440
+ # Get detailed XML definition of a specific user
441
+ ```
442
+
443
+ **Task Management Workflow:**
444
+ ```bash
445
+ midpoint> tasks
446
+ # View all tasks with status and duration
447
+
448
+ midpoint> task run "Recompute All Users"
449
+ # Execute a task and monitor progress
450
+ # For running tasks, duration shows elapsed time
451
+ # For completed tasks, duration shows total execution time
452
+
453
+ midpoint> tasks
454
+ # Check updated status after task completion
455
+ ```
456
+
457
+ **Resource Testing and Monitoring:**
458
+ ```bash
459
+ midpoint> resources
460
+ # List all configured resources
461
+
462
+ midpoint> resource test "Active Directory"
463
+ # Test connectivity to a specific resource
464
+
465
+ midpoint> tasks
466
+ # View any reconciliation tasks that may have been triggered
467
+ ```
468
+
469
+ **Quick Object Inspection:**
470
+ ```bash
471
+ midpoint> get user 00000000-0000-0000-0000-000000000002
472
+ # Get administrator user definition
473
+
474
+ midpoint> get task 12345678-task-1234-abcd-123456789012
475
+ # Get task details and configuration
476
+
477
+ midpoint> get resource 12345678-res1-1234-abcd-123456789012
478
+ # Get resource configuration
479
+ ```
480
+
481
+ #### Interactive vs. Direct Execution
482
+
483
+ **Interactive mode advantages:**
484
+ - No need to re-authenticate for each command
485
+ - Command history for repeated operations
486
+ - Tab completion for faster input
487
+ - Persistent session for exploration
488
+ - Better for troubleshooting and manual operations
489
+
490
+ **Direct execution advantages:**
491
+ - Better for scripting and automation
492
+ - Can be used in CI/CD pipelines
493
+ - Single command operations
494
+ - Output can be easily piped to other commands
495
+
496
+ Commands can also be piped on standard input, one per line. Every line runs, and the process
497
+ exits with the code of the first line that failed (for example 3 for a `script run` that called
498
+ `sys.exit(3)`), or 0 when all of them succeeded.
499
+
500
+ **Example comparison:**
501
+ ```bash
502
+ # Direct execution - requires full authentication each time
503
+ midpoint-cli -u admin -p pass -U https://localhost:8080/midpoint/ users
504
+ midpoint-cli -u admin -p pass -U https://localhost:8080/midpoint/ tasks
505
+ midpoint-cli -u admin -p pass -U https://localhost:8080/midpoint/ resources
506
+
507
+ # Interactive mode - authenticate once, run multiple commands
508
+ midpoint-cli -u admin -p pass -U https://localhost:8080/midpoint/
509
+ midpoint> users
510
+ midpoint> tasks
511
+ midpoint> resources
512
+ midpoint> task run "Recompute All Users"
513
+ midpoint> tasks
514
+ midpoint> exit
515
+ ```
516
+
517
+ ### User Management
518
+
519
+ #### List all users
520
+
521
+ ```bash
522
+ # Direct command execution
523
+ midpoint-cli -u admin -p pass -U https://localhost:8080/midpoint/ users
524
+
525
+ # Output example:
526
+ # OID Name Title FullName Status EmpNo Email OU
527
+ # ------------------------------------ ------------- -------------- --------------- -------- ------- ----------------------- ----
528
+ # 00000000-0000-0000-0000-000000000002 administrator Administrator enabled admin@example.com
529
+ # 12345678-abcd-1234-abcd-123456789012 jdoe IT Manager John Doe enabled E12345 jdoe@example.com IT
530
+ ```
531
+
532
+ #### Limit and filter a listing
533
+
534
+ Every `ls` command (`user`, `role`, `org`, `task`, `resource`) accepts `--limit N` and
535
+ `--filter TEXT`. With either option the server filters and pages the list instead of the CLI
536
+ downloading the whole collection, which matters on deployments with many objects:
537
+
538
+ ```bash
539
+ # The first 20 users, sorted by name
540
+ midpoint-cli user ls --limit 20
541
+
542
+ # Tasks whose name contains "recon" (case-insensitive)
543
+ midpoint-cli task ls --filter recon
544
+
545
+ # Both
546
+ midpoint-cli role ls --filter admin --limit 10
547
+ ```
548
+
549
+ Without these options `ls` lists the whole collection, as before.
550
+
551
+ #### Search for a specific user
552
+
553
+ ```bash
554
+ # Search by name, full name or email (OR: matches users containing "john" OR "jane")
555
+ midpoint-cli user search john jane
556
+
557
+ # Mandatory terms with + prefix (AND: must contain both "john" AND "doe")
558
+ midpoint-cli user search +john +doe
559
+
560
+ # Mixed: email must contain example.com AND name must match Doe or Smith
561
+ midpoint-cli user search +example.com Doe Smith
562
+ ```
563
+
564
+ Searches run on the server. Terms are case-insensitive and matched as substrings of the user's
565
+ name, full name and email address (`role search` and `org search` match the name and display
566
+ name). Name matching uses Midpoint's normalized form, so accents are ignored (e.g. `francois`
567
+ matches `François`).
568
+
569
+ #### Get user details (XML definition)
570
+
571
+ ```bash
572
+ # Retrieve full XML definition of a user by OID
573
+ midpoint-cli get user 12345678-abcd-1234-abcd-123456789012
574
+
575
+ # Save user definition to a file
576
+ midpoint-cli get user 12345678-abcd-1234-abcd-123456789012 > user-backup.xml
577
+
578
+ # A name works too
579
+ midpoint-cli get user jdoe
580
+
581
+ # Or let midpoint-cli write the file, readable by you only (mode 0600)
582
+ midpoint-cli get user 12345678-abcd-1234-abcd-123456789012 user-backup.xml
583
+ ```
584
+
585
+ Files written by midpoint-cli itself (`get TYPE OID FILE`, and the `<patchfile>.xml` written by
586
+ `put -p PATCH -w`) can hold passwords and personal data, so they are created with mode 0600 and
587
+ an existing file is tightened to 0600 before it is overwritten. Since v1.6 midpoint-cli also
588
+ refuses to write when the target is a symbolic link, because a link planted in a shared
589
+ directory would otherwise redirect the export to another file and overwrite it. The command
590
+ fails with an error naming the link and nothing is written. Directories along the path may still
591
+ be links. If you write through a link on purpose, give the link target instead (for example
592
+ `"$(readlink -f user-backup.xml)"`), or set `MIDPOINT_CLI_FOLLOW_SYMLINKS=1`.
593
+
594
+ #### Create or update a user
595
+
596
+ ```bash
597
+ # Upload a user definition from an XML file
598
+ midpoint-cli put user-definition.xml
599
+
600
+ # Upload a user definition after applying a patch file to it
601
+ midpoint-cli put -p user.patch user-definition.xml
602
+ ```
603
+
604
+ When the root element has an `oid` attribute, `put` creates or replaces the object at that
605
+ OID and prints `Object uploaded: UserType <oid>`. Without one, it creates a new object, the
606
+ server assigns the OID and `put` prints `Object created: UserType <oid>`. If the server
607
+ accepts the object without creating it yet (for example while an approval is pending), `put`
608
+ prints `Object accepted` without an OID.
609
+
610
+ See [Apply patches to objects](#apply-patches-to-objects) for the patch file format.
611
+
612
+ #### Assign roles, orgs, archetypes and services
613
+
614
+ ```bash
615
+ # Assign a role (the default target type), then remove the assignment
616
+ midpoint-cli user assign jdoe "Employee"
617
+ midpoint-cli user unassign jdoe "Employee"
618
+
619
+ # Org membership, archetype and service assignments
620
+ midpoint-cli user assign jdoe --org "Sales"
621
+ midpoint-cli user assign jdoe --archetype "Contractor"
622
+ midpoint-cli user unassign jdoe --service "Printer"
623
+ ```
624
+
625
+ The option names the type of the target, which is looked up by name or OID in that type
626
+ only: `user assign jdoe --org Employee` fails if no org is named Employee, even when a role
627
+ is.
628
+
629
+ #### Enable, disable and set passwords
630
+
631
+ ```bash
632
+ # Set the administrative status of one or more users
633
+ midpoint-cli user disable jdoe asmith
634
+ midpoint-cli user enable jdoe
635
+
636
+ # Set a password: asked twice, without echo, on a terminal
637
+ midpoint-cli user passwd jdoe
638
+
639
+ # In scripts, the first line of standard input is the password...
640
+ printf '%s\n' "$NEW_PASSWORD" | midpoint-cli user passwd jdoe
641
+
642
+ # ...or an environment variable names it
643
+ NEW_PASSWORD=... midpoint-cli user passwd jdoe --password-env NEW_PASSWORD
644
+ ```
645
+
646
+ The password is sent as a protected string in clear (`t:clearValue`) and the server encrypts
647
+ or hashes it as its policy says; the server also checks it against the password policy. It is
648
+ never printed, logged or written to the command history, and no option takes the password
649
+ itself, so it never appears in the process list. In a command script piped to `midpoint-cli`,
650
+ the password is the line after `user passwd`.
651
+
652
+ #### Delete a user
653
+
654
+ ```bash
655
+ # Delete a user by OID
656
+ midpoint-cli delete user 12345678-abcd-1234-abcd-123456789012
657
+
658
+ # Delete a user by name: asks for confirmation in a terminal (the question is written
659
+ # on stderr); scripts must add --yes
660
+ midpoint-cli delete user jdoe --yes
661
+ ```
662
+
663
+ #### Names and OIDs
664
+
665
+ Every command that takes an object (`get`, `delete`, `user get`/`assign`/`unassign`/
666
+ `enable`/`disable`/`passwd`, `role get`, `org get`, `task run`/`get`/`wait`/`suspend`/`resume`,
667
+ `resource test`/`import`/`reconcile`, `shadow ls --resource`, `report run` and
668
+ `audit ls --user`) accepts an OID or a name. A value in OID form is used as an OID. Names
669
+ are looked up on the server, exactly and case-sensitively. Some names are not unique: task
670
+ names, for instance, often repeat. When a name matches several objects, the command lists
671
+ their OIDs and does nothing with them, instead of acting on whichever came first:
672
+
673
+ ```
674
+ $ midpoint-cli task run Recompute
675
+ Error: Ambiguous task name 'Recompute': 2 objects have it (OIDs: 3f2a..., 9c41...). Use an OID instead.
676
+ ```
677
+
678
+ ### Organization Management
679
+
680
+ #### List organizational units
681
+
682
+ ```bash
683
+ # List all organizational units
684
+ midpoint-cli org
685
+
686
+ # Interactive mode
687
+ midpoint> org
688
+ # OID Name Parent Description
689
+ # ------------------------------------ -------------- -------- ---------------------
690
+ # 12345678-org1-1234-abcd-123456789012 Engineering Root Engineering Department
691
+ # 12345678-org2-1234-abcd-123456789012 IT Operations Root IT Operations Team
692
+ ```
693
+
694
+ #### Get organization details
695
+
696
+ ```bash
697
+ # Get full XML definition of an org unit
698
+ midpoint-cli get org 12345678-org1-1234-abcd-123456789012
699
+ ```
700
+
701
+ ### Task Management
702
+
703
+ #### List all tasks
704
+
705
+ ```bash
706
+ # List all tasks with status and duration
707
+ midpoint-cli tasks
708
+
709
+ # Output shows running tasks with elapsed time and completed tasks with total execution time
710
+ # Task Name Status Duration Last Run
711
+ # --------------------------- --------- ---------- --------------------
712
+ # Import from HR System running 1h 25m 30s 2025-10-14 10:30:00
713
+ # Recompute All Users closed 5m 42s 2025-10-14 09:15:00
714
+ # Reconciliation Task waiting - Not yet started
715
+ ```
716
+
717
+ #### List tasks by status
718
+
719
+ ```bash
720
+ # Suspended tasks, and tasks whose last run failed (fatal or partial error)
721
+ midpoint-cli task ls --status suspended
722
+ midpoint-cli task ls --status failed
723
+
724
+ # Repeat --status to list tasks in any of several states
725
+ midpoint-cli task ls --status running --status runnable
726
+ ```
727
+
728
+ `--status` takes an execution state (`running`, `runnable`, `waiting`, `suspended`, `closed`)
729
+ or the result of the last run (`in_progress`, `success`, `warning`, `failed`). The server
730
+ filters the tasks, so it combines with `--limit` and `--filter`.
731
+
732
+ #### Execute a task synchronously
733
+
734
+ ```bash
735
+ # Run a task and wait for completion
736
+ midpoint-cli task run "Recompute All Users"
737
+
738
+ # Run task by OID
739
+ midpoint-cli task run 12345678-task-1234-abcd-123456789012
740
+ ```
741
+
742
+ While `task run` and `task wait` follow a task, standard error shows one mark per processed
743
+ item: `.` for a success and `F` for a failure, where failures are the failed actions of the
744
+ task statistics. A summary with the success and error counts ends the progress. On a terminal,
745
+ the progress is a single animated line instead: a bar (filled against the expected total when
746
+ the task has one), the items processed, the success and failure counts, the most recent marks
747
+ (failures in red) and the time since the task started:
748
+
749
+ ```
750
+ ⠙ ━━━━━━━━━━━━━━━━╺━━━━━━━ 40/60 66% ✓ 35 ✗ 5 F.............FF 0:30
751
+ ```
752
+
753
+ When a task fails, its details, transitions and action counts are printed before the error.
754
+ While the server cannot be reached, a terminal shows a spinner with the number of retries and
755
+ the time waited; elsewhere, a dot is printed per retry.
756
+
757
+ #### Get task details
758
+
759
+ ```bash
760
+ # Get task status and XML definition
761
+ midpoint-cli get task 12345678-task-1234-abcd-123456789012
762
+ ```
763
+
764
+ #### Monitor long-running tasks
765
+
766
+ ```bash
767
+ # In interactive mode, you can repeatedly check task status
768
+ midpoint> task run "Import from HR System"
769
+ # Task started: 12345678-task-1234-abcd-123456789012
770
+ # Status: running (Duration: 5m 30s)
771
+
772
+ midpoint> tasks
773
+ # Check all running tasks with real-time duration updates
774
+ ```
775
+
776
+ ### Resource Management
777
+
778
+ #### List all resources
779
+
780
+ ```bash
781
+ # List configured resources
782
+ midpoint-cli resources
783
+
784
+ # Example output:
785
+ # OID Name Type Status
786
+ # ------------------------------------ ---------------- ------------ --------
787
+ # 12345678-res1-1234-abcd-123456789012 Active Directory LDAP UP
788
+ # 12345678-res2-1234-abcd-123456789012 HR Database Database UP
789
+ ```
790
+
791
+ `resource ls` (and `resources`) exits with status 1 when any listed resource reports an
792
+ availability status other than `up`. Resources with no recorded status (e.g. never tested)
793
+ and an empty resource list do not affect the exit status.
794
+
795
+ #### Shadow metrics
796
+
797
+ ```bash
798
+ # Count the shadows of each resource by synchronization situation
799
+ midpoint-cli resource ls --metrics
800
+ midpoint-cli -o csv resource ls --metrics --filter HR
801
+ ```
802
+
803
+ `--metrics` adds the columns `Linked`, `Unlinked`, `Unmatched`, `Disputed`, `Deleted`,
804
+ `No Situation` and `Shadows` (the total) to each resource. The counts cover every shadow the
805
+ repository holds for the resource (all kinds and intents, dead shadows included); they are
806
+ read with the `raw` option, so no resource is contacted.
807
+
808
+ The metrics are optional because their cost depends on the server version:
809
+
810
+ * Midpoint 4.10 and later count on the server (`returnTotalCount`), with six small searches
811
+ per resource whatever its size.
812
+ * Midpoint 4.4 to 4.9 cannot return a count over REST, so all shadows of each resource are
813
+ downloaded in one search and counted by the CLI. On resources with many thousands of
814
+ accounts this is slow and memory hungry: narrow the listing with `--filter` or `--limit`.
815
+
816
+ A resource whose shadows cannot be counted (e.g. the account may not read shadows) gets empty
817
+ cells and a warning on standard error; the exit status still only reflects availability.
818
+
819
+ #### Test a resource connection
820
+
821
+ ```bash
822
+ # Test resource connectivity
823
+ midpoint-cli resource test 12345678-res1-1234-abcd-123456789012
824
+
825
+ # Test by resource name
826
+ midpoint-cli resource test "Active Directory"
827
+ ```
828
+
829
+ #### Import and reconcile a resource
830
+
831
+ ```bash
832
+ # Import the accounts of a resource, following the task like `task run`
833
+ midpoint-cli resource import "HR Database"
834
+
835
+ # Reconcile the entitlements of one intent
836
+ midpoint-cli resource reconcile "Active Directory" --kind entitlement --intent group
837
+
838
+ # Select by object class instead, and return at once with the task OID on standard output
839
+ TASK_OID=$(midpoint-cli resource import "Active Directory" --object-class inetOrgPerson --no-wait)
840
+ ```
841
+
842
+ Midpoint's REST API has no import or reconciliation operation for a kind and intent, so these
843
+ commands create the task the Midpoint GUI would create (an activity-based task with the Import
844
+ or Reconciliation task archetype, named after the resource and the time) and the server starts
845
+ it. Without `--kind` and `--object-class`, the accounts of the resource are processed. The
846
+ task stays on the server: `task run` runs it again.
847
+
848
+ #### List shadows and connectors
849
+
850
+ ```bash
851
+ # Shadows of one resource, kind and intent, with their synchronization situation
852
+ midpoint-cli shadow ls --resource "HR Database" --kind account --intent default
853
+
854
+ # Connectors installed on the server, with their type, version and bundle
855
+ midpoint-cli connector ls
856
+ ```
857
+
858
+ `shadow ls` reads the Midpoint repository only (a raw search): it shows what Midpoint last
859
+ saw on the resource without contacting it.
860
+
861
+ #### Get resource configuration
862
+
863
+ ```bash
864
+ # Retrieve full resource definition
865
+ midpoint-cli get resource 12345678-res1-1234-abcd-123456789012 > ad-resource.xml
866
+ ```
867
+
868
+ ### Server Information
869
+
870
+ ```bash
871
+ midpoint-cli info
872
+ # Same data as Property/Value rows, for scripts
873
+ midpoint-cli -o json info
874
+ ```
875
+
876
+ `info` gathers what the REST API tells about the server, in the spirit of the web UI's
877
+ About page:
878
+
879
+ | Property | Source | Notes |
880
+ |----------|--------|-------|
881
+ | Midpoint Version, Build, Branch, Build Timestamp, License | `actuator/info` | All versions 4.4 to 4.11. Without it, the version comes from the nodes' build. |
882
+ | Repository | the version | `native (PostgreSQL)` from 4.10 on, where the generic repository is gone. Earlier versions do not report it over REST: see the About page. |
883
+ | Deployment Name, Subscription | system configuration (`deploymentInformation`) | Only says whether a subscription identifier is configured, never the identifier itself; the server decides whether it is valid. |
884
+ | Nodes, Node *id* | `ws/rest/nodes` | Host, execution state, Midpoint build and last check-in of each cluster node. |
885
+ | Logged In As | `ws/rest/self` | The account the CLI authenticated as. |
886
+
887
+ A source the account may not read (or a proxy hides) is left out with a warning on standard
888
+ error, and `info` still succeeds. It fails when nothing can be read, or at once when the server
889
+ does not answer or rejects the credentials.
890
+
891
+ ### Logger Levels
892
+
893
+ ```bash
894
+ # Raise the level of a logger, adding it to the logging configuration if needed
895
+ midpoint-cli log lu.lns.connector DEBUG
896
+ # Same, with the explicit subcommand
897
+ midpoint-cli log set com.evolveum.midpoint.model.impl.lens.Clockwork TRACE
898
+ # List the configured class loggers; the root logger level follows the table
899
+ midpoint-cli log ls
900
+ ```
901
+
902
+ `log` edits the `logging` section of the system configuration (OID
903
+ `00000000-0000-0000-0000-000000000001`), which Midpoint applies as soon as it is saved. The level is
904
+ one of `ALL`, `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG` and `TRACE`, in any case. Only the logging items
905
+ are sent, as a REST `PATCH`: the level of an existing class logger is replaced, a new logger is
906
+ added without appenders, so its messages go to the root logger's appenders. Setting the level a logger
907
+ already has sends nothing. `log ls` honours `-o` (`Logger`, `Level` and `Appenders` columns).
908
+ Use `log set` for a logger literally named `ls` or `set`.
909
+
910
+ ### Reports
911
+
912
+ ```bash
913
+ # List reports, then run one and wait for it
914
+ midpoint-cli report ls
915
+ midpoint-cli report run "Users in MidPoint"
916
+ ```
917
+
918
+ `report run` creates a report export task, like the Midpoint GUI. The server stores the output
919
+ as a report data object, which the GUI lists under Reports > Created reports.
920
+
921
+ ### Searching any object type
922
+
923
+ ```bash
924
+ # Disabled users, with a Midpoint Query Language filter evaluated by the server
925
+ midpoint-cli search user --filter 'activation/administrativeStatus = "disabled"'
926
+
927
+ # At most 10 roles whose name starts with App
928
+ midpoint-cli search role --filter 'name startsWith "App"' --limit 10
929
+
930
+ # Shadows of a resource, searched in the repository only (--raw)
931
+ midpoint-cli search shadow --raw --filter 'resourceRef matches (oid = "<resource OID>") and kind = "account"'
932
+ ```
933
+
934
+ `search` takes any object type that `get` takes. The filter is written in the Midpoint Query
935
+ Language (Axiom), which the REST search of Midpoint 4.4 and later accepts; a filter the server
936
+ cannot parse is reported as an error.
937
+
938
+ ### Audit Log
939
+
940
+ ```bash
941
+ # Latest audit events, then the history of one object
942
+ midpoint-cli audit ls --since 1h --limit 20
943
+ midpoint-cli audit object 00000000-0000-0000-0000-000000000002
944
+ # One event with its deltas, by the EventIdentifier column of audit ls
945
+ midpoint-cli audit get 1715251800000-0-1
946
+ ```
947
+
948
+ Midpoint has no REST endpoint for audit search, so `audit` (and the change stream shown by
949
+ `task run`) sends a small Groovy script to `rpc/executeScript`.
950
+
951
+ The `task run` change stream starts 60 seconds before the client's clock, or at the run start
952
+ reported by the server when that is later, so a client clock ahead of the server's does not
953
+ hide the first events. If the same task ran shortly before, the stream can therefore begin
954
+ with the last events of that earlier run.
955
+
956
+ The script uses Midpoint-internal classes, so the CLI reads the server version from
957
+ `actuator/info` and adapts the script to it. If a server release moves or changes those
958
+ classes, the CLI reports that the script could not be compiled or run on that server version.
959
+
960
+ #### Midpoint 4.11 and later
961
+
962
+ Midpoint 4.11 refuses Groovy by default, even for administrators, and the CLI then reports
963
+ which server check blocked it. To enable audit search:
964
+
965
+ 1. In `config.xml`, set `safeScriptingLanguagesOnly` to `false` and restart Midpoint. Skip this
966
+ step if your `config.xml` has no such setting.
967
+
968
+ ```xml
969
+ <expressions>
970
+ <safeScriptingLanguagesOnly>false</safeScriptingLanguagesOnly>
971
+ </expressions>
972
+ ```
973
+
974
+ 2. In the system configuration, add an expression profile that allows Groovy and use it for
975
+ privileged principals:
976
+
977
+ ```xml
978
+ <expressions>
979
+ <expressionProfile>
980
+ <identifier>privileged-groovy</identifier>
981
+ <decision>allow</decision>
982
+ </expressionProfile>
983
+ <defaults>
984
+ <privilegedPrincipal>privileged-groovy</privilegedPrincipal>
985
+ </defaults>
986
+ </expressions>
987
+ ```
988
+
989
+ This gives privileged principals the same unrestricted scripting they had before 4.11, so
990
+ weigh it against your security requirements.
991
+
992
+ ### Scripting and Automation
993
+
994
+ #### Batch operations with scripts
995
+
996
+ ```bash
997
+ #!/bin/bash
998
+ # Script to backup all users
999
+
1000
+ MIDPOINT_URL="https://midpoint.example.com/midpoint/"
1001
+ MIDPOINT_USERNAME="administrator"
1002
+ MIDPOINT_PASSWORD="mypassword"
1003
+
1004
+ export MIDPOINT_URL MIDPOINT_USERNAME MIDPOINT_PASSWORD
1005
+
1006
+ # Create backup directory
1007
+ mkdir -p user-backups
1008
+
1009
+ # List users as TSV (OID and Name are the first two columns), skip the header, back up each one
1010
+ midpoint-cli -o tsv users | tail -n +2 | while IFS=$'\t' read -r OID NAME _; do
1011
+ echo "Backing up user: $NAME ($OID)"
1012
+ midpoint-cli get user "$OID" > "user-backups/${NAME}.xml"
1013
+ done
1014
+
1015
+ echo "Backup completed!"
1016
+ ```
1017
+
1018
+ #### Automated user provisioning
1019
+
1020
+ ```bash
1021
+ #!/bin/bash
1022
+ # Create users from a list
1023
+
1024
+ MIDPOINT_CLI="midpoint-cli -u admin -p pass -U https://localhost:8080/midpoint/"
1025
+
1026
+ # Read user list and create each user
1027
+ while IFS=',' read -r username fullname email; do
1028
+ cat > /tmp/new-user.xml <<EOF
1029
+ <?xml version="1.0" encoding="UTF-8"?>
1030
+ <user xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
1031
+ xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3">
1032
+ <name>$username</name>
1033
+ <fullName>$fullname</fullName>
1034
+ <emailAddress>$email</emailAddress>
1035
+ <credentials>
1036
+ <password>
1037
+ <value>
1038
+ <t:clearValue>ChangeMe123</t:clearValue>
1039
+ </value>
1040
+ </password>
1041
+ </credentials>
1042
+ </user>
1043
+ EOF
1044
+
1045
+ echo "Creating user: $username"
1046
+ $MIDPOINT_CLI put /tmp/new-user.xml
1047
+ done < users.csv
1048
+ ```
1049
+
1050
+ #### Task automation with environment variables
1051
+
1052
+ ```bash
1053
+ # Use environment variables for credentials (more secure)
1054
+ export MIDPOINT_URL="https://midpoint.example.com/midpoint/"
1055
+ export MIDPOINT_USERNAME="administrator"
1056
+ export MIDPOINT_PASSWORD="$(cat /secure/location/password.txt)"
1057
+
1058
+ # Run tasks without exposing credentials in command line
1059
+ midpoint-cli task run "Daily User Reconciliation"
1060
+ midpoint-cli task run "Nightly Cleanup Task"
1061
+
1062
+ # Check task status: names of the tasks whose execution status is running or runnable
1063
+ midpoint-cli -o tsv task ls --status running --status runnable | tail -n +2 | cut -f 2
1064
+ ```
1065
+
1066
+ #### Continuous monitoring script
1067
+
1068
+ ```bash
1069
+ #!/bin/bash
1070
+ # Monitor running tasks and send alerts
1071
+
1072
+ while true; do
1073
+ RUNNING_TASKS=$(midpoint-cli -o json task ls --status running --status runnable | jq length)
1074
+
1075
+ if [ "$RUNNING_TASKS" -gt 5 ]; then
1076
+ echo "WARNING: More than 5 tasks running simultaneously!"
1077
+ # Send alert (e.g., via email or Slack)
1078
+ fi
1079
+
1080
+ # Check for suspended tasks (OID and name of each)
1081
+ FAILED_TASKS=$(midpoint-cli -o json tasks | jq -r '.[] | select(."Execution Status" == "suspended") | "\(.OID) \(.Name)"')
1082
+ if [ -n "$FAILED_TASKS" ]; then
1083
+ echo "ALERT: Failed tasks detected:"
1084
+ echo "$FAILED_TASKS"
1085
+ fi
1086
+
1087
+ sleep 60 # Check every minute
1088
+ done
1089
+ ```
1090
+
1091
+ #### Running Python client scripts
1092
+
1093
+ `script run` executes a local Python file (or standard input with `-`) with two variables in
1094
+ scope: `client`, the authenticated `MidpointClient`, and `tc`, a `unittest.TestCase` for
1095
+ assertions. A failed assertion or an uncaught exception exits with status 1, and the script may
1096
+ call `sys.exit()` to choose its own exit code, which makes it convenient for end-to-end checks:
1097
+
1098
+ ```bash
1099
+ echo 'assert len(client.get_users()) > 0' | midpoint-cli script run -
1100
+ midpoint-cli script run checks/provisioning.py
1101
+ ```
1102
+
1103
+ Scripts can import the rest of the client API from `midpoint_cli.client`. Object types are the
1104
+ values of `MidpointObjectTypes` (for example `MidpointObjectTypes.USER.value`). To look one up from
1105
+ a string, use `MidpointObjectTypes.find_by_name` (lenient: `user`, `User`, `UserType`) or one of
1106
+ the exact lookups `find_by_tagname('user')`, `find_by_java_type('UserType')` and
1107
+ `find_by_endpoint('users')`. All of them raise `midpoint_cli.client.objects.MidpointTypeNotFound`
1108
+ when nothing matches:
1109
+
1110
+ ```bash
1111
+ echo "from midpoint_cli.client import MidpointObjectTypes
1112
+ print(client.get_xml(MidpointObjectTypes.find_by_name('role'), 'role-oid'))" | midpoint-cli script run -
1113
+ ```
1114
+
1115
+ Scripts run as-is, with full access to the server through the configured credentials. Only run
1116
+ scripts you trust, exactly as you would with any other program handed your administrator password.
1117
+
1118
+ ### Working with XML Definitions
1119
+
1120
+ #### Export configuration for version control
1121
+
1122
+ ```bash
1123
+ # Export all critical configurations
1124
+ mkdir -p midpoint-config
1125
+
1126
+ # Export resources (resources exits 1 when a resource is not up, hence the "|| true")
1127
+ { midpoint-cli -o tsv resources || true; } | tail -n +2 | while IFS=$'\t' read -r OID NAME _; do
1128
+ midpoint-cli get resource "$OID" > "midpoint-config/resource-${NAME}.xml"
1129
+ done
1130
+
1131
+ # Export roles
1132
+ midpoint-cli get role 00000000-0000-0000-0000-000000000004 > midpoint-config/superuser-role.xml
1133
+
1134
+ # Commit to version control
1135
+ git add midpoint-config/
1136
+ git commit -m "Backup Midpoint configuration"
1137
+ ```
1138
+
1139
+ #### Apply patches to objects
1140
+
1141
+ `put -p PATCH FILE...` applies a patch file to each XML file before uploading it. This keeps one
1142
+ exported definition and adapts it per environment, for example to swap host names and secrets
1143
+ between test and production. The patch only edits the text sent to the server: the XML files
1144
+ on disk are not changed. With `-w`, the patched XML is also saved to `PATCH.xml` (mode 0600),
1145
+ which helps to check the result.
1146
+
1147
+ ```bash
1148
+ # Export a resource once
1149
+ midpoint-cli get resource 12345678-res1-1234-abcd-123456789012 ldap.xml
1150
+
1151
+ # Production values; quote the heredoc delimiter so the shell leaves backslashes alone
1152
+ cat > prod.patch <<'EOF'
1153
+ # Host names: escape the dots so they only match literally
1154
+ ldap-test\.example\.com => ldap.example.com
1155
+ # Replace the whole element content, whatever it was
1156
+ <baseContext>[^<]*</baseContext> => <baseContext>dc=example,dc=com</baseContext>
1157
+ # Password s3\cret: the backslash is doubled in the replacement
1158
+ CHANGEME => s3\\cret
1159
+ # A line without '=>' deletes every match
1160
+ <!-- DEBUG -->
1161
+ EOF
1162
+
1163
+ # Upload the patched resource, and keep a copy of what was sent in prod.patch.xml
1164
+ midpoint-cli put -p prod.patch -w ldap.xml
1165
+ ```
1166
+
1167
+ #### Patch file format
1168
+
1169
+ A patch file is a list of regular-expression substitutions, applied in order to the whole XML
1170
+ text (each line works on the result of the previous ones):
1171
+
1172
+ * Each line is `PATTERN => REPLACEMENT`. Every match of `PATTERN` is replaced, not only the
1173
+ first one. Whitespace around both sides is ignored.
1174
+ * Only the first ` =>` (a space followed by `=>`) splits the line, so a replacement may itself
1175
+ contain `=>`. A pattern cannot contain ` =>`; write it `[ ]=>` instead.
1176
+ * A line without ` =>` (or with nothing after it) is a deletion: every match of the pattern is
1177
+ removed.
1178
+ * Blank lines and lines starting with `#` are ignored.
1179
+ * `PATTERN` is a [Python regular expression](https://docs.python.org/3/library/re.html#regular-expression-syntax).
1180
+ Metacharacters keep their regex meaning: `.` matches any character, so `ldap.example.com`
1181
+ also matches `ldapXexample.com`. Escape `. ^ $ * + ? { } [ ] \ | ( )` with a backslash to
1182
+ match them literally (`ldap\.example\.com`). `.` does not match a line break, so `<!--.*`
1183
+ removes a comment opening up to the end of its line.
1184
+ * `REPLACEMENT` is a Python `re.sub` template: `\1`, `\2`, ... insert the groups captured by
1185
+ the pattern, so `<port>(\d+)</port> => <port>\1</port><ssl>false</ssl>` keeps the port. A
1186
+ literal backslash must be doubled: a password `s3\cret` is written `s3\\cret`.
1187
+ * A line that matches nothing prints a warning naming the line and leaves the XML unchanged;
1188
+ the upload goes ahead.
1189
+ * A line that is not a valid pattern or replacement (for example an unbalanced `(`, or a single
1190
+ backslash in the replacement such as `s3\cret`) stops `put` before that file is uploaded, and
1191
+ the files after it are skipped. The error names the file and the offending line, and the
1192
+ command exits with status 1.
1193
+
1194
+ ### Using Configuration Files
1195
+
1196
+ Create a configuration file for each environment and select one with `--config` or
1197
+ `MIDPOINT_CLI_CONFIG`; without either, only `~/.midpoint-cli.cfg` is read:
1198
+
1199
+ **~/.midpoint-cli.cfg** (Production):
1200
+ ```ini
1201
+ [Midpoint]
1202
+ url = https://midpoint.production.example.com/midpoint/
1203
+ username = automation-user
1204
+ password = secure-production-password
1205
+ ```
1206
+
1207
+ **./midpoint-cli.cfg** (Development - used only when named explicitly, it replaces the home directory config):
1208
+ ```ini
1209
+ [Midpoint]
1210
+ url = https://localhost:8080/midpoint/
1211
+ username = administrator
1212
+ password = 5ecr3t
1213
+ ```
1214
+
1215
+ Then simply run commands without authentication parameters:
1216
+
1217
+ ```bash
1218
+ # Uses configuration from ~/.midpoint-cli.cfg
1219
+ midpoint-cli users
1220
+ midpoint-cli tasks
1221
+ midpoint-cli resource test "AD Resource"
1222
+
1223
+ # Uses the development configuration instead
1224
+ midpoint-cli --config midpoint-cli.cfg users
1225
+ export MIDPOINT_CLI_CONFIG=./midpoint-cli.cfg
1226
+ midpoint-cli tasks
1227
+ ```
1228
+
1229
+ ## Requirements
1230
+
1231
+ This program is compatible with Python version 3.11 or above.
1232
+
1233
+ ## Installation
1234
+
1235
+ ### Through PyPI
1236
+
1237
+ The most common way to install midpoint-cli on your own computer is to use the PyPI repository:
1238
+
1239
+ ```bash
1240
+ pip3 install midpoint-cli
1241
+ ```
1242
+
1243
+ The installation will automatically install all required dependencies including:
1244
+ - `requests` and `urllib3` for HTTP communication with the Midpoint REST API
1245
+ - `rich` for tables, colors and progress display
1246
+ - `defusedxml` for safe parsing of XML returned by the server
1247
+ - `prompt-toolkit` for the interactive prompt, history and tab completion
1248
+ - `pygments` for XML syntax highlighting
1249
+ - `unidecode` for accent-insensitive searching
1250
+
1251
+ ### Standalone Linux binary
1252
+
1253
+ Each release also ships a single-file binary, `midpoint-cli-linux-amd64`, that needs no Python
1254
+ installation. Download it from the assets of the
1255
+ [release page](https://gitlab.com/alcibiade/midpoint-cli/-/releases), or directly by tag:
1256
+
1257
+ ```bash
1258
+ TAG=1.6.0 # the release tag
1259
+ curl -fLo midpoint-cli "https://gitlab.com/api/v4/projects/alcibiade%2Fmidpoint-cli/packages/generic/midpoint-cli/${TAG}/midpoint-cli-linux-amd64"
1260
+ chmod +x midpoint-cli
1261
+ ./midpoint-cli --version
1262
+ ```
1263
+
1264
+ The binary is built on AlmaLinux 8 and runs on x86_64 Linux distributions with glibc 2.28 or
1265
+ later: RHEL, Rocky and AlmaLinux 8+, Debian 10+, Ubuntu 20.04+, Amazon Linux 2023, openSUSE Leap
1266
+ 15.6 and current Fedora. It does not run on older glibc (Amazon Linux 2, CentOS 7) or on musl
1267
+ distributions such as Alpine; use `pip3 install midpoint-cli` there.
1268
+
1269
+ Binaries are attached to releases after 1.5.0.
1270
+
1271
+ ### Development build
1272
+
1273
+ Dependency management, build and test is managed using Python Poetry.
1274
+
1275
+ To install Poetry, please refer to [the official Python Poetry website](https://python-poetry.org/).
1276
+
1277
+ To install the current development version from GIT:
1278
+
1279
+ ```bash
1280
+ git clone https://gitlab.com/alcibiade/midpoint-cli.git
1281
+ cd midpoint-cli
1282
+ poetry install
1283
+ poetry run midpoint-cli --version
1284
+ ```
1285
+
1286
+ `poetry.lock` is committed so that every checkout and CI run installs the same dependency
1287
+ versions. After changing a dependency in `pyproject.toml`, run `poetry lock` and commit the
1288
+ updated lock file.
1289
+
1290
+ ### Anaconda
1291
+
1292
+ Anaconda packages are not available yet.
1293
+
1294
+ ## Setting up a sandbox environment
1295
+
1296
+ If you wish to test this project locally and don’t have a midpoint server available, you can use the
1297
+ following instructions.
1298
+
1299
+ ### Using the Evolveum managed Docker image
1300
+
1301
+ Pull the image locally:
1302
+
1303
+ ```bash
1304
+ yk@lunar:~$ docker pull evolveum/midpoint
1305
+ Using default tag: latest
1306
+ latest: Pulling from evolveum/midpoint
1307
+
1308
+ [...]
1309
+
1310
+ Digest: sha256:1e29b7e891d17bf7b1cf1853c84609e414c3a71d5c420aa38927200b2bdecc8e
1311
+ Status: Downloaded newer image for evolveum/midpoint:latest
1312
+ docker.io/evolveum/midpoint:latest
1313
+
1314
+
1315
+ ```
1316
+
1317
+ Then run the server and bind the port 8080:
1318
+
1319
+ ```bash
1320
+ yk@lunar:~$ docker run -d --name midpoint-1 -p8080:8080 evolveum/midpoint
1321
+ c048d519395ca48c8e94e361a2239b1c35c5e5305a29600895056e030d6a576f
1322
+
1323
+ yk@lunar:~$ midpoint-cli
1324
+ Welcome to Midpoint client ! Type ? for a list of commands
1325
+ midpoint> users
1326
+ OID Name Title FullName Status EmpNo Email OU
1327
+ ------------------------------------ ------------- ------- ---------------------- -------- ------- ------- ----
1328
+ 00000000-0000-0000-0000-000000000002 administrator midPoint Administrator enabled
1329
+ midpoint>
1330
+
1331
+ yk@lunar:~$ docker stop midpoint-1
1332
+ midpoint-1
1333
+ ```
1334
+