ligoj-cli 1.0.0__py3-none-any.whl
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.
- ligoj_cli-1.0.0.dist-info/METADATA +2350 -0
- ligoj_cli-1.0.0.dist-info/RECORD +20 -0
- ligoj_cli-1.0.0.dist-info/WHEEL +5 -0
- ligoj_cli-1.0.0.dist-info/entry_points.txt +2 -0
- ligoj_cli-1.0.0.dist-info/licenses/LICENSE +21 -0
- ligoj_cli-1.0.0.dist-info/top_level.txt +1 -0
- ligojcli/__init__.py +0 -0
- ligojcli/ligoj.py +126 -0
- ligojcli/plugins/__init__.py +3 -0
- ligojcli/plugins/alfresco.py +246 -0
- ligojcli/plugins/argocd.py +205 -0
- ligojcli/plugins/bootstrap.py +672 -0
- ligojcli/plugins/gitlab.py +221 -0
- ligojcli/plugins/harbor.py +170 -0
- ligojcli/plugins/jenkins.py +606 -0
- ligojcli/plugins/ligoj.py +1665 -0
- ligojcli/plugins/nexus.py +245 -0
- ligojcli/plugins/sonarqube.py +295 -0
- ligojcli/plugins/ssl.py +143 -0
- ligojcli/plugins/utils.py +401 -0
|
@@ -0,0 +1,2350 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ligoj-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Ligoj CLI
|
|
5
|
+
Author-email: Fabrice Daugan <fdaugan@kloudy.io>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ligoj/cli
|
|
8
|
+
Project-URL: Documentation, https://github.com/ligoj/cli/README.md
|
|
9
|
+
Project-URL: Repository, https://github.com/ligoj/cli
|
|
10
|
+
Project-URL: Issues, https://github.com/ligoj/cli/issues
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: colorama==0.4.6
|
|
21
|
+
Requires-Dist: requests==2.32.4
|
|
22
|
+
Requires-Dist: dnspython==2.7.0
|
|
23
|
+
Requires-Dist: pyyaml==6.0.2
|
|
24
|
+
Requires-Dist: configparser==7.2.0
|
|
25
|
+
Requires-Dist: unidecode==1.4.0
|
|
26
|
+
Requires-Dist: jsonschema===4.25.0
|
|
27
|
+
Requires-Dist: jsonmerge==1.9.2
|
|
28
|
+
Requires-Dist: Jinja2==3.1.6
|
|
29
|
+
Requires-Dist: pytimeparse==1.1.8
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
[[_TOC_]]
|
|
33
|
+
|
|
34
|
+
# Description
|
|
35
|
+
|
|
36
|
+
Ligoj CLI makes REST calls to a remote Ligoj instance, with parameters and error handling.
|
|
37
|
+
|
|
38
|
+
# Requirements
|
|
39
|
+
|
|
40
|
+
- Python 3.11+
|
|
41
|
+
- Connectivity and API keys to target endpoints `Ligoj`, `Nexus`, `Jenkins`, `SonarQube`
|
|
42
|
+
- `pip`
|
|
43
|
+
- Valid [credentials](#credentials)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Configuration
|
|
47
|
+
|
|
48
|
+
## Credentials
|
|
49
|
+
|
|
50
|
+
Ligoj credentials are based on user/password or user/API Key.
|
|
51
|
+
|
|
52
|
+
Populate the [configuration files](#configuration-files) with the API key created here [#/api/token ("?" > "Api" > "Token")](http://localhost:8080/ligoj/#/api/token)
|
|
53
|
+
|
|
54
|
+
You can also:
|
|
55
|
+
- use the [session login](#login-with-password) command to get a temporary session
|
|
56
|
+
- use the [token](#token) command to create durable API keys
|
|
57
|
+
|
|
58
|
+
For standard actions, only `LIGOJ_ENDPOINT` is required and can be set either in the [configuration files](#configuration-files), as an environment variable, or as a CLI option.
|
|
59
|
+
|
|
60
|
+
For `bootstrap` actions, more endpoints and credentials may be required in the [configuration files](#configuration-files).
|
|
61
|
+
|
|
62
|
+
Sample usage:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ligoj \
|
|
66
|
+
--api-user="ligoj-admin" \
|
|
67
|
+
--api-key="..." \
|
|
68
|
+
--endpoint="http://localhost:8080/ligoj" \
|
|
69
|
+
--version
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
# Commands
|
|
73
|
+
|
|
74
|
+
## Settings
|
|
75
|
+
|
|
76
|
+
Options are sourced in the following order of priority, from highest to lowest:
|
|
77
|
+
|
|
78
|
+
1. Command line options – Overrides settings in any other location, such as the `--output` and `--profile` parameters.
|
|
79
|
+
2. Environment variables – You can store values in your system's environment variables.
|
|
80
|
+
3. Session file – `default` section or given profile name. The session file is located at `~/.ligoj/sessions` on Linux or macOS and holds:
|
|
81
|
+
- Session cookies set with the [`login`](#login-with-password) command.
|
|
82
|
+
- API keys set with the [`login`](#login-with-api-key) command.
|
|
83
|
+
4. Credentials file – `default` section or given profile name. The credentials file is located at `~/.ligoj/credentials` on Linux or macOS.
|
|
84
|
+
5. Configuration file – `default` section or given profile name. The config file is located at `~/.ligoj/config` on Linux or macOS. Alternative file `~/.ligoj/cli-config` is supported.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### Configuration files
|
|
88
|
+
|
|
89
|
+
Sections in these `.ini` files correspond to profile names. The default profile name is `default` and is used when no `--profile` option and no `LIGOJ_PROFILE` are provided.
|
|
90
|
+
|
|
91
|
+
In the file `~/.ligoj/config`, default configurations can be specified. No secrets are sourced from this file.
|
|
92
|
+
|
|
93
|
+
```ini
|
|
94
|
+
[default]
|
|
95
|
+
output = "json"
|
|
96
|
+
log_level = "DEBUG"
|
|
97
|
+
endpoint=http://localhost:8080/ligoj
|
|
98
|
+
jenkins_endpoint=http://localhost:8086
|
|
99
|
+
sonar_endpoint=http://localhost:9000/
|
|
100
|
+
|
|
101
|
+
[some]
|
|
102
|
+
output = "json"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Read-only secrets are stored in the `~/.ligoj/credentials` file.
|
|
106
|
+
|
|
107
|
+
Temporary secrets (stored from the [`session`](#session) command) are stored in the `~/.ligoj/sessions` file.
|
|
108
|
+
|
|
109
|
+
While `~/.ligoj/credentials` can contain configuration settings, secrets are only sourced from the `~/.ligoj/credentials` and `~/.ligoj/sessions` files.
|
|
110
|
+
|
|
111
|
+
Sample credential file:
|
|
112
|
+
```ini
|
|
113
|
+
[default]
|
|
114
|
+
api_user = ligoj-user1
|
|
115
|
+
api_key = secret
|
|
116
|
+
jenkins_api_user = admin
|
|
117
|
+
jenkins_api_token = secret
|
|
118
|
+
sonar_api_token = secret
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
*Note* Leading spaces are ignored, and enclosing `'` and `"` are removed. Empty strings are ignored.
|
|
122
|
+
|
|
123
|
+
## Generic options
|
|
124
|
+
|
|
125
|
+
The generic options are available to all actions.
|
|
126
|
+
|
|
127
|
+
### Output mode
|
|
128
|
+
|
|
129
|
+
Determines the output mode of the command. Use the `--output` option. The following modes are available:
|
|
130
|
+
|
|
131
|
+
- `json` : JSON format
|
|
132
|
+
- `text` : Text format
|
|
133
|
+
|
|
134
|
+
This option can also be specified in [configuration files](#configuration-files) as `output` or in environment variable `LIGOJ_OUTPUT`
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
ligoj --output json --version
|
|
138
|
+
ligoj --version
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{"version": "3.3.1-SNAPSHOT"}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
ligoj --output text --version
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```txt
|
|
150
|
+
3.3.1-SNAPSHOT
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Log level
|
|
154
|
+
|
|
155
|
+
To configure the verbosity, use the `--log-level` option. The following levels are available:
|
|
156
|
+
|
|
157
|
+
- `TRACE` level displays the in/out data. `--verbose` and `--trace` are shortcuts for this level.
|
|
158
|
+
- `DEBUG` level displays the internal API calls `--debug` is a shortcut for this level.
|
|
159
|
+
- `INFO` level displays the actions
|
|
160
|
+
- `WARN` level displays the unexpected behaviors
|
|
161
|
+
- `ERROR` level displays only fatal errors
|
|
162
|
+
|
|
163
|
+
This option can also be specified in [configuration files](#configuration-files) as `log-level` or in environment variable `LIGOJ_LOG_LEVEL`
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
ligoj --log-level INFO ....
|
|
167
|
+
ligoj --verbose ....
|
|
168
|
+
ligoj --trace ....
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
If you want to pipe JSON result to `jq`, use `--output json` and `--log-level ERROR` options.
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
### Insecure server connections
|
|
175
|
+
|
|
176
|
+
To allow insecure server connections when using SSL, use the `--insecure` option. This option can also be specified in [configuration files](#configuration-files) as `insecure` or in environment variable `LIGOJ_INSECURE`
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
ligoj --insecure ....
|
|
180
|
+
ligoj --k ....
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### API user
|
|
184
|
+
|
|
185
|
+
Ligoj API user name. Use the `--api-user` option. This option can also be specified in [configuration files](#configuration-files) as `api-user` or in environment variable `LIGOJ_API_USER`. By default is `ligoj-admin`.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
ligoj --api-user ligoj-admin ....
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### API key
|
|
192
|
+
|
|
193
|
+
Provide an API key, which can be created here [#/api/token ("?" > "Api" > "Token")](https://localhost:8080/ligoj/#/api/token). Use the `--api-key` option. This option can also be specified in [configuration files](#configuration-files) as `api-key` or in environment variable `LIGOJ_API_KEY`
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
ligoj --api-key secret ....
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
### API run as user
|
|
201
|
+
|
|
202
|
+
Ligoj API user name for impersonation. Use the `--api-run-as-user` option. This option can also be specified in [configuration files](#configuration-files) as `api-run-as-user` or in environment variable `LIGOJ_API_RUN_AS_USER`.
|
|
203
|
+
|
|
204
|
+
Constraints are:
|
|
205
|
+
- After the authentication succeeds with [--api-key](#api-key) and [--api-user](#api-user)
|
|
206
|
+
- The current user must have `POST /system.user` authorization
|
|
207
|
+
- `--api-run-as-user` must exist
|
|
208
|
+
- The actions are executed in the name of `--api-run-as-user` and without needing the related credentials.
|
|
209
|
+
|
|
210
|
+
This option can also be specified in [configuration files](#configuration-files) as `api-run-as-user` or in environment variable `LIGOJ_API_RUN_AS_USER`.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
ligoj --api-run-as-user ligoj-user ....
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
### API local roles
|
|
218
|
+
|
|
219
|
+
Restrict the computed roles to the local roles of the authenticated user. No plugin roles are involved.
|
|
220
|
+
This flag makes the authentication independent of the configured plugins (e.g., availability, misconfiguration, etc.).
|
|
221
|
+
|
|
222
|
+
Since this flag reduces the set of available roles, there is no restriction on the usage.
|
|
223
|
+
|
|
224
|
+
This option can also be specified in [configuration files](#configuration-files) as `api-local-roles` or in environment variable `LIGOJ_API_LOCAL_ROLES`.
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
ligoj --api-local-roles session get
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
### Profile
|
|
232
|
+
|
|
233
|
+
Ligoj profile name to read from [configuration files](#configuration-files), `credentials`, `config`, and `sessions`. Use the `--profile` option. This option can also be specified with environment variable `LIGOJ_PROFILE`. The default is `default`.
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
ligoj --profile some ....
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### From
|
|
240
|
+
|
|
241
|
+
JSON content to load. Use the `--from` option. The following forms are available:
|
|
242
|
+
|
|
243
|
+
- Path to a local JSON file
|
|
244
|
+
- Remote HTTP URL
|
|
245
|
+
- Inline JSON string
|
|
246
|
+
|
|
247
|
+
After the content has been retrieved, it is interpolated with [Jinja](https://pypi.org/project/Jinja2/) with current project (`project`) and environment variables (`env`) as context:
|
|
248
|
+
- For example:
|
|
249
|
+
- `{{ project.id }}` is replaced by the project identifier.
|
|
250
|
+
- `{{ env.ENV_VAR }}` is replaced by the `ENV_VAR` environment variable value.
|
|
251
|
+
- `$${_not_existing_property_in_context_}` is replaced by an empty string.
|
|
252
|
+
- `null` values are considered as empty string
|
|
253
|
+
- The context depends on the current action. Usually, all given parameters are added to the context.
|
|
254
|
+
- The context is completed with environment variables.
|
|
255
|
+
- Surrounding spaces inside `{{..}}` are ignored
|
|
256
|
+
|
|
257
|
+
### No color
|
|
258
|
+
|
|
259
|
+
Disable colors in messages. Use the `--no-color` option. This option can also be specified in [configuration files](#configuration-files) as `no-color` or in environment variable `LIGOJ_NO_COLOR`
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
ligoj --no-color ....
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Fail on hook error
|
|
266
|
+
|
|
267
|
+
Fail (exit code 1) when any hook returns a failure status (`X-Ligoj-Hook-*=FAILED`). See [hooks](https://github.com/ligoj/ligoj/blob/master/DOC.md#hook) for more details. Use the `--fail-on-hook-error` option. This option can also be specified in [configuration files](#configuration-files) as `fail-on-hook-error` or in environment variable `LIGOJ_FAIL_ON_HOOK_ERROR`
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
ligoj --fail-on-hook-error ....
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Fail (exit code 1) when any hook returns a failure status (`X-Ligoj-Hook-*=FAILED`). See [hooks](https://github.com/ligoj/ligoj/blob/master/DOC.md#hook) for more details.
|
|
274
|
+
|
|
275
|
+
Hooks status and message are displayed with `DEBUG` log level:
|
|
276
|
+
```log
|
|
277
|
+
[DEBUG] [ligoj] Hook 'audit_role_change' status: SUCCEED
|
|
278
|
+
[DEBUG] [ligoj] Hook 'audit_role_change' status: FAILED: Message for user
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Session
|
|
282
|
+
|
|
283
|
+
Session operations with credentials and profile management.
|
|
284
|
+
|
|
285
|
+
### Login with password
|
|
286
|
+
|
|
287
|
+
Verify the provided user and password and save the returned session cookie into the `~/.ligoj/sessions` file for further API call without providing credentials.
|
|
288
|
+
|
|
289
|
+
*Note* Secrets like `api-user` and `password` are sourced from the CLI options, sessions and credential files, not from the configuration one.
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
ligoj --api-user "ligoj-admin" --profile default session login --password secret
|
|
294
|
+
ligoj --api-user "ligoj-admin" login session --password secret
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Completed `~/.ligoj/sessions` file:
|
|
298
|
+
|
|
299
|
+
```ini
|
|
300
|
+
[default]
|
|
301
|
+
session = session_secret_value.node0
|
|
302
|
+
api_user = ligoj-admin
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Login with api key
|
|
306
|
+
|
|
307
|
+
Verify the provided user and API key and save the provided API user and API keys into the `~/.ligoj/sessions` file for further API call without providing credentials.
|
|
308
|
+
|
|
309
|
+
*Note* Secrets like `api-user` and `password` are sourced from the CLI options, sessions and credential files, not from the configuration one.
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
ligoj --api-user "ligoj-admin" --api-key "__api_key__" session login
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Get session
|
|
316
|
+
|
|
317
|
+
Return user session details
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
ligoj session get
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"applicationSettings": {
|
|
326
|
+
"buildNumber": "", "buildTimestamp": "", "buildVersion": "3.3.1-SNAPSHOT",
|
|
327
|
+
"digestVersion": "rRXmeWPgn+...==",
|
|
328
|
+
"plugins": ["feature:welcome:data-rbac"]
|
|
329
|
+
},
|
|
330
|
+
"userSettings": {"restricted-hash--": "#/home/project/1/subscription/1002", "security-agreement": "1"},
|
|
331
|
+
"uiAuthorizations": ["^id/container/group.*", "^id/user.*", "^id/delegate.*", "^message.*", "^id$", "^home.*", "^id/container/company.*", "^api.*", "^id/home.*", ".*"],
|
|
332
|
+
"apiAuthorizations": [{"pattern": ".*", "method": "DELETE"}], "roles": ["ADMIN", "USER"], "userName": "ligoj-admin"
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### whoami
|
|
337
|
+
|
|
338
|
+
Return user identifier
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
ligoj session whoami
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{"id": "ligoj-admin"}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
## System User
|
|
350
|
+
|
|
351
|
+
A system user can live without federated identity. After a successful login, a federated user can be managed with system roles and API keys.
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
### Create a system user
|
|
355
|
+
|
|
356
|
+
Create a new system user with role names or identifiers.
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
ligoj user upsert --id ligoj-admin@sample.com --roles USER ADMIN
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Optionally, at this time, an API key is generated but only once and only from administrator users.
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
ligoj user upsert --id ligoj-admin@sample.com --roles USER ADMIN --api_key_name cli
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Output the API key only if not existing.
|
|
369
|
+
|
|
370
|
+
```json
|
|
371
|
+
{"id": "__api_key__", "name": "cli"}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
*Note* When role names are provided API calls are executed to retrieve their identifiers.
|
|
375
|
+
|
|
376
|
+
### Delete a system user
|
|
377
|
+
|
|
378
|
+
Delete a system user. The command will not fail if the user is not found.
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
ligoj user delete --id ligoj-user
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
### List system users
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
ligoj user list
|
|
389
|
+
ligoj user list --with-roles
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
```json
|
|
393
|
+
{"recordsTotal": 3, "recordsFiltered": 3, "data": ["ligoj-admin", "ligoj-admin@sample.com", "ligoj-user"]}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
*Note* When role names are provided API calls are executed to retrieve their identifiers.
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
### Delete a system user
|
|
400
|
+
|
|
401
|
+
Create a new system user with role names or identifiers.
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
ligoj user delete --id ligoj-user
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
## System Role
|
|
409
|
+
|
|
410
|
+
A system role holds the permissions (ui and api), and can be assigned to users or groups.
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
### Create a system role
|
|
414
|
+
|
|
415
|
+
Create or update a system role.
|
|
416
|
+
|
|
417
|
+
**Note** Whereas Ligoj supports per HTTP method authorizations, this feature is not yet available from this CLI action.
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
# Deprecated `--id` option
|
|
421
|
+
ligoj role create --id ADMIN --api ".*" --ui ".*"
|
|
422
|
+
ligoj role create --name ADMIN --api ".*" --ui ".*"
|
|
423
|
+
ligoj role create --name SELF_TOKEN_RENEW --api "/api/token.*" --ui "/sys/token"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Output is the created/existing role identifier.
|
|
427
|
+
```json
|
|
428
|
+
123
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Delete a system role
|
|
432
|
+
|
|
433
|
+
Delete a system role. The command will not fail if the role does not exist.
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
ligoj role delete --id 1
|
|
437
|
+
ligoj role delete --name ADMIN
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### List system roles
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
ligoj role list
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Get a system role
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
ligoj role get --id 1
|
|
450
|
+
ligoj role get --name ADMIN
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
```json
|
|
454
|
+
{"id": 1, "createdBy": "_system", "createdDate": 1758279349911, "lastModifiedBy": "_system", "lastModifiedDate": 1758279349911, "name": "ADMIN"}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Info
|
|
458
|
+
|
|
459
|
+
### Status
|
|
460
|
+
|
|
461
|
+
Return API server status
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
ligoj info status
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
```json
|
|
468
|
+
{"status": "UP"}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Optionally, a wait for status can be defined. A regular poll to the server [status](#status) is performed until reaching `DOWN` or `UP` status.
|
|
472
|
+
When different from `0`, the final status is returned.
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
ligoj info status --wait 20
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
```json
|
|
479
|
+
{"status": "DOWN"}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Version
|
|
483
|
+
|
|
484
|
+
Return API server version
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
ligoj info version
|
|
488
|
+
ligoj --version
|
|
489
|
+
ligoj -v
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
```json
|
|
493
|
+
{"version": "3.3.1-SNAPSHOT"}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
### API Specification
|
|
498
|
+
|
|
499
|
+
All Ligoj APIs are accessible with REST verbs.
|
|
500
|
+
|
|
501
|
+
Currently 3 specification formats are available:
|
|
502
|
+
- Swagger : Web UI based on OpenAPI JSON file
|
|
503
|
+
- OpenAPI JSON file
|
|
504
|
+
- [WADL](https://www.w3.org/submissions/wadl/)
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
ligoj info api --output openapi --print content
|
|
508
|
+
ligoj info api
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
```json
|
|
512
|
+
{
|
|
513
|
+
"openapi" : "3.0.1",
|
|
514
|
+
"info" : {
|
|
515
|
+
"title" : "Ligoj API application",
|
|
516
|
+
"description" : "REST API services of application. Includes the core services and the features of actually loaded plugins",
|
|
517
|
+
"contact" : {
|
|
518
|
+
"name" : "The Ligoj team",
|
|
519
|
+
"url" : "https://github.com/ligoj"
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
ligoj info api --output wadl --print url
|
|
524
|
+
ligoj info api --output openapi --print url
|
|
525
|
+
ligoj info api --output swagger --print url
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
```text
|
|
529
|
+
http://localhost:8080/ligoj/rest?_wadl
|
|
530
|
+
http://localhost:8080/ligoj/rest/openapi.json
|
|
531
|
+
http://localhost:8080/ligoj/api-docs?url=openapi.json
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## Token
|
|
535
|
+
|
|
536
|
+
Manage API keys of current user.
|
|
537
|
+
|
|
538
|
+
### Create a token
|
|
539
|
+
|
|
540
|
+
For `expiration` option:
|
|
541
|
+
- Either a full ISO date, which corresponds to the furthest date the generated token can be trusted.
|
|
542
|
+
- Either a duration starting from now, in a standard duration format. See [pytimeparse](https://pypi.org/project/pytimeparse/)
|
|
543
|
+
|
|
544
|
+
Expired tokens are neither listed nor returned even if they are not yet physically deleted.
|
|
545
|
+
|
|
546
|
+
```bash
|
|
547
|
+
ligoj token create --id cli_init
|
|
548
|
+
ligoj token create --id today_only --expiration 1d
|
|
549
|
+
ligoj token create --id SELF_TOKEN_RENEW --expiration 2029-12-31T23:59:59
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Optionally, the created token can be saved into the current profile, replacing any previously existing one:
|
|
553
|
+
|
|
554
|
+
Output:
|
|
555
|
+
|
|
556
|
+
```json
|
|
557
|
+
{"id": "__api_key__", "name": "cli_init"}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### List tokens
|
|
561
|
+
|
|
562
|
+
```bash
|
|
563
|
+
ligoj token list
|
|
564
|
+
|
|
565
|
+
["cli_init", "test"]
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Get a token value
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
ligoj token get --id cli_init
|
|
572
|
+
|
|
573
|
+
```json
|
|
574
|
+
{"value": "__api_key__"}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Delete a token value
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
ligoj token delete --id cli_init
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Version
|
|
584
|
+
|
|
585
|
+
Return API server version
|
|
586
|
+
|
|
587
|
+
```bash
|
|
588
|
+
ligoj info version
|
|
589
|
+
ligoj --version
|
|
590
|
+
ligoj -v
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
```json
|
|
594
|
+
{"version": "3.3.1-SNAPSHOT"}
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
## Configuration
|
|
599
|
+
|
|
600
|
+
Configure global values
|
|
601
|
+
|
|
602
|
+
### Set value
|
|
603
|
+
|
|
604
|
+
```bash
|
|
605
|
+
ligoj configuration set --id "foo" --value "bar"
|
|
606
|
+
ligoj configuration set --id "plugins.repository-manager.nexus.search.url" --value "https://localhost/?g:org.ligoj.plugin"
|
|
607
|
+
ligoj configuration set --id "plugins.repository-manager.nexus.search.proxy.host" --value "my-proxy.local"
|
|
608
|
+
ligoj configuration set --id "plugins.repository-manager.nexus.search.proxy.port" --value "8080"
|
|
609
|
+
ligoj configuration set --id "plugins.repository-manager.nexus.artifact.url" --value "https://nexus.localhost:8443/repository/maven_corporate/org/ligoj/plugin/"
|
|
610
|
+
ligoj configuration set --id "cache.id-ldap-data.ttl" --value "3600"
|
|
611
|
+
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
*Note* When you change a configuration related to plugin management, invalidate the related caches to retrieve the up-to-date plugin versions.
|
|
616
|
+
|
|
617
|
+
### Get value
|
|
618
|
+
|
|
619
|
+
Return the configuration value from its `id`, which can be a Java property name or a stored value in the `S_CONFIGURATION` table.
|
|
620
|
+
|
|
621
|
+
Return a specific value. Encrypted values are returned as decrypted.
|
|
622
|
+
|
|
623
|
+
```bash
|
|
624
|
+
ligoj configuration get --id "foo"
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
```json
|
|
628
|
+
{"value": "bar"}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
Return all values. Encrypted values are not returned.
|
|
632
|
+
|
|
633
|
+
```bash
|
|
634
|
+
ligoj configuration get
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
```json
|
|
638
|
+
[{"name": "COMMAND_MODE", "value": "unix2003", "persisted": false, "secured": false, "overridden": false, "source": "systemEnvironment"},...]
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Delete value
|
|
642
|
+
|
|
643
|
+
```bash
|
|
644
|
+
ligoj configuration delete --id "foo"
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
## Cache
|
|
648
|
+
|
|
649
|
+
### Invalidate cache
|
|
650
|
+
|
|
651
|
+
```bash
|
|
652
|
+
ligoj cache invalidate --id "node-parameters"
|
|
653
|
+
ligoj cache invalidate --id "nodes"
|
|
654
|
+
ligoj cache invalidate --id "iam-node-configuration"
|
|
655
|
+
ligoj cache invalidate --id "id-ldap-data"
|
|
656
|
+
ligoj cache invalidate --id "user-details"
|
|
657
|
+
ligoj cache invalidate --id "plugins-last-version-nexus"
|
|
658
|
+
ligoj cache invalidate
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Get cache details
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
ligoj cache get --id "user-details"
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
```json
|
|
668
|
+
{
|
|
669
|
+
"id": "user-details",
|
|
670
|
+
"size": 1,
|
|
671
|
+
"hitCount": 123,
|
|
672
|
+
"missCount": 14,
|
|
673
|
+
"hitPercentage": 89.78102,
|
|
674
|
+
"missPercentage": 10.218978,
|
|
675
|
+
"averageGetTime": 16.860365,
|
|
676
|
+
"node": {"id": "00000000-0000-0000-0000-000000000000", "address": "[127.0.0.1]:5701", "version": "5.3.2", "cluster": {"id": "00000000-0000-0000-0000-000000000001", "state": "ACTIVE", "members": [{"id": "00000000-0000-0000-0000-000000000000", "address": "[127.0.0.1]:5701", "version": "5.3.2"}]}}
|
|
677
|
+
}
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
ligoj cache list
|
|
682
|
+
```
|
|
683
|
+
```json
|
|
684
|
+
[
|
|
685
|
+
{"id": "terraform-version", "size": 0, "hitCount": 0, "missCount": 0, "hitPercentage": 0.0, "missPercentage": 0.0, "averageGetTime": 0.0, "node": {"id": "00000000-0000-0000-0000-000000000000", "address": "[127.0.0.1]:5701", "version": "5.3.2", "cluster": {"id": "00000000-0000-0000-0000-000000000001", "state": "ACTIVE", "members": [{"id": "00000000-0000-0000-0000-000000000000", "address": "[127.0.0.1]:5701", "version": "5.3.2"}]}}},
|
|
686
|
+
...
|
|
687
|
+
]
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
## File
|
|
691
|
+
|
|
692
|
+
A [file](https://github.com/ligoj/ligoj/blob/master/DOC.md#hook) is a remote file readable and/or writable by the API container.
|
|
693
|
+
|
|
694
|
+
Related path must be authorized by the configuration value `ligoj.file.path`. This check is performed at upload and download times.
|
|
695
|
+
|
|
696
|
+
```bash
|
|
697
|
+
ligoj configuration set --id "ligoj.file.path" --value "^/home/files/.*,^/home/hooks/.*,^/home/ligoj/META-INF/resources/webjars/.*,^/home/ligoj/statics/themes/.*"
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Create or update file
|
|
701
|
+
|
|
702
|
+
Upload a local file to a remote file.
|
|
703
|
+
|
|
704
|
+
```bash
|
|
705
|
+
ligoj file put --from https://path/to/icon.png --path "/home/ligoj/icon.png"
|
|
706
|
+
ligoj file put --from docs/ui/logo.png --path "/home/ligoj/META-INF/resources/webjars/home/img/logo.png"
|
|
707
|
+
ligoj file put --from docs/ui/bg1.jpg --path "/home/ligoj/statics/themes/bootstrap-material-design/img/bg1.jpg"
|
|
708
|
+
ligoj file put --from docs/ui/logo.png --path "/home/ligoj/statics/favicon.ico"
|
|
709
|
+
ligoj file put --from docs/ui/logo.png --path "/home/ligoj/statics/themes/bootstrap-material-design/ico/favicon.ico"
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### Delete file
|
|
713
|
+
|
|
714
|
+
```bash
|
|
715
|
+
ligoj file delete --path "/home/ligoj/icon.png"
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### Hook get
|
|
719
|
+
|
|
720
|
+
Download a remote file and save it to a local file.
|
|
721
|
+
|
|
722
|
+
```bash
|
|
723
|
+
ligoj file get --path "/home/ligoj/icon.png" --out "./icon2.png"
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
## Hook
|
|
727
|
+
|
|
728
|
+
A [hook](https://github.com/ligoj/ligoj/blob/master/DOC.md#hook) is a command uploaded by a user, and triggered by a successfully invoked API call of Ligoj.
|
|
729
|
+
|
|
730
|
+
When this command is executed, it receives a `PAYLOAD` event as environment variable.
|
|
731
|
+
|
|
732
|
+
Related command must be authorized by the configuration value `ligoj.hook.path`. This check is performed at creation and execution time:
|
|
733
|
+
|
|
734
|
+
```bash
|
|
735
|
+
ligoj configuration set --id "ligoj.hook.path" --value "^/home/ligoj/hooks/.*"
|
|
736
|
+
ligoj configuration set --id "ligoj.file.path" --value "^/home/ligoj/hooks/.*"
|
|
737
|
+
ligoj file put --from docs/sample_hook_ligoj_audit.sh --path "/home/ligoj/hooks/ligoj_audit.sh" --executable
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
Payload structure:
|
|
741
|
+
|
|
742
|
+
```json
|
|
743
|
+
{
|
|
744
|
+
"name":"audit_role_change",
|
|
745
|
+
"now":"2023-10-17T19:22:21Z",
|
|
746
|
+
"result":{"some_json":"some_value"},
|
|
747
|
+
"path":"system/security/role",
|
|
748
|
+
"api":"RoleResource#update",
|
|
749
|
+
"params":[{"id":2652, "name":"ADMIN_PROJECT1A"}, {}],
|
|
750
|
+
"method":"PUT",
|
|
751
|
+
"user":"ligoj-admin",
|
|
752
|
+
"timeout":30,
|
|
753
|
+
"inject": {"secret1":"value1","secret2":"value2"}
|
|
754
|
+
}'
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
### Create hook
|
|
758
|
+
|
|
759
|
+
```bash
|
|
760
|
+
# Asynchronous hook
|
|
761
|
+
ligoj hook upsert --name "audit_role_change" --command "/home/ligoj/hooks/ligoj_audit.sh" --directory /var/log --timeout 10 --match '{"path":"system/security/role.*"}' --inject secret1 secret2
|
|
762
|
+
|
|
763
|
+
# Synchronous hook
|
|
764
|
+
ligoj hook upsert --name "audit_role_change" --command "/home/ligoj/hooks/ligoj_audit.sh" --directory /var/log --timeout 10 --match '{"path":"system/security/role.*", "method":"POST"}' --inject secret1 secret2 --delay 0
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
**Note**
|
|
768
|
+
- For Docker image runtime, this program is executed by the container `ligoj-api`, and must be resolvable. Either this program is already packaged in the container, or it is mounted as a Docker volume to the host. Usually the mounted volume is `/home/ligoj` and points to the host path such as `/var/path/to/ligoj`. In the above hook sample, the user-level script would be `/var/path/to/ligoj/ligoj_audit.sh`.
|
|
769
|
+
- `--name` The human readable hook name. Is displayed in logs and HTTP headers of synchronous executions.
|
|
770
|
+
- `--command` The command to execute. Must be allowed by `ligoj.hook.path` configuration. This condition is checked at creation and execution time.
|
|
771
|
+
- `--directory` The working directory where the hook is executed.
|
|
772
|
+
- `--inject` Can relate to any configuration names supported by the [configuration get](#configuration) command and will be provided in the payload variable.
|
|
773
|
+
- `--match` Must be a valid JSON stringified object having :
|
|
774
|
+
* at least the `path` property relating to a valid regular expression matching to one of the available Ligoj's endpoint.
|
|
775
|
+
* an optional `method` property corresponding to ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"].
|
|
776
|
+
- `--delay` The delay in seconds before the hook is executed. Default to `1`. Use `0` for synchronous hooks.
|
|
777
|
+
- `--timeout` The timeout in seconds before the hook is executed. Default to `10`.
|
|
778
|
+
|
|
779
|
+
Sample executable hook script `/home/ligoj/ligoj_audit.sh`:
|
|
780
|
+
|
|
781
|
+
```bash
|
|
782
|
+
#!/bin/bash
|
|
783
|
+
payload="$(echo "$PAYLOAD" | base64 -d)"
|
|
784
|
+
echo "$(echo "$payload"|jq -r '.now') $(echo "$payload"|jq -r '.method') $(echo "$payload"|jq -r '.path') [$(echo "$payload"|jq -r '.user')]" >> ligoj_audit.log
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
For Docker runtime, to verify this hook would run as expected, try the following command from the host:
|
|
788
|
+
|
|
789
|
+
```bash
|
|
790
|
+
docker exec ligoj-api jq --version
|
|
791
|
+
# > jq-1.6
|
|
792
|
+
docker exec ligoj-api python3 --version
|
|
793
|
+
# > Python 3.11.5
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Update hook
|
|
797
|
+
|
|
798
|
+
For update, `id` or `name` can be used. However, if `name` needs to be updated, provide the `id` as well.
|
|
799
|
+
|
|
800
|
+
```bash
|
|
801
|
+
ligoj hook upsert --id 4 --name "audit_role_change_new" --command "$(pwd)/docs/sample_hook_ligoj_audit.sh" --directory /var/log --match '{"path":"system/security/role.*"}' --inject "feature:iam:node:primary" "my-secret"
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
### Delete hook
|
|
805
|
+
|
|
806
|
+
Deletion can be done by `id` or `name` attribute:
|
|
807
|
+
|
|
808
|
+
```bash
|
|
809
|
+
ligoj hook delete --id 2
|
|
810
|
+
ligoj hook delete --name "audit_role_change"
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
### Hook get
|
|
814
|
+
|
|
815
|
+
Optional `id` or `name` filters are accepted:
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
```bash
|
|
819
|
+
ligoj hook get
|
|
820
|
+
ligoj hook get --id 1
|
|
821
|
+
ligoj hook get --name "audit_role_change"
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
```json
|
|
825
|
+
[{"id": 1, "name": "audit_role_change", "workingDirectory": "/var/log", "command": "/path/to/ligoj_audit.sh", "match": "{\"path\":\"system/security/role.*\"}", "injects": ["java.class.path"]}]
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
## Plugin
|
|
830
|
+
|
|
831
|
+
### List Ligoj plugins
|
|
832
|
+
|
|
833
|
+
```bash
|
|
834
|
+
ligoj plugin list
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
```json
|
|
838
|
+
[
|
|
839
|
+
{
|
|
840
|
+
"id": "feature:ui",
|
|
841
|
+
"name": "Ui",
|
|
842
|
+
"plugin": {
|
|
843
|
+
"id": 4,
|
|
844
|
+
"createdBy": "_system",
|
|
845
|
+
"createdDate": 1758279349900,
|
|
846
|
+
"lastModifiedBy": "_system",
|
|
847
|
+
"lastModifiedDate": 1762277251346,
|
|
848
|
+
"version": "2025-10-31T14:25:16.306432087Z",
|
|
849
|
+
"key": "feature:ui",
|
|
850
|
+
"artifact": "plugin-ui",
|
|
851
|
+
"basePackage": "org.ligoj.app.plugin.ui",
|
|
852
|
+
"type": "FEATURE"
|
|
853
|
+
},
|
|
854
|
+
"location": "/path/to/ligoj-plugins/plugin-ui/target/classes/",
|
|
855
|
+
"deleted": false,
|
|
856
|
+
"nodes": 0,
|
|
857
|
+
"subscriptions": 0
|
|
858
|
+
},
|
|
859
|
+
...
|
|
860
|
+
{
|
|
861
|
+
"id": "service:id:ldap",
|
|
862
|
+
"name": "Ldap",
|
|
863
|
+
"plugin": {
|
|
864
|
+
"id": 155,
|
|
865
|
+
"createdBy": "_system",
|
|
866
|
+
"createdDate": 1762277251427,
|
|
867
|
+
"lastModifiedBy": "_system",
|
|
868
|
+
"lastModifiedDate": 1762450362232,
|
|
869
|
+
"version": "2025-11-05T22:06:40.787627578Z",
|
|
870
|
+
"key": "service:id:ldap",
|
|
871
|
+
"artifact": "plugin-id-ldap",
|
|
872
|
+
"basePackage": "org.ligoj.app.plugin.id.ldap.resource",
|
|
873
|
+
"type": "TOOL"
|
|
874
|
+
},
|
|
875
|
+
"location": "/path/to/ligoj-plugins/plugin-id-ldap/target/classes/",
|
|
876
|
+
"nodes": 2,
|
|
877
|
+
"node": {
|
|
878
|
+
"id": "service:id:ldap",
|
|
879
|
+
"name": "Identity LDAP",
|
|
880
|
+
"refined": {"id": "service:id","name": "Identity", "mode": "create", "uiClasses": "far fa-id-badge"},
|
|
881
|
+
"mode": "all"
|
|
882
|
+
},
|
|
883
|
+
"subscriptions": 5
|
|
884
|
+
}
|
|
885
|
+
]
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### Install Ligoj plugins
|
|
889
|
+
|
|
890
|
+
When an explicit version is not provided, the latest version available from Maven Central is used.
|
|
891
|
+
|
|
892
|
+
This lookup depends on the `plugins.repository-manager.nexus.search` configuration, while the download relies on `plugins.repository-manager.nexus.artifact` configuration.
|
|
893
|
+
|
|
894
|
+
```bash
|
|
895
|
+
ligoj plugin install --id "plugin-id" --repository "central" --version "2.2.10" --force
|
|
896
|
+
ligoj plugin install --id "plugin-id" --version "LATEST" --repository "nexus"
|
|
897
|
+
ligoj plugin install --id "plugin-id-ldap" --version "2.1.1" --repository "nexus" --force
|
|
898
|
+
ligoj plugin install --id "plugin-req-squash"
|
|
899
|
+
ligoj plugin install --id "plugin-req"
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
```log
|
|
903
|
+
[INFO ] [ligoj] Plugin 'plugin-req' has been installed/updated, a restart is required
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
Two successful consecutive executions give this output:
|
|
907
|
+
|
|
908
|
+
```log
|
|
909
|
+
[INFO ] [ligoj] Plugin 'plugin-id-ldap:2.0.3' is being installed
|
|
910
|
+
[INFO ] [ligoj] Plugin 'plugin-req:1.0.1' is installed but requires a restart to be available
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
*Note* After installing plugins, a restart is needed to use them.
|
|
914
|
+
|
|
915
|
+
### Restart API
|
|
916
|
+
|
|
917
|
+
```bash
|
|
918
|
+
ligoj plugin restart
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
```json
|
|
922
|
+
null
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
Optionally, a wait for status can be defined. A regular poll to the server [status](#status) is performed until reaching `DOWN` or `UP` status.
|
|
926
|
+
When different from `0`, the final status is returned.
|
|
927
|
+
|
|
928
|
+
```bash
|
|
929
|
+
ligoj plugin restart --wait 20
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
```json
|
|
933
|
+
{"status": "UP"}
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
## Node
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
### List nodes
|
|
940
|
+
|
|
941
|
+
```bash
|
|
942
|
+
ligoj node list
|
|
943
|
+
```
|
|
944
|
+
|
|
945
|
+
```json
|
|
946
|
+
{
|
|
947
|
+
"recordsTotal": 23,
|
|
948
|
+
"recordsFiltered": 23,
|
|
949
|
+
"data": [
|
|
950
|
+
{"id": "service:build", "name": "Build", "mode": "link", "uiClasses": "fa fa-cogs", "enabled": true},
|
|
951
|
+
{"id": "service:build:jenkins", "name": "Jenkins", "refined": {"id": "service:build", "name": "Build", "mode": "link", "uiClasses": "fa fa-cogs"}, "mode": "all", "uiClasses": "fab fa-jenkins", "enabled": true},
|
|
952
|
+
...
|
|
953
|
+
]
|
|
954
|
+
}
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
Optionally, parameters can be returned with provided mode and other filters
|
|
958
|
+
|
|
959
|
+
```bash
|
|
960
|
+
ligoj node list --parameters-mode "all"
|
|
961
|
+
ligoj node list --parameters-mode "all" --search jenkins
|
|
962
|
+
ligoj node list --parameters-output "map" --refined "service:build:jenkins"
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
```json
|
|
966
|
+
{
|
|
967
|
+
"recordsTotal": 23,
|
|
968
|
+
"recordsFiltered": 23,
|
|
969
|
+
"data": [
|
|
970
|
+
{"id": "service:build", "name": "Build", "mode": "link", "uiClasses": "fa fa-cogs", "enabled": true, "parameters": []},
|
|
971
|
+
{"id": "service:build:jenkins", "name": "Jenkins", "refined": {"id": "service:build", "name": "Build", "mode": "link", "uiClasses": "fa fa-cogs"}, "mode": "all", "uiClasses": "fab fa-jenkins", "enabled": true, "parameters": []},
|
|
972
|
+
{"id": "service:build:jenkins:local", "name": "Jenkins Local", "refined": {"id": "service:build:jenkins", "name": "Jenkins", "refined": {"id": "service:build", "name": "Build", "mode": "link", "uiClasses": "fa fa-cogs"}, "mode": "all", "uiClasses": "fab fa-jenkins"}, "mode": "all", "enabled": true,
|
|
973
|
+
"parameters": [
|
|
974
|
+
{"text": "-secured-", "parameter": "service:build:jenkins:api-token"}, {"text": "http://localhost:9190/", "parameter": "service:build:jenkins:url"},
|
|
975
|
+
{"text": "-secured-", "parameter": "service:build:jenkins:user"}
|
|
976
|
+
]
|
|
977
|
+
},
|
|
978
|
+
...
|
|
979
|
+
]
|
|
980
|
+
}
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
### Configure/update a node
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
If the related node already exists, it is updated.
|
|
987
|
+
|
|
988
|
+
```bash
|
|
989
|
+
ligoj node upsert --id "service:id:ldap:remote1" --name "Remote1" --from ligoj-ldap.json
|
|
990
|
+
ligoj node upsert --id "service:id:ldap:remote1" --name "Remote1" --from https://path/to/ligoj-ldap.json
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
```json
|
|
994
|
+
{"id": "service:id:ldap:remote1", "name": "Remote1", "mode": "all", "enabled": true}
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
Input `--from` JSON:
|
|
998
|
+
- See [`--from`](#--from) for JSON loading options
|
|
999
|
+
- JSON can be as list or dict (compact). See sample.
|
|
1000
|
+
- The parameters marked as sensitive are encrypted in database of Ligoj.
|
|
1001
|
+
|
|
1002
|
+
Content of sample [ligoj-ldap.json](docs/nodes/ldap.json) file:
|
|
1003
|
+
|
|
1004
|
+
```json
|
|
1005
|
+
[
|
|
1006
|
+
{
|
|
1007
|
+
"parameter": "service:id:ldap:base-dn",
|
|
1008
|
+
"text": "cn=Test"
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
"parameter": "service:id:ldap:uid-attribute",
|
|
1012
|
+
"text": "uid"
|
|
1013
|
+
}
|
|
1014
|
+
]
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
### Get node by identifier
|
|
1019
|
+
|
|
1020
|
+
```bash
|
|
1021
|
+
ligoj node get --id "service:id"
|
|
1022
|
+
ligoj node get --id "service:id:ldap"
|
|
1023
|
+
ligoj node get --id "service:id:ldap:remote1"
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
```json
|
|
1027
|
+
{"id": "service:id:ldap:remote1", "name": "Remote1", "mode": "all", "enabled": true}
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
Optionally, parameters can be returned with provided mode
|
|
1031
|
+
|
|
1032
|
+
```bash
|
|
1033
|
+
ligoj node get --id "service:id" --parameters-mode "all"
|
|
1034
|
+
ligoj node get --id "service:id:ldap" --parameters-mode "all"
|
|
1035
|
+
ligoj node get --id "service:id:ldap:remote1" --parameters-mode "all"
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
```json
|
|
1039
|
+
{
|
|
1040
|
+
"id": "service:id:ldap:remote1", "name": "Remote1", "mode": "all", "enabled": true,
|
|
1041
|
+
"parameters": [
|
|
1042
|
+
{"text": "cn=Test", "parameter": "service:id:ldap:base-dn"}, {"bool": true, "parameter": "service:id:ldap:clear-password"},
|
|
1043
|
+
{"text": "organizationalUnit", "parameter": "service:id:ldap:companies-class"},
|
|
1044
|
+
{"text": "-secured-", "parameter": "service:id:ldap:user-dn"}]
|
|
1045
|
+
}
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
Optionally, parameters can be returned with more details
|
|
1049
|
+
|
|
1050
|
+
```bash
|
|
1051
|
+
ligoj node get --id "service:id:ldap:remote1" --parameters-mode "all" --parameters-output "full"
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
```json
|
|
1055
|
+
{
|
|
1056
|
+
"id": "service:id:ldap:remote1", "name": "Remote1", "mode": "all", "enabled": true,
|
|
1057
|
+
"parameters": [{
|
|
1058
|
+
"parameter": {
|
|
1059
|
+
"id": "service:id:group",
|
|
1060
|
+
"type": "text",
|
|
1061
|
+
"owner": {
|
|
1062
|
+
"id": "service:id",
|
|
1063
|
+
"name": "Identity",
|
|
1064
|
+
"mode": "create",
|
|
1065
|
+
"uiClasses": "far fa-id-badge"
|
|
1066
|
+
},
|
|
1067
|
+
"mandatory": true,
|
|
1068
|
+
"secured": false,
|
|
1069
|
+
"depends": []
|
|
1070
|
+
}
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
"text": "cn=Test",
|
|
1074
|
+
"parameter": {
|
|
1075
|
+
"id": "service:id:ldap:base-dn",
|
|
1076
|
+
"type": "text",
|
|
1077
|
+
"owner": {
|
|
1078
|
+
"id": "service:id:ldap",
|
|
1079
|
+
"name": "Identity LDAP",
|
|
1080
|
+
"refined": {
|
|
1081
|
+
"id": "service:id",
|
|
1082
|
+
"name": "Identity",
|
|
1083
|
+
"mode": "create",
|
|
1084
|
+
"uiClasses": "far fa-id-badge"
|
|
1085
|
+
},
|
|
1086
|
+
"mode": "all"
|
|
1087
|
+
},
|
|
1088
|
+
"mandatory": false,
|
|
1089
|
+
"secured": false,
|
|
1090
|
+
"depends": []
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
]
|
|
1094
|
+
}
|
|
1095
|
+
```
|
|
1096
|
+
|
|
1097
|
+
Optionally, parameter values can be decrypted. One API call is performed for each secured value.
|
|
1098
|
+
|
|
1099
|
+
This mode is only available for users having `ADMIN` role.
|
|
1100
|
+
|
|
1101
|
+
```bash
|
|
1102
|
+
ligoj node get --id "service:id:ldap:remote1" --parameters-mode "all" --parameters-output map --parameters-secured
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
```json
|
|
1106
|
+
{
|
|
1107
|
+
"id": "service:id:ldap:remote1", "name": "Remote1", "mode": "all", "enabled": true,
|
|
1108
|
+
"parameters": {
|
|
1109
|
+
"service:id:ldap:base-dn": "cn=Test",
|
|
1110
|
+
"service:id:ldap:clear-password": true,
|
|
1111
|
+
"service:id:ldap:url": "ldap:localhost:1389",
|
|
1112
|
+
"service:id:ldap:password": "secret",
|
|
1113
|
+
"service:id:ldap:companies-class": "organizationalUnit",
|
|
1114
|
+
"service:id:ldap:companies-dn": "ou=people,dc=sample,dc=com"
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
### Get node status
|
|
1120
|
+
|
|
1121
|
+
```bash
|
|
1122
|
+
ligoj node status --id "service:id:ldap:remote1"
|
|
1123
|
+
```
|
|
1124
|
+
|
|
1125
|
+
```json
|
|
1126
|
+
{"id": "down"}
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
## Delegate node
|
|
1130
|
+
|
|
1131
|
+
Node delegates allow users, groups or companies to manage nodes.
|
|
1132
|
+
|
|
1133
|
+
Sub nodes inherit the delegate permissions.
|
|
1134
|
+
|
|
1135
|
+
### List delegate nodes
|
|
1136
|
+
|
|
1137
|
+
```bash
|
|
1138
|
+
ligoj delegate-node list
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
```json
|
|
1142
|
+
[
|
|
1143
|
+
{"id": 1, "createdBy": "_system", "createdDate": 1758279349979, "lastModifiedBy": "_system", "lastModifiedDate": 1758279349979, "name": "service", "receiver": "ligoj-admin", "receiverType": "user", "canWrite": true, "canAdmin": true, "canSubscribe": true, "referenceID": "service"}
|
|
1144
|
+
]
|
|
1145
|
+
```
|
|
1146
|
+
|
|
1147
|
+
### Create delegate node
|
|
1148
|
+
|
|
1149
|
+
Create a delegate with subscribe, administration, and creation rights for a receiver on an optional node and its sub-nodes.
|
|
1150
|
+
|
|
1151
|
+
The provided node does not need to exist yet.
|
|
1152
|
+
|
|
1153
|
+
```bash
|
|
1154
|
+
ligoj delegate-node create --node service --can-subscribe --can-admin --can-write --receiver jdoe --receiver-type user
|
|
1155
|
+
ligoj delegate-node create --node service:id --can-subscribe --receiver internal --receiver-type company
|
|
1156
|
+
ligoj delegate-node create --node service:id:ldap:instance1 --can-admin --can-write --receiver group1 --receiver-type group
|
|
1157
|
+
```
|
|
1158
|
+
|
|
1159
|
+
### Delete delegate node
|
|
1160
|
+
|
|
1161
|
+
Delete a delegate node from its identifier.
|
|
1162
|
+
|
|
1163
|
+
```bash
|
|
1164
|
+
ligoj delegate-node delete --id 1
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
### Get a delegate node
|
|
1168
|
+
|
|
1169
|
+
Get a delegate node from its identifier.
|
|
1170
|
+
|
|
1171
|
+
```bash
|
|
1172
|
+
ligoj delegate-node get --id 1
|
|
1173
|
+
ligoj delegate-node get --node 1
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
## Project
|
|
1178
|
+
|
|
1179
|
+
### List projects
|
|
1180
|
+
|
|
1181
|
+
List projects with optional search criteria.
|
|
1182
|
+
|
|
1183
|
+
```bash
|
|
1184
|
+
ligoj project list
|
|
1185
|
+
ligoj project list --search project1
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1188
|
+
```json
|
|
1189
|
+
{
|
|
1190
|
+
"recordsTotal": 1,
|
|
1191
|
+
"recordsFiltered": 1,
|
|
1192
|
+
"data": [
|
|
1193
|
+
{
|
|
1194
|
+
"id": 153,
|
|
1195
|
+
"createdDate": 1705853880193, "lastModifiedDate": 1705853880193,
|
|
1196
|
+
"createdBy": { "id": "ligoj-admin", ...},
|
|
1197
|
+
"lastModifiedBy": {"id": "ligoj-admin", ...},
|
|
1198
|
+
"name": "Project 1",
|
|
1199
|
+
"teamLeader": {"id": "ligoj-admin", ...},
|
|
1200
|
+
"pkey": "project1",
|
|
1201
|
+
"description": "",
|
|
1202
|
+
"nbSubscriptions": 2
|
|
1203
|
+
},
|
|
1204
|
+
...
|
|
1205
|
+
]
|
|
1206
|
+
}
|
|
1207
|
+
```
|
|
1208
|
+
### Get Project
|
|
1209
|
+
|
|
1210
|
+
```bash
|
|
1211
|
+
ligoj project get --id 153
|
|
1212
|
+
ligoj project get --id "project1"
|
|
1213
|
+
```
|
|
1214
|
+
|
|
1215
|
+
```json
|
|
1216
|
+
{
|
|
1217
|
+
"id": 153,
|
|
1218
|
+
"createdDate": 1705853880193, "lastModifiedDate": 1705853880193,
|
|
1219
|
+
"createdBy": { "id": "ligoj-admin", ...},
|
|
1220
|
+
"lastModifiedBy": {"id": "ligoj-admin", ...},
|
|
1221
|
+
"name": "Project 1",
|
|
1222
|
+
"teamLeader": {"id": "ligoj-admin", ...},
|
|
1223
|
+
"pkey": "project1",
|
|
1224
|
+
"description": "",
|
|
1225
|
+
"manageSubscriptions": true,
|
|
1226
|
+
"subscriptions": [
|
|
1227
|
+
{"id": 355, ...},
|
|
1228
|
+
{"id": 362, ...}
|
|
1229
|
+
]
|
|
1230
|
+
}
|
|
1231
|
+
```
|
|
1232
|
+
|
|
1233
|
+
### Create Project
|
|
1234
|
+
|
|
1235
|
+
```bash
|
|
1236
|
+
ligoj project create --name "project4" --team-leader "ligoj-admin" --pkey "sample:project4" --description "Sample project 4" --context='{"some":"value"}'
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
```json
|
|
1240
|
+
{
|
|
1241
|
+
"id": 352,
|
|
1242
|
+
"creationContext": "{\"some\":\"value\"}",
|
|
1243
|
+
"name": "project4",
|
|
1244
|
+
"teamLeader": {"id": "ligoj-admin",...},
|
|
1245
|
+
"pkey": "sample:project4",
|
|
1246
|
+
"description": "Sample project 4",
|
|
1247
|
+
...
|
|
1248
|
+
}
|
|
1249
|
+
```
|
|
1250
|
+
|
|
1251
|
+
### Delete Project
|
|
1252
|
+
|
|
1253
|
+
Delete project with optional search criteria.
|
|
1254
|
+
|
|
1255
|
+
```bash
|
|
1256
|
+
ligoj project delete --id 252
|
|
1257
|
+
ligoj project delete --id "sample:project4"
|
|
1258
|
+
ligoj project delete --id "sample:project4" --with-data
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
## Subscription operations
|
|
1263
|
+
|
|
1264
|
+
### List subscriptions
|
|
1265
|
+
|
|
1266
|
+
Combined filters are accepted.
|
|
1267
|
+
|
|
1268
|
+
```bash
|
|
1269
|
+
ligoj subscription list --node "service:id:ldap:remote1"
|
|
1270
|
+
ligoj subscription list --tool "service:id:ldap"
|
|
1271
|
+
ligoj subscription list --service "service:id"
|
|
1272
|
+
ligoj subscription list --project "project1"
|
|
1273
|
+
ligoj subscription list --project 104
|
|
1274
|
+
```
|
|
1275
|
+
|
|
1276
|
+
```json
|
|
1277
|
+
[
|
|
1278
|
+
{"id": 155, "node": "service:id:ldap:remote1", "project": 104},
|
|
1279
|
+
{"id": 302, "node": "service:qa:sonarqube:8", "project": 104}
|
|
1280
|
+
]
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1283
|
+
### Get subscription details
|
|
1284
|
+
|
|
1285
|
+
```bash
|
|
1286
|
+
ligoj subscription get --id 302
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
```json
|
|
1290
|
+
{"service:qa:sonarqube:project": "test", "service:qa:sonarqube:url": "http://127.0.0.1:9000/"}
|
|
1291
|
+
```
|
|
1292
|
+
|
|
1293
|
+
#### With related project and node details
|
|
1294
|
+
|
|
1295
|
+
```bash
|
|
1296
|
+
ligoj subscription get --id 302 --details
|
|
1297
|
+
```
|
|
1298
|
+
|
|
1299
|
+
```json
|
|
1300
|
+
{"subscription": 302, "project": {"id": 104, "name": "Project1", "description": "Foo bar"}, "parameters": {"service:qa:sonarqube:project": "test", "service:qa:sonarqube:url": "http://127.0.0.1:9000/"}, "node": {"id": "service:qa:sonarqube:8", "name": "Sonar Local 8", "refined": {"id": "service:qa:sonarqube", "name": "SonarQube", "refined": {"id": "service:qa", "name": "Quality Assurance", "mode": "link", "uiClasses": "fas fa-tachometer-alt"}, "mode": "link"}, "mode": "link", "enabled": true}}
|
|
1301
|
+
```
|
|
1302
|
+
|
|
1303
|
+
### Create subscription
|
|
1304
|
+
|
|
1305
|
+
Configuration file can be a JSON file, a remote HTTP URL, or plain JSON. Both forms of parameters are accepted, as list or dict (compact).
|
|
1306
|
+
|
|
1307
|
+
Duplicate subscriptions are ignored: same project, node and parameters.
|
|
1308
|
+
|
|
1309
|
+
```bash
|
|
1310
|
+
ligoj subscription create --project project1 --node "service:id:ldap:remote1" --from conf.json
|
|
1311
|
+
ligoj subscription create --project project1 --node "service:id:ldap:remote1" --from "https://path/to/conf.json"
|
|
1312
|
+
ligoj subscription create --project project1 --node "service:id:ldap:remote1" --from '[{"parameter": "service:id:group", "text": "project1-team"}, {"parameter": "service:id:ou", "text": "project1"}]'
|
|
1313
|
+
ligoj subscription create --project project1 --node "service:id:ldap:remote1" --from '{"service:id:group": "project1-team", "service:id:ou": "project1"}'
|
|
1314
|
+
...
|
|
1315
|
+
```
|
|
1316
|
+
|
|
1317
|
+
```json
|
|
1318
|
+
362
|
|
1319
|
+
```
|
|
1320
|
+
|
|
1321
|
+
Input `--from` JSON:
|
|
1322
|
+
- See [`--from`](#--from) for JSON loading options
|
|
1323
|
+
- JSON can be as list or dict (compact). See sample.
|
|
1324
|
+
- The parameters marked as sensitive are encrypted in database of Ligoj.
|
|
1325
|
+
|
|
1326
|
+
### Delete a subscription
|
|
1327
|
+
|
|
1328
|
+
Delete a subscription from its identifier.
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
```bash
|
|
1332
|
+
ligoj subscription delete --id 302
|
|
1333
|
+
```
|
|
1334
|
+
|
|
1335
|
+
By default, only the link between Ligoj and the remote tool is removed. Optionally, when Ligoj has created data with the subscription, it can also be deleted with this operation.
|
|
1336
|
+
|
|
1337
|
+
For example, LDAP groups or a Jenkins job created at subscription time will be deleted.
|
|
1338
|
+
|
|
1339
|
+
```bash
|
|
1340
|
+
ligoj subscription delete --id 302 --with-data
|
|
1341
|
+
```
|
|
1342
|
+
|
|
1343
|
+
### Get subscription statuses of a project
|
|
1344
|
+
|
|
1345
|
+
Return the last computed status of all subscriptions of given project.
|
|
1346
|
+
|
|
1347
|
+
```bash
|
|
1348
|
+
ligoj subscription status --project 104
|
|
1349
|
+
ligoj subscription status --project project1
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1352
|
+
```json
|
|
1353
|
+
{
|
|
1354
|
+
"155": {"specifics": [], "value": "UP", "type": "status", "node": {"id": "service:id:ldap:remote1", "name": "TestAnnuaireCLI", "mode": "all"}, "subscription": 155},
|
|
1355
|
+
"252": {"specifics": [], "value": "DOWN", "type": "status", "node": {"id": "service:qa:sonarqube:user", "name": "Sonar Local User", "mode": "link"}, "subscription": 252},
|
|
1356
|
+
"157": {"specifics": [], "value": "UP", "type": "status", "node": {"id": "service:id:ldap:remote1", "name": "TestAnnuaireCLI", "mode": "all"}, "subscription": 157}
|
|
1357
|
+
}
|
|
1358
|
+
```
|
|
1359
|
+
|
|
1360
|
+
### Request subscription status refresh
|
|
1361
|
+
|
|
1362
|
+
Retrieve the up-to-date status of a subscription.
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
Up subscription:
|
|
1366
|
+
|
|
1367
|
+
```bash
|
|
1368
|
+
ligoj subscription refresh --id 155
|
|
1369
|
+
```
|
|
1370
|
+
|
|
1371
|
+
```json
|
|
1372
|
+
{"id": 155, "status": "up", "node": "service:id:ldap:remote1", "project": 104, "data": {"members": 0}, "parameters": {...}}
|
|
1373
|
+
```
|
|
1374
|
+
|
|
1375
|
+
Down subscription:
|
|
1376
|
+
```bash
|
|
1377
|
+
ligoj subscription refresh --id 252
|
|
1378
|
+
```
|
|
1379
|
+
|
|
1380
|
+
```json
|
|
1381
|
+
{"id": 252, "status": "down", "project": 104, "data": {}, "parameters": {"service:qa:sonarqube:project": "test",...}}
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
# Plugin id
|
|
1386
|
+
|
|
1387
|
+
Operations related to [plugin-id](https://github.com/ligoj/plugin-id) and sub-plugins.
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
## Plugin `id:scope` operations
|
|
1391
|
+
|
|
1392
|
+
Operations related to container scopes managed by `service:id` nodes.
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
### Create container scope
|
|
1396
|
+
|
|
1397
|
+
Create a container scope
|
|
1398
|
+
|
|
1399
|
+
```bash
|
|
1400
|
+
ligoj id:scope create --id "Unassigned" --type "group" --dn "ou=groups,dc=example,dc=com"
|
|
1401
|
+
ligoj id:scope create --id "Projects" --type "group" --dn "ou=projects,ou=groups,dc=example,dc=com"
|
|
1402
|
+
ligoj id:scope create --id "Tools" --type "group" --dn "ou=tools,ou=groups,dc=example,dc=com"
|
|
1403
|
+
ligoj id:scope create --id "Unassigned" --type "company" --dn "ou=people,dc=example,dc=com"
|
|
1404
|
+
ligoj id:scope create --id "Internal" --type "company" --dn "ou=internal,ou=people,dc=example,dc=com"
|
|
1405
|
+
ligoj id:scope create --id "Unassigned" --type "tree" --dn "dc=example,dc=com"
|
|
1406
|
+
```
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
### Get container scope
|
|
1410
|
+
|
|
1411
|
+
Return a container scope
|
|
1412
|
+
|
|
1413
|
+
```bash
|
|
1414
|
+
ligoj id:scope get --id "SampleGroup2"
|
|
1415
|
+
```
|
|
1416
|
+
|
|
1417
|
+
```json
|
|
1418
|
+
{"id": "samplegroup2", "name": "SampleGroup2", "scope": "Unassigned", "locked": false}
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
### List container scopes
|
|
1423
|
+
|
|
1424
|
+
Return a list of container scopes
|
|
1425
|
+
|
|
1426
|
+
```bash
|
|
1427
|
+
ligoj id:scope list --type "group"
|
|
1428
|
+
```
|
|
1429
|
+
|
|
1430
|
+
```json
|
|
1431
|
+
{
|
|
1432
|
+
"recordsTotal": 4, "recordsFiltered": 3,
|
|
1433
|
+
"data": [
|
|
1434
|
+
{"id": 5, "name": "Unassigned", "dn": "ou=groups,dc=sample,dc=com", "type": "group", "locked": false},
|
|
1435
|
+
{"id": 6, "name": "Project", "dn": "ou=projects,ou=groups,dc=sample,dc=com", "type": "group", "locked": false},
|
|
1436
|
+
{"id": 7, "name": "Technical", "dn": "ou=tools,ou=groups,dc=sample,dc=com", "type": "group", "locked": false}
|
|
1437
|
+
]
|
|
1438
|
+
}
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
## Plugin `id:group` operations
|
|
1442
|
+
|
|
1443
|
+
Operations related to groups managed by `service:id` nodes
|
|
1444
|
+
|
|
1445
|
+
Group name is case insensitive.
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
### Create group
|
|
1449
|
+
|
|
1450
|
+
Create a group.
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
```bash
|
|
1454
|
+
ligoj id:group create --name "SampleGroup2" --scope "Unassigned"
|
|
1455
|
+
```
|
|
1456
|
+
|
|
1457
|
+
Create a group inside a group
|
|
1458
|
+
|
|
1459
|
+
```bash
|
|
1460
|
+
ligoj id:group create --name "SampleSubGroup" --scope "Unassigned" --parent "SampleGroup2"
|
|
1461
|
+
ligoj id:group create --name "SampleSubGroup2" --scope "Unassigned" --parent "SampleSubGroup"
|
|
1462
|
+
```
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
### Delete a group
|
|
1466
|
+
|
|
1467
|
+
Delete a group. The command will not fail if the group does not exist.
|
|
1468
|
+
|
|
1469
|
+
```bash
|
|
1470
|
+
ligoj id:group delete --name "SampleGroup2"
|
|
1471
|
+
```
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
### Get group
|
|
1475
|
+
|
|
1476
|
+
Retrieve a group
|
|
1477
|
+
|
|
1478
|
+
```bash
|
|
1479
|
+
ligoj id:group get --name "SampleGroup2"
|
|
1480
|
+
```
|
|
1481
|
+
|
|
1482
|
+
```json
|
|
1483
|
+
{"id": "samplegroup2", "name": "SampleGroup2", "scope": "Unassigned", "locked": false}
|
|
1484
|
+
```
|
|
1485
|
+
|
|
1486
|
+
### Delete group
|
|
1487
|
+
|
|
1488
|
+
Delete a group. If the group does not exist, the command will not return an error.
|
|
1489
|
+
|
|
1490
|
+
```bash
|
|
1491
|
+
ligoj id:group delete --name "SampleGroup2"
|
|
1492
|
+
```
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
### List group
|
|
1496
|
+
|
|
1497
|
+
List groups
|
|
1498
|
+
|
|
1499
|
+
```bash
|
|
1500
|
+
ligoj id:group list
|
|
1501
|
+
```
|
|
1502
|
+
|
|
1503
|
+
```json
|
|
1504
|
+
{
|
|
1505
|
+
"recordsTotal": 4,
|
|
1506
|
+
"recordsFiltered": 4,
|
|
1507
|
+
"data": [
|
|
1508
|
+
{
|
|
1509
|
+
"id": "sample group",
|
|
1510
|
+
"name": "Sample Group",
|
|
1511
|
+
"scope": "Unassigned",
|
|
1512
|
+
"locked": false,
|
|
1513
|
+
"countVisible": 3,
|
|
1514
|
+
"count": 3,
|
|
1515
|
+
"canWrite": true,
|
|
1516
|
+
"canAdmin": true,
|
|
1517
|
+
"containerType": "group"
|
|
1518
|
+
},
|
|
1519
|
+
{
|
|
1520
|
+
"id": "samplegroup2",
|
|
1521
|
+
"name": "SampleGroup2",
|
|
1522
|
+
"scope": "Unassigned",
|
|
1523
|
+
"locked": false,
|
|
1524
|
+
"countVisible": 0,
|
|
1525
|
+
"count": 0,
|
|
1526
|
+
"canWrite": true,
|
|
1527
|
+
"canAdmin": true,
|
|
1528
|
+
"containerType": "group"
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
"id": "samplesubgroup",
|
|
1532
|
+
"name": "SampleSubGroup",
|
|
1533
|
+
"scope": "Unassigned",
|
|
1534
|
+
"locked": false,
|
|
1535
|
+
"countVisible": 0,
|
|
1536
|
+
"count": 0,
|
|
1537
|
+
"canWrite": true,
|
|
1538
|
+
"canAdmin": true,
|
|
1539
|
+
"containerType": "group",
|
|
1540
|
+
"parents": [
|
|
1541
|
+
"samplegroup2"
|
|
1542
|
+
]
|
|
1543
|
+
},
|
|
1544
|
+
{
|
|
1545
|
+
"id": "samplesubgroup2",
|
|
1546
|
+
"name": "SampleSubGroup2",
|
|
1547
|
+
"scope": "Unassigned",
|
|
1548
|
+
"locked": false,
|
|
1549
|
+
"countVisible": 0,
|
|
1550
|
+
"count": 0,
|
|
1551
|
+
"canWrite": true,
|
|
1552
|
+
"canAdmin": true,
|
|
1553
|
+
"containerType": "group",
|
|
1554
|
+
"parents": [
|
|
1555
|
+
"samplesubgroup",
|
|
1556
|
+
"samplegroup2"
|
|
1557
|
+
]
|
|
1558
|
+
}
|
|
1559
|
+
]
|
|
1560
|
+
}
|
|
1561
|
+
```
|
|
1562
|
+
|
|
1563
|
+
## Plugin `id:user` operations
|
|
1564
|
+
|
|
1565
|
+
Operations related to users managed by `service:id` nodes
|
|
1566
|
+
|
|
1567
|
+
|
|
1568
|
+
### Create user
|
|
1569
|
+
|
|
1570
|
+
```bash
|
|
1571
|
+
ligoj id:user create --id jdupont --firstname "Jean" --lastname "Dupont" --mail "jdupont@kloudy.io" --company "external" --groups "Sample Group,SampleGroup2"
|
|
1572
|
+
ligoj id:user create --id jdupont2 --firstname "Jean" --lastname "Dupont" --mail "jdupont@kloudy.io" --company "external" --groups "Sample Group,SampleGroup2"
|
|
1573
|
+
```
|
|
1574
|
+
|
|
1575
|
+
### Delete user
|
|
1576
|
+
|
|
1577
|
+
Delete a user. If the user does not exist, the command will not return an error.
|
|
1578
|
+
|
|
1579
|
+
```bash
|
|
1580
|
+
ligoj id:user delete --id jdupont2
|
|
1581
|
+
ligoj id:user delete --mail jdupont@kloudy.io
|
|
1582
|
+
```
|
|
1583
|
+
|
|
1584
|
+
### List users
|
|
1585
|
+
|
|
1586
|
+
```bash
|
|
1587
|
+
ligoj id:user list
|
|
1588
|
+
ligoj id:user list --company "department1" --group "Sample Group" --criteria "@sample.com" --page-length 2
|
|
1589
|
+
ligoj id:user list --company "department1" --page-length 2
|
|
1590
|
+
```
|
|
1591
|
+
|
|
1592
|
+
```json
|
|
1593
|
+
{
|
|
1594
|
+
"recordsTotal": 102,
|
|
1595
|
+
"recordsFiltered": 102,
|
|
1596
|
+
"extensions": {"customAttributes": ["uidFonctionnel"]}},
|
|
1597
|
+
"data": [
|
|
1598
|
+
{"firstName": "John", "lastName": "Doe", "id": "jdoe", "company": "external", "mails": ["jdoe@sample.com"], "groups": ["Sample Group", "SampleGroup2"], "name": "jdoe"},
|
|
1599
|
+
{"firstName": "Cli2", "lastName": "Name", "id": "cli2name", "company": "external", "mails": ["a@bc.org","cli2@sample.com"], "groups": ["Sample Group"], "name": "cli2name"}
|
|
1600
|
+
]
|
|
1601
|
+
}
|
|
1602
|
+
```
|
|
1603
|
+
### Get user
|
|
1604
|
+
|
|
1605
|
+
Return a user. If the user does not exist, the command will return `null`.
|
|
1606
|
+
|
|
1607
|
+
```bash
|
|
1608
|
+
ligoj id:user get --id jdupont
|
|
1609
|
+
ligoj id:user get --mail jdupont@kloudy.io
|
|
1610
|
+
```
|
|
1611
|
+
|
|
1612
|
+
```json
|
|
1613
|
+
{"firstName": "Jean", "lastName": "Dupont", "id": "jdupont", "company": "external", "mails": ["jdupont@kloudy.io"], "groups": ["Sample Group", "SampleGroup2"], "name": "jdupont"}
|
|
1614
|
+
```
|
|
1615
|
+
|
|
1616
|
+
### Add user to a group
|
|
1617
|
+
|
|
1618
|
+
The user and the group must exist.
|
|
1619
|
+
The command does not fail if the user is already in the group.
|
|
1620
|
+
|
|
1621
|
+
```bash
|
|
1622
|
+
ligoj id:user add --id jdupont --groups "SampleGroup2"
|
|
1623
|
+
ligoj id:user add --mail jdupont@kloudy.io --groups "SampleGroup2"
|
|
1624
|
+
ligoj id:user add --mail cli10.name@sample.com --groups "Sample Group"
|
|
1625
|
+
```
|
|
1626
|
+
|
|
1627
|
+
### Remove user from a group
|
|
1628
|
+
|
|
1629
|
+
The user and the group must exist.
|
|
1630
|
+
The command does not fail if the user is not in the group.
|
|
1631
|
+
|
|
1632
|
+
```bash
|
|
1633
|
+
ligoj id:user remove --id jdupont --groups "SampleGroup2"
|
|
1634
|
+
ligoj id:user remove --mail jdupont@kloudy.io --groups "SampleGroup2"
|
|
1635
|
+
```
|
|
1636
|
+
|
|
1637
|
+
### Reset user password
|
|
1638
|
+
|
|
1639
|
+
For a specific user (need administrative rights):
|
|
1640
|
+
|
|
1641
|
+
The user must exist.
|
|
1642
|
+
|
|
1643
|
+
```bash
|
|
1644
|
+
ligoj id:user reset-password --id jdupont
|
|
1645
|
+
ligoj id:user reset-password --mail jdupont@kloudy.io
|
|
1646
|
+
```
|
|
1647
|
+
|
|
1648
|
+
For current user:
|
|
1649
|
+
|
|
1650
|
+
```bash
|
|
1651
|
+
ligoj id:user reset-password
|
|
1652
|
+
```
|
|
1653
|
+
|
|
1654
|
+
# Bootstrap
|
|
1655
|
+
|
|
1656
|
+
The following commands can be executed to perform several API commands following a complex workflow.
|
|
1657
|
+
|
|
1658
|
+
Most bootstrap arguments like `--jenkins-endpoint`, corresponding [configuration file](#configuration-files) option such as `jenkins_endpoint` is accepted, and environment variable `JENKINS_ENDPOINT` too.
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
## Bootstrap `init`
|
|
1662
|
+
|
|
1663
|
+
Initialize Ligoj with basic group management, containers, and companies hierarchy.
|
|
1664
|
+
|
|
1665
|
+
Sample Docker command:
|
|
1666
|
+
|
|
1667
|
+
```bash
|
|
1668
|
+
ligoj bootstrap init --base-dn="dc=sample,dc=com"
|
|
1669
|
+
```
|
|
1670
|
+
|
|
1671
|
+
*Note* `--base-dn` argument can also be defined as `ligoj_ldap_base_dn` in [configuration file](#configuration-files) and `LIGOJ_LDAP_BASE_DN` environment variable.
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
Hierarchy tree sample for base DN `dc=sample,dc=com`
|
|
1675
|
+
|
|
1676
|
+
|
|
1677
|
+
| DN LDAP | Scope name | Scope type |
|
|
1678
|
+
| ------------------------------------------------------------------------------------ | ------------ | ---------- |
|
|
1679
|
+
| `ou=people` | `Unassigned` | `company` |
|
|
1680
|
+
| ` ou=technical-users,ou=people` | `Technical` | `company` |
|
|
1681
|
+
| ` ou=external,ou=people` | `External` | `company` |
|
|
1682
|
+
| `ou=groups` | `Unassigned` | `group` |
|
|
1683
|
+
| ` ou=projects,ou=groups` | `Project` | `group` |
|
|
1684
|
+
| ` ou=tools,ou=groups` | `Technical` | `group` |
|
|
1685
|
+
| ` cn=jenkins-administrators,ou=tools,ou=groups` | (inherited) | `group` |
|
|
1686
|
+
| ` cn=nexus-administrators,ou=tools,ou=groups` | (inherited) | `group` |
|
|
1687
|
+
| ` cn=nexus-administrators-paris,cn=nexus-administrators,ou=tools,ou=groups` | (inherited) | `group` |
|
|
1688
|
+
| ` cn=nexus-administrators-paris-8,cn=nexus-administrators,ou=tools,ou=groups` | (inherited) | `group` |
|
|
1689
|
+
|
|
1690
|
+
|
|
1691
|
+
### Via `ligoj bootstrap init`
|
|
1692
|
+
|
|
1693
|
+
```bash
|
|
1694
|
+
ligoj bootstrap init --base-dn="dc=sample,dc=com" --users-base-dn "ou=people" --internal-users-base-dn "" --technical-users-base-dn "ou=technical-users" --external-users-base-dn "ou=external" --groups-base-dn "ou=groups" --technical-groups-base-dn "ou=tools" --projects-base-dn "ou=projects" --technical-groups "sonar-administrators" "jenkins-administrators" "nexus-administrators"
|
|
1695
|
+
```
|
|
1696
|
+
|
|
1697
|
+
### Via `ligoj id` commands
|
|
1698
|
+
|
|
1699
|
+
```bash
|
|
1700
|
+
## Users and companies
|
|
1701
|
+
|
|
1702
|
+
### OU LDAP intermediate
|
|
1703
|
+
ligoj id:ou create --name "people" --parent-dn "dc=sample,dc=com"
|
|
1704
|
+
ligoj id:ou create --name "external" --parent-dn "ou=people,dc=sample,dc=com"
|
|
1705
|
+
ligoj id:ou create --name "technical-users" --parent-dn "ou=people,dc=sample,dc=com"
|
|
1706
|
+
|
|
1707
|
+
### Companies
|
|
1708
|
+
ligoj id:scope create --name "Unassigned" --type "company" --dn "ou=people,dc=sample,dc=com"
|
|
1709
|
+
ligoj id:scope create --name "External" --type "company" --dn "ou=external,ou=people,dc=sample,dc=com"
|
|
1710
|
+
ligoj id:scope create --name "Technical" --type "company" --dn "ou=technical-users,ou=people,dc=sample,dc=com"
|
|
1711
|
+
|
|
1712
|
+
## Groups
|
|
1713
|
+
|
|
1714
|
+
### OU LDAP intermediate
|
|
1715
|
+
ligoj id:ou create --name "groups" --parent-dn "dc=sample,dc=com"
|
|
1716
|
+
ligoj id:ou create --name "projects" --parent-dn "ou=groups,dc=sample,dc=com"
|
|
1717
|
+
ligoj id:ou create --name "tools" --parent-dn "ou=groups,dc=sample,dc=com"
|
|
1718
|
+
|
|
1719
|
+
### Scope functionals for groups
|
|
1720
|
+
ligoj id:scope create --name "Unassigned" --type "group" --dn "ou=groups,dc=sample,dc=com"
|
|
1721
|
+
ligoj id:scope create --name "Project" --type "group" --dn "ou=projects,ou=groups,dc=sample,dc=com"
|
|
1722
|
+
ligoj id:scope create --name "Technical" --type "group" --dn "ou=tools,ou=groups,dc=sample,dc=com"
|
|
1723
|
+
|
|
1724
|
+
### Technical groups and sub-groups
|
|
1725
|
+
ligoj id:group create --name "jenkins-administrators" --scope "Technical"
|
|
1726
|
+
ligoj id:group create --name "nexus-administrators" --scope "Technical"
|
|
1727
|
+
ligoj id:group create --name "nexus-administrators-paris" --scope "Technical" --parent "nexus-administrators"
|
|
1728
|
+
ligoj id:group create --name "nexus-administrators-paris-8" --scope "Technical" --parent "nexus-administrators-paris"
|
|
1729
|
+
```
|
|
1730
|
+
|
|
1731
|
+
|
|
1732
|
+
## Bootstrap `welcome-user`
|
|
1733
|
+
|
|
1734
|
+
Configure a new project and its administrator.
|
|
1735
|
+
|
|
1736
|
+

|
|
1737
|
+
|
|
1738
|
+
```bash
|
|
1739
|
+
ligoj bootstrap welcome-user --id jdupont --project project1 --name "Project 1" --group-suffix="-team"
|
|
1740
|
+
```
|
|
1741
|
+
|
|
1742
|
+
Optionally, the project key can be validated with DNS within a defined DNS zone :
|
|
1743
|
+
|
|
1744
|
+
```bash
|
|
1745
|
+
ligoj bootstrap welcome-user --id jdupont --project project1 --name "PIProject 1" --verify-project-with-dns "PROJECT_KEY.holder.kloudy.io,PROJECT_KEY.holder2.kloudy.io" --group-suffix="-team"
|
|
1746
|
+
```
|
|
1747
|
+
|
|
1748
|
+
```json
|
|
1749
|
+
{
|
|
1750
|
+
"admin_user": "jdupont",
|
|
1751
|
+
"script_user": "project1-script",
|
|
1752
|
+
"script_api_key": "...",
|
|
1753
|
+
"reader_user": "project1-reader",
|
|
1754
|
+
"reader_password": "...",
|
|
1755
|
+
"project_key": "project1",
|
|
1756
|
+
"project_id": 6552
|
|
1757
|
+
}
|
|
1758
|
+
```
|
|
1759
|
+
|
|
1760
|
+
Optionally, Ligoj nodes such as Jenkins and SonarQube can be created during this step.
|
|
1761
|
+
|
|
1762
|
+
```bash
|
|
1763
|
+
ligoj bootstrap welcome-user --id jdupont --project project1 --name "Project 1" --verify-project-with-dns "PROJECT_KEY.holder.kloudy.io,PROJECT_KEY.holder2.kloudy.io" --group-suffix="-team" --jenkins-create-node --jenkins-endpoint http://localhost:8086 --jenkins-api-token="" --sonar-create-node --sonar-endpoint http://localhost:9000 --sonar-api-token="" --reset-reader-password
|
|
1764
|
+
```
|
|
1765
|
+
|
|
1766
|
+
*Notes*
|
|
1767
|
+
- `reader_password` result is provided only for new user and cannot be retrieved by Ligoj.
|
|
1768
|
+
- To generate another password, use the `--reset-reader-password` flag.
|
|
1769
|
+
- `reader_password` (or reset password) is used to create API tokens saved in Ligoj nodes
|
|
1770
|
+
- `--jenkins-api-token` and `--sonar-api-token` can be provided with this command but should be related to the `reader_user` or `--jenkins-api-user` value.
|
|
1771
|
+
- All endpoints and tokens are also sourced from [configuration file](#configuration-files) and environment variables.
|
|
1772
|
+
|
|
1773
|
+
## Bootstrap `create-project`
|
|
1774
|
+
|
|
1775
|
+
Create new groups within a new project related to another one.
|
|
1776
|
+
|
|
1777
|
+
Considering this use case :
|
|
1778
|
+
- Create a new project having `project-a` as key and `Project A` as name.
|
|
1779
|
+
- Team leader (administrator) will be `cli100.name@sample.com`. Actual username is resolved automatically from email.
|
|
1780
|
+
- Initial groups within this project are `admin`, `dev` and `test`.
|
|
1781
|
+
- The parent project's key (used as context) is `project1`. This project must be managed by the user: `ligoj-user`
|
|
1782
|
+
|
|
1783
|
+
The corresponding command is:
|
|
1784
|
+
|
|
1785
|
+
```bash
|
|
1786
|
+
ligoj bootstrap create-project --project project-a --name "Project A" --groups "admin" "dev" "test" \
|
|
1787
|
+
--parent-project "project1" \
|
|
1788
|
+
--parent-admin "ligoj-user" \
|
|
1789
|
+
--team-leader cli100.name@sample.com \
|
|
1790
|
+
```
|
|
1791
|
+
|
|
1792
|
+
*Note* When `parent-admin` is provided, this operation exploits the `run-as` feature of Ligoj to check the administrator of `parent-project`. In such a case, the session user must be a system administrator.
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
## Bootstrap `delete-project`
|
|
1796
|
+
|
|
1797
|
+
Delete a project including all groups, not only the references.
|
|
1798
|
+
|
|
1799
|
+
```bash
|
|
1800
|
+
ligoj bootstrap delete-project --project project-a --parent-admin "ligoj-user"
|
|
1801
|
+
```
|
|
1802
|
+
|
|
1803
|
+
*Note* When `parent-admin` is provided, this operation exploits the `run-as` feature of Ligoj to check the administrator of `parent-project`. In such a case, the session user must be a system administrator.
|
|
1804
|
+
|
|
1805
|
+
## Bootstrap create-roles
|
|
1806
|
+
|
|
1807
|
+
Create mapped roles in various tools
|
|
1808
|
+
|
|
1809
|
+
Supported services are:
|
|
1810
|
+
- Jenkins
|
|
1811
|
+
- SonarQube
|
|
1812
|
+
- Nexus
|
|
1813
|
+
- Alfresco
|
|
1814
|
+
- GitLab
|
|
1815
|
+
|
|
1816
|
+

|
|
1817
|
+
|
|
1818
|
+
|
|
1819
|
+
Created contents by tools
|
|
1820
|
+
|
|
1821
|
+
| Tool | Content type | Note |
|
|
1822
|
+
| --------------------------------- | ----------------------- | ----------------------------------------------------- |
|
|
1823
|
+
| [Jenkins](#jenkins) | Folder RBAC Permissions | See [CasC notes](#security-and-configuration-as-code) |
|
|
1824
|
+
| [Jenkins](#jenkins) | Global RBAC Permissions | See [CasC notes](#security-and-configuration-as-code) |
|
|
1825
|
+
| [Jenkins](#jenkins) | Folder credentials | See [supported credentials](#credentials) |
|
|
1826
|
+
| [Jenkins](#jenkins) | Global credentials | See [supported credentials](#credentials) |
|
|
1827
|
+
| [Jenkins](#jenkins) | Folders | Nested `folders` structure supported |
|
|
1828
|
+
| [SonarQube](#sonarqube) | Groups and RBAC | |
|
|
1829
|
+
| [SonarQube](#sonarqube) | Projects | |
|
|
1830
|
+
| [SonarQube](#sonarqube) | Templates | |
|
|
1831
|
+
| [GitLab](#gitLab) | Wrapper project Groups | |
|
|
1832
|
+
| [GitLab](#gitLab) | LDAP project Groups | |
|
|
1833
|
+
| [GitLab](#gitLab) | Project Groups | |
|
|
1834
|
+
| [Sonatype Nexus](#sonatype-nexus) | Roles | |
|
|
1835
|
+
| [Sonatype Nexus](#sonatype-nexus) | Repositories | |
|
|
1836
|
+
| [Alfresco](#alfresco) | Roles | |
|
|
1837
|
+
| [Alfresco](#alfresco) | Sites | |
|
|
1838
|
+
| [ArgoCD](#argocd) | Permissions | Optional `permission=deny` and `application` scope |
|
|
1839
|
+
| [ArgoCD](#argocd) | Projects | |
|
|
1840
|
+
| [Harbor](#harbor) | Projects | |
|
|
1841
|
+
| [Harbor](#harbor) | Projects members | |
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
Group and role configuration [JSON file conf.json](docs/bootstrap/create-roles.json).
|
|
1845
|
+
See [`--from`](#--from) for JSON loading options
|
|
1846
|
+
|
|
1847
|
+
```bash
|
|
1848
|
+
ligoj bootstrap create-roles --project project-a --from conf.json \
|
|
1849
|
+
--argocd-token="$ARGOCD_TOKEN" \
|
|
1850
|
+
--argocd-user="$ARGOCD_USER" \
|
|
1851
|
+
--alfresco-endpoint="$ALFRESCO_ENDPOINT" \
|
|
1852
|
+
--alfresco-user="$ALFRESCO_USER" \
|
|
1853
|
+
--alfresco-password="$ALFRESCO_PASSWORD" \
|
|
1854
|
+
--nexus-endpoint="$NEXUS_ENDPOINT" \
|
|
1855
|
+
--nexus-user="$NEXUS_USER" \
|
|
1856
|
+
--nexus-password="$NEXUS_PASSWORD" \
|
|
1857
|
+
--gitlab-endpoint="$GITLAB_ENDPOINT" \
|
|
1858
|
+
--gitlab-token="$GITLAB_TOKEN" \
|
|
1859
|
+
--jenkins-home="$JENKINS_HOME" \
|
|
1860
|
+
--jenkins-endpoint="$JENKINS_ENDPOINT" \
|
|
1861
|
+
--sonar-endpoint="$SONAR_ENDPOINT" \
|
|
1862
|
+
--sonar-api-token="$SONAR_API_KEY" \
|
|
1863
|
+
--harbor-endpoint="$HARBOR_ENDPOINT" \
|
|
1864
|
+
--harbor-user="$HARBOR_USER" \
|
|
1865
|
+
--harbor-password="$HARBOR_PASSWORD"
|
|
1866
|
+
```
|
|
1867
|
+
|
|
1868
|
+
```bash
|
|
1869
|
+
ligoj bootstrap create-roles --project project-a --from "https://path/to/conf.json"
|
|
1870
|
+
```
|
|
1871
|
+
|
|
1872
|
+
```bash
|
|
1873
|
+
ligoj bootstrap create-roles --project project-a --from '[{"text": "organizationalUnit","parameter": "service:id:ldap:companies-class"},...]'
|
|
1874
|
+
```
|
|
1875
|
+
|
|
1876
|
+
For detailed tool specific options, execute usage command:
|
|
1877
|
+
|
|
1878
|
+
```bash
|
|
1879
|
+
ligoj bootstrap create-roles --help
|
|
1880
|
+
```
|
|
1881
|
+
|
|
1882
|
+
```log
|
|
1883
|
+
usage: Ligoj CLI bootstrap create-roles [-h] [--project PROJECT] [--group-suffix GROUP_SUFFIX] [--groups [GROUPS ...]] [--from FROM]
|
|
1884
|
+
[--schema SCHEMA]
|
|
1885
|
+
[--alfresco-endpoint ALFRESCO_ENDPOINT] [--alfresco-user ALFRESCO_USER] [--alfresco-password ALFRESCO_PASSWORD]
|
|
1886
|
+
[--alfresco-ticket ALFRESCO_TICKET]
|
|
1887
|
+
[--gitlab-endpoint GITLAB_ENDPOINT] [--gitlab-token GITLAB_TOKEN] [--gitlab-base-group GITLAB_BASE_GROUP]
|
|
1888
|
+
[--gitlab-project-group-prefix GITLAB_PROJECT_GROUP_PREFIX] [--gitlab-project-subgroup-prefix GITLAB_PROJECT_SUBGROUP_PREFIX]
|
|
1889
|
+
[--jenkins-home JENKINS_HOME] [--jenkins-crumb JENKINS_CRUMB] [--jenkins-endpoint JENKINS_ENDPOINT]
|
|
1890
|
+
[--jenkins-api-user JENKINS_API_USER] [--jenkins-api-token JENKINS_API_TOKEN]
|
|
1891
|
+
...
|
|
1892
|
+
|
|
1893
|
+
options:
|
|
1894
|
+
-h, --help show this help message and exit
|
|
1895
|
+
--project PROJECT, -p PROJECT
|
|
1896
|
+
Associated project key
|
|
1897
|
+
...
|
|
1898
|
+
```
|
|
1899
|
+
|
|
1900
|
+
### `--includes` and `--excludes` options
|
|
1901
|
+
|
|
1902
|
+
Each supported tool can be included or excluded from the bootstrap commands:
|
|
1903
|
+
- By default, all discovered JSON's content is considered, no exclusion. Implicit `--includes "*"`.
|
|
1904
|
+
- Special value `*` means all.
|
|
1905
|
+
- Multiple `includes` and `excludes` values can be provided
|
|
1906
|
+
- The `excludes` option has higher priority than `includes`.
|
|
1907
|
+
- When the resolved endpoint is empty or null, the tool is ignored.
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
### Constraints
|
|
1911
|
+
|
|
1912
|
+
Checked constraints:
|
|
1913
|
+
- Referenced groups must be defined at root level. This constraint ensures a correct definition and avoids typos.
|
|
1914
|
+
- Empty permissions set are not allowed.
|
|
1915
|
+
- Given JSON must validate the [JSON Schema](https://json-schema.org/) [document schema.json](./schema.json).
|
|
1916
|
+
- [JSON Schema](https://json-schema.org/) can be merged with custom additions: `--schema "JSON Schema string, file or URL"`.
|
|
1917
|
+
|
|
1918
|
+
Sample constraint limiting Alfresco sites to `1`: `--schema='{"properties":{"alfresco":{"properties":{"sites":{"maxItems": 1}}}}}'`
|
|
1919
|
+
|
|
1920
|
+
### Jenkins
|
|
1921
|
+
|
|
1922
|
+
Supported resources are:
|
|
1923
|
+
- Nested folders
|
|
1924
|
+
- Credentials with or without values
|
|
1925
|
+
- Roles, group mapping and permissions, at folder or global level
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
#### Configuration
|
|
1929
|
+
|
|
1930
|
+
| Parameter | Environment variable | Note | Default |
|
|
1931
|
+
| --------------------- | -------------------- | ---------------------------------------------- | --------------- |
|
|
1932
|
+
| `--jenkins-endpoint` | `JENKINS_ENDPOINT` | HTTPS endpoint | Current Jenkins |
|
|
1933
|
+
| `--jenkins-api-user` | `JENKINS_API_USER` | Username | |
|
|
1934
|
+
| `--jenkins-api-token` | `JENKINS_API_TOKEN` | Token generated from `/user/_me_/configure` | |
|
|
1935
|
+
| | | Sourced from Jenkins credential `JENKINS_API`. | |
|
|
1936
|
+
| `--jenkins-home` | `JENKINS_HOME` | JENKINS home location for CasC update | |
|
|
1937
|
+
| `--jenkins-crumb` | `JENKINS_CRUMB` | Crumb protection enablement | `auto` |
|
|
1938
|
+
|
|
1939
|
+
#### Folders
|
|
1940
|
+
|
|
1941
|
+
- Recursive folders are supported; however, each folder must be unique. This is not an implementation limit, but it makes folder reorganization possible.
|
|
1942
|
+
- Folder maximal depth is `4`, but it is not a hard limit
|
|
1943
|
+
- Folder names are encoded, special chars are supported
|
|
1944
|
+
- Supported folder types are `com.cloudbees.hudson.plugins.folder.Folder` and `jenkins.branch.OrganizationFolder`. Folder mode update is not supported. Other folder modes *might* work, but have not been tested.
|
|
1945
|
+
- There is no [permission](https://www.jenkins.io/doc/book/security/access-control/permissions/#optional-permissions) limitation; internal identifiers must be used, such as `hudson.model.Item.Build`, `hudson.model.Hudson.Administer`, etc.:
|
|
1946
|
+
- [Overall permissions](https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/security/Permission.java)
|
|
1947
|
+
- [Run permissions](https://github.com/jenkinsci/jenkins/blob/3bc62eeae933c86f6a94c940fe6f35882f1e29d5/core/src/main/java/hudson/model/Run.java#LL2593C7-L2593C7)
|
|
1948
|
+
- [Item permissions](https://github.com/jenkinsci/jenkins/blob/3bc62eeae933c86f6a94c940fe6f35882f1e29d5/core/src/main/java/hudson/model/Item.java#L252)
|
|
1949
|
+
- [SCM permissions](https://github.com/jenkinsci/jenkins/blob/3bc62eeae933c86f6a94c940fe6f35882f1e29d5/core/src/main/java/hudson/scm/SCM.java#L761)
|
|
1950
|
+
- [Credential permissions](https://github.com/jenkinsci/credentials-plugin/blob/b96f366e7badeedaf69724991e44409be11a07b6/src/main/java/com/cloudbees/plugins/credentials/CredentialsProvider.java#L185)
|
|
1951
|
+
- The naming convention for permissions is the full class name, followed by the field ([Permission](https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/security/Permission.java)) name converted to Camel case, e.g., `hudson.model.View.Read`
|
|
1952
|
+
|
|
1953
|
+
#### Credentials
|
|
1954
|
+
|
|
1955
|
+
There is no limitation for credentials type, the supported configuration is:
|
|
1956
|
+
- Any parameter type but file
|
|
1957
|
+
- Tested types are:
|
|
1958
|
+
- `com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl`
|
|
1959
|
+
- `org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl`
|
|
1960
|
+
- `com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey`
|
|
1961
|
+
- Supported `scope` values are `global` and `system` (case insensitive). When not provided, the default behavior of this credential type is applied.
|
|
1962
|
+
- Attached domain is always `All domains`: `_`
|
|
1963
|
+
|
|
1964
|
+
|
|
1965
|
+
#### Security and Configuration as Code
|
|
1966
|
+
|
|
1967
|
+
Requires the installed, configured and assigned Jenkins plugin [Role-based Authorization Strategy](https://plugins.jenkins.io/role-strategy/).
|
|
1968
|
+
Underlying [role management API](https://javadoc.jenkins.io/plugin/role-strategy/com/michelin/cio/hudson/plugins/rolestrategy/RoleBasedAuthorizationStrategy.html) is executed.
|
|
1969
|
+
|
|
1970
|
+
CaC (Configuration as Code) [YAML file]($JENKINS_HOME/jenkins.yaml) management is supported:
|
|
1971
|
+
- CaC file location override support is `JENKINS_CASC_FILE` variable, then `CASC_JENKINS_CONFIG` variable, then `$JENKINS_HOME/jenkins.yaml` as default.
|
|
1972
|
+
- Only update mode is supported after all API calls, not creation
|
|
1973
|
+
- Both current and in-memory CaC files YAML structure must contain this path: `jenkins.authorizationStrategy.roleBased.roles`
|
|
1974
|
+
- Both current and in-memory CaC files YAML structure must contain this path: `jenkins.securityRealm.ldap.configurations`
|
|
1975
|
+
- The script must be able to write the backup file `$path_to_cac_file.ligoj`, which will be overwritten.
|
|
1976
|
+
- A unified diff is computed and printed for current and in-memory CaC files
|
|
1977
|
+
- Backup and update are executed only if there is at least one change detected in the computed unified diff
|
|
1978
|
+
- By default, the related sub-folder access is granted from the parent folder, and the related pattern is suffixed with the `(/.*)?` expression. Set `recursive` to `false` to block this behavior.
|
|
1979
|
+
- Roles use the folder identifier, case is insensitive
|
|
1980
|
+
|
|
1981
|
+
``` yml
|
|
1982
|
+
securityRealm:
|
|
1983
|
+
ldap:
|
|
1984
|
+
configurations:
|
|
1985
|
+
- displayNameAttributeName: "cn"
|
|
1986
|
+
groupMembershipStrategy:
|
|
1987
|
+
fromGroupSearch:
|
|
1988
|
+
filter: "(| (member={0}) (uniqueMember={0}) (memberUid={1}))"
|
|
1989
|
+
groupSearchBase: "ou=groups"
|
|
1990
|
+
groupSearchFilter: "(& (cn={0}) (| (objectClass=groupOfNames) (objectClass=groupOfUniqueNames)\
|
|
1991
|
+
\ (objectClass=posixGroup)))"
|
|
1992
|
+
inhibitInferRootDN: false
|
|
1993
|
+
managerDN: "cn=Manager,dc=sample,dc=com"
|
|
1994
|
+
managerPasswordSecret: "{...}"
|
|
1995
|
+
rootDN: "dc=sample,dc=com"
|
|
1996
|
+
server: "ldap://localhost:1389"
|
|
1997
|
+
userSearchBase: "ou=people"
|
|
1998
|
+
disableMailAddressResolver: false
|
|
1999
|
+
disableRolePrefixing: true
|
|
2000
|
+
groupIdStrategy: "caseInsensitive"
|
|
2001
|
+
userIdStrategy: "caseInsensitive"
|
|
2002
|
+
```
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
### SonarQube
|
|
2006
|
+
|
|
2007
|
+
Supported resources are:
|
|
2008
|
+
- Projects
|
|
2009
|
+
- Template
|
|
2010
|
+
- Roles, group mapping and permissions, at project or global level
|
|
2011
|
+
|
|
2012
|
+
|
|
2013
|
+
#### Configuration
|
|
2014
|
+
|
|
2015
|
+
| Parameter | Environment variable | Note |
|
|
2016
|
+
| ------------------- | -------------------- | ---------------------------------------------- |
|
|
2017
|
+
| `--sonar-endpoint` | `SONAR_ENDPOINT` | HTTPS endpoint |
|
|
2018
|
+
| | | Sourced from Jenkins build parameter. |
|
|
2019
|
+
| `--sonar-api-token` | `SONAR_API_TOKEN` | API key generated from `/account/security` API |
|
|
2020
|
+
| | | - Type is `User Token` |
|
|
2021
|
+
| | | - User rights : `System Administrator` |
|
|
2022
|
+
| | | Sourced from Jenkins credential `SONAR_API`. |
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
### Sonatype Nexus
|
|
2026
|
+
|
|
2027
|
+
Supported resources are:
|
|
2028
|
+
- Repository
|
|
2029
|
+
- Roles, group mapping and permissions, at repository level or global level
|
|
2030
|
+
|
|
2031
|
+
Repository configuration must follow the `[/#admin/system/api](http://localhost:8681/#admin/system/api)` of your Nexus instance of:
|
|
2032
|
+
- `POST /vi/repositories/docker/hosted`
|
|
2033
|
+
- `POST /vi/repositories/maven/hosted`
|
|
2034
|
+
- ...
|
|
2035
|
+
By default, repository mode is `hosted` and can be overridden with `mode` property.
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
#### Configuration
|
|
2039
|
+
|
|
2040
|
+
| Parameter | Environment variable | Note | Default |
|
|
2041
|
+
| ------------------ | -------------------- | -------------------------------------------- | ------- |
|
|
2042
|
+
| `--nexus-endpoint` | `NEXUS_ENDPOINT` | HTTPS endpoint | |
|
|
2043
|
+
| | | Sourced from Jenkins build parameter. | |
|
|
2044
|
+
| `--nexus-user` | `NEXUS_USER` | LDAP or internal user name | `admin` |
|
|
2045
|
+
| | | Sourced from Jenkins credential `NEXUS_API`. | |
|
|
2046
|
+
| `--nexus-password` | `NEXUS_PASSWORD` | LDAP or internal password | |
|
|
2047
|
+
| | | Sourced from Jenkins credential `NEXUS_API`. | |
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
### Harbor
|
|
2051
|
+
|
|
2052
|
+
Supported resources are:
|
|
2053
|
+
- Projects
|
|
2054
|
+
- Roles and group mapping, at project level
|
|
2055
|
+
|
|
2056
|
+
|
|
2057
|
+
#### Configuration
|
|
2058
|
+
|
|
2059
|
+
| Parameter | Environment variable | Note | Default |
|
|
2060
|
+
| ------------------- | -------------------- | --------------------------------------------- | ------- |
|
|
2061
|
+
| `--harbor-endpoint` | `HARBOR_ENDPOINT` | HTTPS endpoint | |
|
|
2062
|
+
| | | Sourced from Jenkins build parameter. | |
|
|
2063
|
+
| `--harbor-user` | `HARBOR_USER` | LDAP or internal user name | `admin` |
|
|
2064
|
+
| | | Sourced from Jenkins credential `HARBOR_API`. | |
|
|
2065
|
+
| `--harbor-password` | `HARBOR_PASSWORD` | LDAP or internal password | |
|
|
2066
|
+
| | | Sourced from Jenkins credential `HARBOR_API`. | |
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
### GitLab
|
|
2070
|
+
|
|
2071
|
+
No resources are supported, only roles. GitLab groups and sub-groups are created according to the given groups and naming guidelines.
|
|
2072
|
+
Real Git repository projects are not managed by this CLI.
|
|
2073
|
+
|
|
2074
|
+
#### Configuration
|
|
2075
|
+
|
|
2076
|
+
| Parameter | Environment variable | Note | Default |
|
|
2077
|
+
| ---------------------------------- | -------------------------------- | ------------------------------------------------------------------- | -------- |
|
|
2078
|
+
| `--gitlab-endpoint` | `GITLAB_ENDPOINT` | HTTPS endpoint | |
|
|
2079
|
+
| | | Sourced from Jenkins global `GITLAB_ENDPOINT` environment variable. | |
|
|
2080
|
+
| `--gitlab-token` | `GITLAB_TOKEN` | Access token with following constraints: | |
|
|
2081
|
+
| | | - Type: `Personal or Group Access Token` | |
|
|
2082
|
+
| | | - Scope is `${gitlab_base_group}` or root level | |
|
|
2083
|
+
| | | - Role: `owner` role | |
|
|
2084
|
+
| | | - Access level: `api` | |
|
|
2085
|
+
| | | Sourced from Jenkins credential `GITLAB_API`. | |
|
|
2086
|
+
| `--gitlab-base-group` | `GITLAB_BASE_GROUP` | Base group where created groups sit | `/` |
|
|
2087
|
+
| `--gitlab-wrapper-group` | `GITLAB_WRAPPER_GROUP` | Path of created wrapper group. Ignored if undefined | `ligoj` |
|
|
2088
|
+
| `--gitlab-wrapper-group-name` | `GITLAB_WRAPPER_GROUP_NAME` | Name of created wrapper group | |
|
|
2089
|
+
| `--gitlab_project_subgroup_prefix` | `GITLAB_PROJECT_SUBGROUP_PREFIX` | Path prefix of created groups. No wrapper if undefined | `ligoj-` |
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
#### Created hierarchy
|
|
2093
|
+
|
|
2094
|
+
Project hierarchy for a project `project1`:
|
|
2095
|
+
|
|
2096
|
+
| Gitlab path | Path pattern | Default |
|
|
2097
|
+
| -------------------------------------------------------------------- | ---------------------------------------------------------- | --------------- |
|
|
2098
|
+
| /base | `${gitlab_base_group}` | `/` |
|
|
2099
|
+
| |_ project1 | `${gitlab_project_group_prefix}${project_key}` | *No prefix* |
|
|
2100
|
+
| |— any-repo | *Git repository, not managed* | |
|
|
2101
|
+
| |— any-group | *User group, not managed* | |
|
|
2102
|
+
| |_ ligoj | `${gitlab_wrapper_group}` | `ligoj` |
|
|
2103
|
+
| |_ ligoj-project1-dev | `${gitlab-project-subgroup-prefix}${project_key}-${group}` | Prefix `ligoj-` |
|
|
2104
|
+
|
|
2105
|
+
Sub-groups are created with `project_creation_level` flag set to `noone` and with a specific avatar. See [GitLab API create-a-subgroup](https://docs.gitlab.com/ee/api/groups.html#create-a-subgroup)
|
|
2106
|
+
|
|
2107
|
+
|
|
2108
|
+
### ArgoCD
|
|
2109
|
+
|
|
2110
|
+
Supported resources are:
|
|
2111
|
+
- Projects
|
|
2112
|
+
- Roles and permissions, at project level only
|
|
2113
|
+
- `action: [delete, get]`
|
|
2114
|
+
- `permission: [allow,deny]`, by default `allow`
|
|
2115
|
+
- `application:`, by default `*`
|
|
2116
|
+
|
|
2117
|
+
Sample JSON part:
|
|
2118
|
+
|
|
2119
|
+
```json
|
|
2120
|
+
{
|
|
2121
|
+
"projects": [
|
|
2122
|
+
{
|
|
2123
|
+
"name": "project1",
|
|
2124
|
+
"description": "Project description",
|
|
2125
|
+
"roles": {
|
|
2126
|
+
"dev": {
|
|
2127
|
+
"permissions": [
|
|
2128
|
+
{
|
|
2129
|
+
"action": "get"
|
|
2130
|
+
},
|
|
2131
|
+
{
|
|
2132
|
+
"action": "delete",
|
|
2133
|
+
"application": "app1",
|
|
2134
|
+
"permission": "deny"
|
|
2135
|
+
}
|
|
2136
|
+
]
|
|
2137
|
+
},
|
|
2138
|
+
"test": {
|
|
2139
|
+
"permissions": [
|
|
2140
|
+
{
|
|
2141
|
+
"action": "get"
|
|
2142
|
+
}
|
|
2143
|
+
]
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
]
|
|
2148
|
+
}
|
|
2149
|
+
```
|
|
2150
|
+
|
|
2151
|
+
#### Configuration
|
|
2152
|
+
|
|
2153
|
+
| Parameter | Environment variable | Note |
|
|
2154
|
+
| ------------------- | -------------------- | -------------------------------------------------------- |
|
|
2155
|
+
| `--argocd-endpoint` | `ARGOCD_ENDPOINT` | HTTPS endpoint. |
|
|
2156
|
+
| | | Sourced from Jenkins build parameter. |
|
|
2157
|
+
| `--argocd-user` | `ARGOCD_USER` | Username. Not recommended, see `ARGOCD_TICKET` |
|
|
2158
|
+
| `--argocd-password` | `ARGOCD_PASSWORD` | Password. Not recommended, see `ARGOCD_TICKET` |
|
|
2159
|
+
| `--argocd-ticket` | `ARGOCD_TICKET` | Ticket generated by `/alfresco/s/api/login` API |
|
|
2160
|
+
| | | Generated automatically if `ARGOCD_PASSWORD` is provided |
|
|
2161
|
+
| | | Sourced from Jenkins credential `ARGOCD_API`. |
|
|
2162
|
+
|
|
2163
|
+
|
|
2164
|
+
### Alfresco
|
|
2165
|
+
|
|
2166
|
+
Supported resources are:
|
|
2167
|
+
- Sites
|
|
2168
|
+
- Roles and permissions, at site level only
|
|
2169
|
+
|
|
2170
|
+
```bash
|
|
2171
|
+
ligoj bootstrap create-roles --schema='{
|
|
2172
|
+
"properties": {
|
|
2173
|
+
"groups": {
|
|
2174
|
+
"items": {
|
|
2175
|
+
"enum": [
|
|
2176
|
+
"dev",
|
|
2177
|
+
"admin",
|
|
2178
|
+
"test",
|
|
2179
|
+
"securite"
|
|
2180
|
+
]
|
|
2181
|
+
}
|
|
2182
|
+
},
|
|
2183
|
+
"alfresco": {
|
|
2184
|
+
"properties": {
|
|
2185
|
+
"sites": {
|
|
2186
|
+
"maxItems": 1
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
}' --project "project1" --group-suffix="-team" --from="conf/sample.conf.alfresco.json"
|
|
2192
|
+
```
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
#### Configuration
|
|
2196
|
+
|
|
2197
|
+
| Parameter | Environment variable | Note |
|
|
2198
|
+
| --------------------- | -------------------- | --------------------------------------------------------------------- |
|
|
2199
|
+
| `--alfresco-endpoint` | `ALFRESCO_ENDPOINT` | HTTPS endpoint. |
|
|
2200
|
+
| | | Sourced from Jenkins global `ALFRESCO_ENDPOINT` environment variable. |
|
|
2201
|
+
| `--alfresco-user` | `ALFRESCO_USER` | Username. Not recommended, see `ALFRESCO_TICKET` |
|
|
2202
|
+
| `--alfresco-password` | `ALFRESCO_PASSWORD` | Password. Not recommended, see `ALFRESCO_TICKET` |
|
|
2203
|
+
| `--alfresco-ticket` | `ALFRESCO_TICKET` | Ticket generated by `/alfresco/s/api/login` API |
|
|
2204
|
+
| | | Generated automatically if `ALFRESCO_PASSWORD` is provided |
|
|
2205
|
+
| | | Sourced from Jenkins credential `ALFRESCO_API`. |
|
|
2206
|
+
|
|
2207
|
+
Alfresco ticket generation by API:
|
|
2208
|
+
- either from Swagger API explorer `/?urls.primaryName=Authentication%20API#/authentication/createTicket`,
|
|
2209
|
+
- either with cURL command:
|
|
2210
|
+
```bash
|
|
2211
|
+
curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"admin"}' "https://alfresco.sample.com/alfresco/s/api/login"
|
|
2212
|
+
```
|
|
2213
|
+
|
|
2214
|
+
## Bootstrap delete-roles
|
|
2215
|
+
|
|
2216
|
+
Delete mapped roles from various tools symmetrically as [`create-roles` operation](#bootstrap-create-roles).
|
|
2217
|
+
|
|
2218
|
+

|
|
2219
|
+
|
|
2220
|
+
|
|
2221
|
+
See [`--from`](#--from) for JSON loading options
|
|
2222
|
+
|
|
2223
|
+
By default, only roles are deleted; to perform a full cleanup, see the [--with-data option](#--with-data)
|
|
2224
|
+
|
|
2225
|
+
```bash
|
|
2226
|
+
ligoj bootstrap delete-roles --project project-a --from conf.json \
|
|
2227
|
+
--with-data "jenkins" "sonar" \
|
|
2228
|
+
--argocd-token="$ARGOCD_TOKEN" \
|
|
2229
|
+
--argocd-user="$ARGOCD_USER" \
|
|
2230
|
+
--alfresco-endpoint="$ALFRESCO_ENDPOINT" \
|
|
2231
|
+
--alfresco-user="$ALFRESCO_USER" \
|
|
2232
|
+
--alfresco-password="$ALFRESCO_PASSWORD" \
|
|
2233
|
+
--nexus-endpoint="$NEXUS_ENDPOINT" \
|
|
2234
|
+
--nexus-user="$NEXUS_USER" \
|
|
2235
|
+
--nexus-password="$NEXUS_PASSWORD" \
|
|
2236
|
+
--gitlab-endpoint="$GITLAB_ENDPOINT" \
|
|
2237
|
+
--gitlab-token="$GITLAB_TOKEN" \
|
|
2238
|
+
--jenkins-home="$JENKINS_HOME" \
|
|
2239
|
+
--jenkins-endpoint="$JENKINS_ENDPOINT" \
|
|
2240
|
+
--sonar-endpoint="$SONAR_ENDPOINT" \
|
|
2241
|
+
--sonar-api-token="$SONAR_API_KEY" \
|
|
2242
|
+
```
|
|
2243
|
+
|
|
2244
|
+
Deleted contents by tools
|
|
2245
|
+
|
|
2246
|
+
| Tool | Content type | Deletion mode | Only `with-data` |
|
|
2247
|
+
| -------------- | ----------------------- | ------------- | ---------------- |
|
|
2248
|
+
| Jenkins | Folder RBAC Permissions | One by one | |
|
|
2249
|
+
| Jenkins | Global RBAC Permissions | One by one | |
|
|
2250
|
+
| Jenkins | Folder credentials | One by one | ✅ |
|
|
2251
|
+
| Jenkins | Global credentials | One by one | ✅ |
|
|
2252
|
+
| Jenkins | Folders | One by one | ✅ |
|
|
2253
|
+
| SonarQube | Groups and RBAC | One by one | |
|
|
2254
|
+
| SonarQube | Projects | One by one | ✅ |
|
|
2255
|
+
| SonarQube | Templates | One by one | ✅ |
|
|
2256
|
+
| GitLab | Wrapper project Groups | Cascade | |
|
|
2257
|
+
| GitLab | LDAP project Groups | One by one | |
|
|
2258
|
+
| GitLab | Project Groups | One by one | ✅ |
|
|
2259
|
+
| Sonatype Nexus | Roles | Cascade | |
|
|
2260
|
+
| Sonatype Nexus | Repositories | One by one | ✅ |
|
|
2261
|
+
| Alfresco | Roles | Cascade | |
|
|
2262
|
+
| Alfresco | Sites | One by one | ✅ |
|
|
2263
|
+
| ArgoCD | Permissions | One by one | |
|
|
2264
|
+
| ArgoCD | Projects | One by one | ✅ |
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
### `--with-data`
|
|
2268
|
+
|
|
2269
|
+
Each supported tool can be included (by default) or excluded, as described in [`create-roles` includes/excludes option documentation](#--includes-and---excludes-options). For excluded tools, no role and no data are deleted.
|
|
2270
|
+
|
|
2271
|
+
By default, only roles are deleted. To symmetrically delete the created contents, `--with-data` must be set to `*` or a specific list of plugins.
|
|
2272
|
+
In this case, all discovered JSON content is considered for deletion, including Jenkins folders, Nexus repositories, etc.
|
|
2273
|
+
- By default, no data is deleted
|
|
2274
|
+
- When `--with-data` is set to `*`, all discovered JSON's content for included plugins is considered
|
|
2275
|
+
- When `--with-data` is set to `plugin1 plugin2`, only these plugins are considered for data deletion, only if these plugins are included
|
|
2276
|
+
|
|
2277
|
+
## Bootstrap roundtrip
|
|
2278
|
+
|
|
2279
|
+
The purpose of this documentation is only for troubleshooting and understanding the full behavior of bootstrap operations:
|
|
2280
|
+
- [Bootstrap init](#bootstrap-init) : initial IDP (LDAP, ...), administrative setup. Only executed once.
|
|
2281
|
+
- [Bootstrap welcome-user](#bootstrap-welcome-user): initial administration user. Each administrator can execute their own base configuration.
|
|
2282
|
+
- [Bootstrap create-project](#bootstrap-create-project): create a new project in Ligoj and the linked IDP
|
|
2283
|
+
- [Bootstrap create-roles](#bootstrap-create-roles): permissions, role mapping and containers creation for an existing project
|
|
2284
|
+
- [Bootstrap delete-roles](#bootstrap-delete-roles): permissions, role mapping and containers deletion from a project
|
|
2285
|
+
- [Bootstrap delete-project](#bootstrap-delete-project): delete a project from Ligoj and linked IDP
|
|
2286
|
+
|
|
2287
|
+
Commands from zero to zero:
|
|
2288
|
+
|
|
2289
|
+
```bash
|
|
2290
|
+
ligoj -V bootstrap init --base-dn="dc=sample,dc=com"
|
|
2291
|
+
ligoj -V bootstrap welcome-user --id "jdupont" --project "pic-master" --name "PIC Master" --script-custom-attributes '{"uidFonctionnel":"pic-master-script"}' --reader-custom-attributes '{"uidFonctionnel":"pic-master-reader"}' --jenkins-create-node --sonar-create-node --reset-reader-password
|
|
2292
|
+
ligoj -V bootstrap create-project --project "project-module1" --name "ProjetNew" --groups "dev" "admin" --parent-project "pic-master" --parent-admin "jdupont" --team-leader jdupont
|
|
2293
|
+
ligoj -V bootstrap create-roles --project "project-module1" --from "conf/ligoj/sample.conf.json" --excludes gitlab alfresco argocd
|
|
2294
|
+
ligoj -V bootstrap create-roles --project "project-module1" --from "conf/ligoj/sample.conf.json" --excludes gitlab
|
|
2295
|
+
ligoj -V bootstrap delete-roles --project "project-module1" --from "conf/ligoj/sample.conf.json" --excludes gitlab
|
|
2296
|
+
ligoj -V project delete --id "project-module1" --parent-admin "jdupont" --with-data '*'
|
|
2297
|
+
ligoj -V project delete --id "pic-master" --with-data '*'
|
|
2298
|
+
```
|
|
2299
|
+
|
|
2300
|
+
# Ligoj SSL Certificates
|
|
2301
|
+
|
|
2302
|
+
This section covers the case of running Ligoj with interaction with HTTPS services using self-signed certificates or issued by internal Certificate Authorities.
|
|
2303
|
+
|
|
2304
|
+
For each HTTPS website, run the following command. It requires `keytool` to be available on the host.
|
|
2305
|
+
|
|
2306
|
+
```bash
|
|
2307
|
+
python plugins/ssl.py keycloack.sample.com 443 ./ligoj.jks changeit
|
|
2308
|
+
```
|
|
2309
|
+
|
|
2310
|
+
When successive calls are done, the target TrustStore JKS file contains all aggregated certificates and can be provided to `ligoj-ui` and/or `ligoj-api` containers.
|
|
2311
|
+
|
|
2312
|
+
```bash
|
|
2313
|
+
# Copy the TrustStore file in the mounted Ligoj home directory
|
|
2314
|
+
cp ./ligoj.jks /var/lib/instance_datas/ligoj/
|
|
2315
|
+
|
|
2316
|
+
# Start the container with the TrustStore reference
|
|
2317
|
+
docker run -e CUSTOM_OPTS='-Djavax.net.ssl.trustStore=/home/ligoj/ligoj.jks' \
|
|
2318
|
+
```
|
|
2319
|
+
|
|
2320
|
+
|
|
2321
|
+
# Development mode installation
|
|
2322
|
+
|
|
2323
|
+
This procedure is only for development where Ligoj CLI package is installed in *editable*.
|
|
2324
|
+
|
|
2325
|
+
```bash
|
|
2326
|
+
echo '
|
|
2327
|
+
export PYENV_ROOT="$HOME/.pyenv"
|
|
2328
|
+
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
|
|
2329
|
+
eval "$(pyenv init -)"' >> ~/.bashrc
|
|
2330
|
+
source ~/.bashrc
|
|
2331
|
+
brew install pyenv-virtualenv 3.11 ligoj # See https://github.com/pyenv/pyenv-virtualenv
|
|
2332
|
+
pyenv install 3.11
|
|
2333
|
+
pyenv virtualenv 3.11 ligoj
|
|
2334
|
+
pyenv activate ligoj
|
|
2335
|
+
|
|
2336
|
+
# Proxy configuration
|
|
2337
|
+
export PYTHON_OPTS=' --proxy="10.154.154.154:3128"'
|
|
2338
|
+
export http_proxy="http://10.154.154.154:3128"
|
|
2339
|
+
export https_proxy="http://10.154.154.154:3128"
|
|
2340
|
+
export NO_PROXY="localhost,*.rie.gouv.fr,127.0.0.1,0.0.0.0,ligoj.$TENANT"
|
|
2341
|
+
|
|
2342
|
+
pip install --upgrade pip
|
|
2343
|
+
pip install -U --root-user-action=ignore pip -e .
|
|
2344
|
+
|
|
2345
|
+
# Build
|
|
2346
|
+
python -m pip install --upgrade build
|
|
2347
|
+
python -m build
|
|
2348
|
+
ruff check . --fix
|
|
2349
|
+
flake8 .
|
|
2350
|
+
```
|