mreg-cli 1.12.0__tar.gz → 1.12.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/CHANGELOG.md +16 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/PKG-INFO +2 -2
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/ci/testsuite-result.json +73 -73
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/_version.py +3 -3
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/cli.py +2 -2
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/client.py +6 -13
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/exceptions.py +20 -16
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/main.py +2 -8
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/utilities/api.py +2 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/PKG-INFO +2 -2
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/requires.txt +1 -1
- mreg_cli-1.12.2/mreg_cli.egg-info/scm_version.json +8 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/pyproject.toml +1 -1
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_exceptions.py +93 -16
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/uv.lock +4 -4
- mreg_cli-1.12.0/mreg_cli.egg-info/scm_version.json +0 -8
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/.github/workflows/publish.yml +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/.github/workflows/test.yml +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/.gitignore +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/.markdownlint.json +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/AUTHORS +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/CLAUDE.md +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/CONTRIBUTING +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/LICENSE +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/README.md +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/ci/Dockerfile +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/ci/diff.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/ci/docker-compose.yml +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/ci/run_testsuite_and_record_V2.sh +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/ci/testsuite +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/data/mreg-cli.conf +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/__about__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/__main__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/choices.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/base.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/cache.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/dhcp.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/group.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/help.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host_submodules/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host_submodules/a_aaaa.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host_submodules/bacnet.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host_submodules/cname.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host_submodules/core.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/host_submodules/rr.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/label.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/logging.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/network.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/permission.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/policy.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/recording.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/registry.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/root.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/commands/zone.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/config.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/dirs.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/errorbuilder.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/help_formatter.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/log.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/base.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/cache.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/group.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/history.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/host.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/meta.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/network.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/policy.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/output/zone.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/outputmanager.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/prompt.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/py.typed +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/tags.txt +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/tokenfile.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/types.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/utilities/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/utilities/fs.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/utilities/shared.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli/utilities/validators.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/SOURCES.txt +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/dependency_links.txt +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/entry_points.txt +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/scm_file_list.json +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/mreg_cli.egg-info/top_level.txt +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/run.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/setup.cfg +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/api/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/api/test_client.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/commands/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/commands/test_host.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/commands/test_network.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/commands/test_rr.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/conftest.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_config.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_errorbuilder.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_log.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_outputmanager.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_prompt.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_tokenfile.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/test_types.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/utilities/__init__.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/utilities/test_fs.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tests/utils.py +0 -0
- {mreg_cli-1.12.0 → mreg_cli-1.12.2}/tox.ini +0 -0
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
<!-- ## Unreleased -->
|
|
9
9
|
|
|
10
|
+
## [1.12.2](https://github.com/unioslo/mreg-cli/releases/tag/1.12.2) - 2026-10-16
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Updated `mreg-api` dependency to 0.8.0.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Commands that resolve hosts and networks throwing generic "not found" error instead of prompting for re-login on expired token.
|
|
19
|
+
|
|
20
|
+
## [1.12.1](https://github.com/unioslo/mreg-cli/releases/tag/1.12.1) - 2026-10-08
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Updated `mreg-api` dependency to 0.6.1. This removes some custom error handling code for M2M errors (hostgroups->owners,hosts; roles->atoms,hosts) and instead uses the server's own error messages.
|
|
25
|
+
|
|
10
26
|
## [1.12.0](https://github.com/unioslo/mreg-cli/releases/tag/1.12.0) - 2026-10-05
|
|
11
27
|
|
|
12
28
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mreg-cli
|
|
3
|
-
Version: 1.12.
|
|
3
|
+
Version: 1.12.2
|
|
4
4
|
Summary: MREG interactive command line client
|
|
5
5
|
Author: Others (see AUTHORS)
|
|
6
6
|
Author-email: Øyvind Kolbu <oyvind.kolbu@usit.uio.no>, Safet A <amedov@usit.uio.no>, Magnus Hirth <mhmorgan42@gmail.com>, Nico <nicolaydmohebi@gmail.com>, Marius Bakke <marius.bakke@usit.uio.no>, Fredrik Larsen <fredrik.larsen@usit.uio.no>, Paal Braathen <paal.braathen@usit.uio.no>, Nils Hiorth <nils@nls.me>, Dmytro Karpenko <dmytrok@usit.uio.no>
|
|
@@ -26,7 +26,7 @@ Requires-Dist: pydantic-extra-types>=2.1.0
|
|
|
26
26
|
Requires-Dist: platformdirs>=4.3.0
|
|
27
27
|
Requires-Dist: pydantic-settings>=2.10.1
|
|
28
28
|
Requires-Dist: rich>=13.9.4
|
|
29
|
-
Requires-Dist: mreg-api<0.
|
|
29
|
+
Requires-Dist: mreg-api<0.9.0,>=0.8.0
|
|
30
30
|
Dynamic: license-file
|
|
31
31
|
|
|
32
32
|
# MREG CLI [](https://github.com/unioslo/mreg-cli/actions/workflows/test.yml)
|
|
@@ -9898,10 +9898,10 @@
|
|
|
9898
9898
|
"command_filter_negate": false,
|
|
9899
9899
|
"command_issued": "host add somehost -ip 10.0.1.20 -contact support@example.org -force # should fail because ip is in excluded range",
|
|
9900
9900
|
"ok": [],
|
|
9901
|
-
"warning": [
|
|
9901
|
+
"warning": [],
|
|
9902
|
+
"error": [
|
|
9902
9903
|
"400 Bad Request: POST http://127.0.0.1:8000/api/v1/hosts/\n1 error:\n non_field_errors: IP 10.0.1.20 in an excluded range: 10.0.1.0/24 -> [10.0.1.20 -> [10.0.1.30] (invalid)"
|
|
9903
9904
|
],
|
|
9904
|
-
"error": [],
|
|
9905
9905
|
"output": [],
|
|
9906
9906
|
"api_requests": [
|
|
9907
9907
|
{
|
|
@@ -9945,18 +9945,18 @@
|
|
|
9945
9945
|
"zone": {
|
|
9946
9946
|
"nameservers": [
|
|
9947
9947
|
{
|
|
9948
|
-
"created_at": "2026-
|
|
9949
|
-
"updated_at": "2026-
|
|
9948
|
+
"created_at": "2026-10-16T12:53:57.454405+02:00",
|
|
9949
|
+
"updated_at": "2026-10-16T12:53:57.454474+02:00",
|
|
9950
9950
|
"name": "ns2.example.org",
|
|
9951
9951
|
"ttl": null
|
|
9952
9952
|
}
|
|
9953
9953
|
],
|
|
9954
|
-
"created_at": "2026-
|
|
9955
|
-
"updated_at": "2026-
|
|
9954
|
+
"created_at": "2026-10-16T12:53:57.061219+02:00",
|
|
9955
|
+
"updated_at": "2026-10-16T12:54:02.548724+02:00",
|
|
9956
9956
|
"updated": true,
|
|
9957
9957
|
"primary_ns": "ns2.example.org",
|
|
9958
9958
|
"email": "hostperson@example.org",
|
|
9959
|
-
"serialno_updated_at": "2026-
|
|
9959
|
+
"serialno_updated_at": "2026-10-16T12:53:57.561895+02:00",
|
|
9960
9960
|
"refresh": 360,
|
|
9961
9961
|
"retry": 1800,
|
|
9962
9962
|
"expire": 2400,
|
|
@@ -9974,8 +9974,8 @@
|
|
|
9974
9974
|
"response": {
|
|
9975
9975
|
"excluded_ranges": [
|
|
9976
9976
|
{
|
|
9977
|
-
"created_at": "2026-
|
|
9978
|
-
"updated_at": "2026-
|
|
9977
|
+
"created_at": "2026-10-16T12:54:03.158958+02:00",
|
|
9978
|
+
"updated_at": "2026-10-16T12:54:03.159059+02:00",
|
|
9979
9979
|
"start_ip": "10.0.1.20",
|
|
9980
9980
|
"end_ip": "10.0.1.30",
|
|
9981
9981
|
"network": 3
|
|
@@ -9983,8 +9983,8 @@
|
|
|
9983
9983
|
],
|
|
9984
9984
|
"policy": null,
|
|
9985
9985
|
"communities": [],
|
|
9986
|
-
"created_at": "2026-
|
|
9987
|
-
"updated_at": "2026-
|
|
9986
|
+
"created_at": "2026-10-16T12:54:02.849972+02:00",
|
|
9987
|
+
"updated_at": "2026-10-16T12:54:02.949770+02:00",
|
|
9988
9988
|
"network": "10.0.1.0/24",
|
|
9989
9989
|
"description": "Frozzzen",
|
|
9990
9990
|
"vlan": null,
|
|
@@ -11176,10 +11176,10 @@
|
|
|
11176
11176
|
"command_filter_negate": false,
|
|
11177
11177
|
"command_issued": "host add otherhost -ip 10.0.1.20 -contact support@example.org # fails because reserved range",
|
|
11178
11178
|
"ok": [],
|
|
11179
|
-
"warning": [
|
|
11179
|
+
"warning": [],
|
|
11180
|
+
"error": [
|
|
11180
11181
|
"400 Bad Request: POST http://127.0.0.1:8000/api/v1/hosts/\n1 error:\n non_field_errors: IP 10.0.1.20 in an excluded range: 10.0.1.0/24 -> [10.0.1.20 -> [10.0.1.30] (invalid)"
|
|
11181
11182
|
],
|
|
11182
|
-
"error": [],
|
|
11183
11183
|
"output": [],
|
|
11184
11184
|
"api_requests": [
|
|
11185
11185
|
{
|
|
@@ -11223,18 +11223,18 @@
|
|
|
11223
11223
|
"zone": {
|
|
11224
11224
|
"nameservers": [
|
|
11225
11225
|
{
|
|
11226
|
-
"created_at": "2026-
|
|
11227
|
-
"updated_at": "2026-
|
|
11226
|
+
"created_at": "2026-10-16T12:53:57.454405+02:00",
|
|
11227
|
+
"updated_at": "2026-10-16T12:53:57.454474+02:00",
|
|
11228
11228
|
"name": "ns2.example.org",
|
|
11229
11229
|
"ttl": null
|
|
11230
11230
|
}
|
|
11231
11231
|
],
|
|
11232
|
-
"created_at": "2026-
|
|
11233
|
-
"updated_at": "2026-
|
|
11232
|
+
"created_at": "2026-10-16T12:53:57.061219+02:00",
|
|
11233
|
+
"updated_at": "2026-10-16T12:54:06.763646+02:00",
|
|
11234
11234
|
"updated": true,
|
|
11235
11235
|
"primary_ns": "ns2.example.org",
|
|
11236
11236
|
"email": "hostperson@example.org",
|
|
11237
|
-
"serialno_updated_at": "2026-
|
|
11237
|
+
"serialno_updated_at": "2026-10-16T12:53:57.561895+02:00",
|
|
11238
11238
|
"refresh": 360,
|
|
11239
11239
|
"retry": 1800,
|
|
11240
11240
|
"expire": 2400,
|
|
@@ -11252,8 +11252,8 @@
|
|
|
11252
11252
|
"response": {
|
|
11253
11253
|
"excluded_ranges": [
|
|
11254
11254
|
{
|
|
11255
|
-
"created_at": "2026-
|
|
11256
|
-
"updated_at": "2026-
|
|
11255
|
+
"created_at": "2026-10-16T12:54:03.158958+02:00",
|
|
11256
|
+
"updated_at": "2026-10-16T12:54:03.159059+02:00",
|
|
11257
11257
|
"start_ip": "10.0.1.20",
|
|
11258
11258
|
"end_ip": "10.0.1.30",
|
|
11259
11259
|
"network": 3
|
|
@@ -11261,8 +11261,8 @@
|
|
|
11261
11261
|
],
|
|
11262
11262
|
"policy": null,
|
|
11263
11263
|
"communities": [],
|
|
11264
|
-
"created_at": "2026-
|
|
11265
|
-
"updated_at": "2026-
|
|
11264
|
+
"created_at": "2026-10-16T12:54:02.849972+02:00",
|
|
11265
|
+
"updated_at": "2026-10-16T12:54:06.888787+02:00",
|
|
11266
11266
|
"network": "10.0.1.0/24",
|
|
11267
11267
|
"description": "Frozen but has one host",
|
|
11268
11268
|
"vlan": 1234,
|
|
@@ -11862,10 +11862,10 @@
|
|
|
11862
11862
|
"command_filter_negate": false,
|
|
11863
11863
|
"command_issued": "host add somehost -ip 2001:db8::20 -contact support@example.org -force # should fail, because the address is in a reserved range",
|
|
11864
11864
|
"ok": [],
|
|
11865
|
-
"warning": [
|
|
11865
|
+
"warning": [],
|
|
11866
|
+
"error": [
|
|
11866
11867
|
"400 Bad Request: POST http://127.0.0.1:8000/api/v1/hosts/\n1 error:\n non_field_errors: IP 2001:db8::20 in an excluded range: 2001:db8::/64 -> [2001:db8::20 -> [2001:db8::30] (invalid)"
|
|
11867
11868
|
],
|
|
11868
|
-
"error": [],
|
|
11869
11869
|
"output": [],
|
|
11870
11870
|
"api_requests": [
|
|
11871
11871
|
{
|
|
@@ -11909,18 +11909,18 @@
|
|
|
11909
11909
|
"zone": {
|
|
11910
11910
|
"nameservers": [
|
|
11911
11911
|
{
|
|
11912
|
-
"created_at": "2026-
|
|
11913
|
-
"updated_at": "2026-
|
|
11912
|
+
"created_at": "2026-10-16T12:53:57.454405+02:00",
|
|
11913
|
+
"updated_at": "2026-10-16T12:53:57.454474+02:00",
|
|
11914
11914
|
"name": "ns2.example.org",
|
|
11915
11915
|
"ttl": null
|
|
11916
11916
|
}
|
|
11917
11917
|
],
|
|
11918
|
-
"created_at": "2026-
|
|
11919
|
-
"updated_at": "2026-
|
|
11918
|
+
"created_at": "2026-10-16T12:53:57.061219+02:00",
|
|
11919
|
+
"updated_at": "2026-10-16T12:54:08.066493+02:00",
|
|
11920
11920
|
"updated": true,
|
|
11921
11921
|
"primary_ns": "ns2.example.org",
|
|
11922
11922
|
"email": "hostperson@example.org",
|
|
11923
|
-
"serialno_updated_at": "2026-
|
|
11923
|
+
"serialno_updated_at": "2026-10-16T12:53:57.561895+02:00",
|
|
11924
11924
|
"refresh": 360,
|
|
11925
11925
|
"retry": 1800,
|
|
11926
11926
|
"expire": 2400,
|
|
@@ -11938,8 +11938,8 @@
|
|
|
11938
11938
|
"response": {
|
|
11939
11939
|
"excluded_ranges": [
|
|
11940
11940
|
{
|
|
11941
|
-
"created_at": "2026-
|
|
11942
|
-
"updated_at": "2026-
|
|
11941
|
+
"created_at": "2026-10-16T12:54:08.538757+02:00",
|
|
11942
|
+
"updated_at": "2026-10-16T12:54:08.538830+02:00",
|
|
11943
11943
|
"start_ip": "2001:db8::20",
|
|
11944
11944
|
"end_ip": "2001:db8::30",
|
|
11945
11945
|
"network": 4
|
|
@@ -11947,8 +11947,8 @@
|
|
|
11947
11947
|
],
|
|
11948
11948
|
"policy": null,
|
|
11949
11949
|
"communities": [],
|
|
11950
|
-
"created_at": "2026-
|
|
11951
|
-
"updated_at": "2026-
|
|
11950
|
+
"created_at": "2026-10-16T12:54:08.253602+02:00",
|
|
11951
|
+
"updated_at": "2026-10-16T12:54:08.349296+02:00",
|
|
11952
11952
|
"network": "2001:db8::/64",
|
|
11953
11953
|
"description": "Lorem ipsum dolor sit amet",
|
|
11954
11954
|
"vlan": null,
|
|
@@ -22009,10 +22009,10 @@
|
|
|
22009
22009
|
"command_filter_negate": false,
|
|
22010
22010
|
"command_issued": "host set_contact bar \"I'm the contact\" # fails because invalid email address",
|
|
22011
22011
|
"ok": [],
|
|
22012
|
-
"warning": [
|
|
22012
|
+
"warning": [],
|
|
22013
|
+
"error": [
|
|
22013
22014
|
"400 Bad Request: PATCH http://127.0.0.1:8000/api/v1/hosts/bar.example.org\n1 error:\n contacts: Invalid email address(es): I'm the contact (invalid)"
|
|
22014
22015
|
],
|
|
22015
|
-
"error": [],
|
|
22016
22016
|
"output": [],
|
|
22017
22017
|
"api_requests": [
|
|
22018
22018
|
{
|
|
@@ -22024,8 +22024,8 @@
|
|
|
22024
22024
|
"ipaddresses": [
|
|
22025
22025
|
{
|
|
22026
22026
|
"macaddress": "11:22:33:aa:bb:cc",
|
|
22027
|
-
"created_at": "2026-
|
|
22028
|
-
"updated_at": "2026-
|
|
22027
|
+
"created_at": "2026-10-16T12:54:34.323181+02:00",
|
|
22028
|
+
"updated_at": "2026-10-16T12:54:34.531313+02:00",
|
|
22029
22029
|
"ipaddress": "10.0.0.10",
|
|
22030
22030
|
"host": 19
|
|
22031
22031
|
}
|
|
@@ -22034,8 +22034,8 @@
|
|
|
22034
22034
|
"mxs": [],
|
|
22035
22035
|
"txts": [
|
|
22036
22036
|
{
|
|
22037
|
-
"created_at": "2026-
|
|
22038
|
-
"updated_at": "2026-
|
|
22037
|
+
"created_at": "2026-10-16T12:54:34.189966+02:00",
|
|
22038
|
+
"updated_at": "2026-10-16T12:54:34.190031+02:00",
|
|
22039
22039
|
"txt": "v=spf1 -all",
|
|
22040
22040
|
"host": 19
|
|
22041
22041
|
}
|
|
@@ -22053,12 +22053,12 @@
|
|
|
22053
22053
|
"contacts": [
|
|
22054
22054
|
{
|
|
22055
22055
|
"email": "hi@ho.com",
|
|
22056
|
-
"created_at": "2026-
|
|
22057
|
-
"updated_at": "2026-
|
|
22056
|
+
"created_at": "2026-10-16T12:54:34.213061+02:00",
|
|
22057
|
+
"updated_at": "2026-10-16T12:54:34.213129+02:00"
|
|
22058
22058
|
}
|
|
22059
22059
|
],
|
|
22060
|
-
"created_at": "2026-
|
|
22061
|
-
"updated_at": "2026-
|
|
22060
|
+
"created_at": "2026-10-16T12:54:34.177486+02:00",
|
|
22061
|
+
"updated_at": "2026-10-16T12:54:37.163243+02:00",
|
|
22062
22062
|
"name": "bar.example.org",
|
|
22063
22063
|
"ttl": null,
|
|
22064
22064
|
"comment": "This is the comment",
|
|
@@ -26113,10 +26113,10 @@
|
|
|
26113
26113
|
"command_filter_negate": false,
|
|
26114
26114
|
"command_issued": "host srv_add -name \"whatever\" -priority 1 -weight 1 -port 80 -host baz # doesn't work",
|
|
26115
26115
|
"ok": [],
|
|
26116
|
-
"warning": [
|
|
26116
|
+
"warning": [],
|
|
26117
|
+
"error": [
|
|
26117
26118
|
"400 Bad Request: POST http://127.0.0.1:8000/api/v1/srvs/\n1 error:\n name: Must match: ^_[a-z0-9]+(([a-z0-9][_-]?)+[a-z0-9]+)?._(tcp|tls|udp)\\. (invalid)"
|
|
26118
26119
|
],
|
|
26119
|
-
"error": [],
|
|
26120
26120
|
"output": [],
|
|
26121
26121
|
"api_requests": [
|
|
26122
26122
|
{
|
|
@@ -26128,15 +26128,15 @@
|
|
|
26128
26128
|
"ipaddresses": [
|
|
26129
26129
|
{
|
|
26130
26130
|
"macaddress": "11:22:33:aa:bb:cc",
|
|
26131
|
-
"created_at": "2026-
|
|
26132
|
-
"updated_at": "2026-
|
|
26131
|
+
"created_at": "2026-10-16T12:54:34.323181+02:00",
|
|
26132
|
+
"updated_at": "2026-10-16T12:54:40.816516+02:00",
|
|
26133
26133
|
"ipaddress": "10.0.0.10",
|
|
26134
26134
|
"host": 20
|
|
26135
26135
|
},
|
|
26136
26136
|
{
|
|
26137
26137
|
"macaddress": "11:22:33:44:55:67",
|
|
26138
|
-
"created_at": "2026-
|
|
26139
|
-
"updated_at": "2026-
|
|
26138
|
+
"created_at": "2026-10-16T12:54:41.501492+02:00",
|
|
26139
|
+
"updated_at": "2026-10-16T12:54:43.873479+02:00",
|
|
26140
26140
|
"ipaddress": "2001:db8::14",
|
|
26141
26141
|
"host": 20
|
|
26142
26142
|
}
|
|
@@ -26145,8 +26145,8 @@
|
|
|
26145
26145
|
"mxs": [],
|
|
26146
26146
|
"txts": [
|
|
26147
26147
|
{
|
|
26148
|
-
"created_at": "2026-
|
|
26149
|
-
"updated_at": "2026-
|
|
26148
|
+
"created_at": "2026-10-16T12:54:40.368541+02:00",
|
|
26149
|
+
"updated_at": "2026-10-16T12:54:40.368622+02:00",
|
|
26150
26150
|
"txt": "v=spf1 -all",
|
|
26151
26151
|
"host": 20
|
|
26152
26152
|
}
|
|
@@ -26162,8 +26162,8 @@
|
|
|
26162
26162
|
"bacnetid": null,
|
|
26163
26163
|
"communities": [],
|
|
26164
26164
|
"contacts": [],
|
|
26165
|
-
"created_at": "2026-
|
|
26166
|
-
"updated_at": "2026-
|
|
26165
|
+
"created_at": "2026-10-16T12:54:40.355234+02:00",
|
|
26166
|
+
"updated_at": "2026-10-16T12:54:40.355299+02:00",
|
|
26167
26167
|
"name": "baz.example.org",
|
|
26168
26168
|
"ttl": null,
|
|
26169
26169
|
"comment": "",
|
|
@@ -26180,18 +26180,18 @@
|
|
|
26180
26180
|
"zone": {
|
|
26181
26181
|
"nameservers": [
|
|
26182
26182
|
{
|
|
26183
|
-
"created_at": "2026-
|
|
26184
|
-
"updated_at": "2026-
|
|
26183
|
+
"created_at": "2026-10-16T12:53:57.454405+02:00",
|
|
26184
|
+
"updated_at": "2026-10-16T12:53:57.454474+02:00",
|
|
26185
26185
|
"name": "ns2.example.org",
|
|
26186
26186
|
"ttl": null
|
|
26187
26187
|
}
|
|
26188
26188
|
],
|
|
26189
|
-
"created_at": "2026-
|
|
26190
|
-
"updated_at": "2026-
|
|
26189
|
+
"created_at": "2026-10-16T12:53:57.061219+02:00",
|
|
26190
|
+
"updated_at": "2026-10-16T12:54:49.256682+02:00",
|
|
26191
26191
|
"updated": true,
|
|
26192
26192
|
"primary_ns": "ns2.example.org",
|
|
26193
26193
|
"email": "hostperson@example.org",
|
|
26194
|
-
"serialno_updated_at": "2026-
|
|
26194
|
+
"serialno_updated_at": "2026-10-16T12:53:57.561895+02:00",
|
|
26195
26195
|
"refresh": 360,
|
|
26196
26196
|
"retry": 1800,
|
|
26197
26197
|
"expire": 2400,
|
|
@@ -26210,18 +26210,18 @@
|
|
|
26210
26210
|
"zone": {
|
|
26211
26211
|
"nameservers": [
|
|
26212
26212
|
{
|
|
26213
|
-
"created_at": "2026-
|
|
26214
|
-
"updated_at": "2026-
|
|
26213
|
+
"created_at": "2026-10-16T12:53:57.454405+02:00",
|
|
26214
|
+
"updated_at": "2026-10-16T12:53:57.454474+02:00",
|
|
26215
26215
|
"name": "ns2.example.org",
|
|
26216
26216
|
"ttl": null
|
|
26217
26217
|
}
|
|
26218
26218
|
],
|
|
26219
|
-
"created_at": "2026-
|
|
26220
|
-
"updated_at": "2026-
|
|
26219
|
+
"created_at": "2026-10-16T12:53:57.061219+02:00",
|
|
26220
|
+
"updated_at": "2026-10-16T12:54:49.256682+02:00",
|
|
26221
26221
|
"updated": true,
|
|
26222
26222
|
"primary_ns": "ns2.example.org",
|
|
26223
26223
|
"email": "hostperson@example.org",
|
|
26224
|
-
"serialno_updated_at": "2026-
|
|
26224
|
+
"serialno_updated_at": "2026-10-16T12:53:57.561895+02:00",
|
|
26225
26225
|
"refresh": 360,
|
|
26226
26226
|
"retry": 1800,
|
|
26227
26227
|
"expire": 2400,
|
|
@@ -36964,10 +36964,10 @@
|
|
|
36964
36964
|
"command_filter_negate": false,
|
|
36965
36965
|
"command_issued": "network community_host_add tinierhost guests",
|
|
36966
36966
|
"ok": [],
|
|
36967
|
-
"warning": [
|
|
36967
|
+
"warning": [],
|
|
36968
|
+
"error": [
|
|
36968
36969
|
"406 Not Acceptable: POST http://127.0.0.1:8000/api/v1/networks/10.0.2.0/28/communities/1/hosts/\n1 error:\n The IP must have a MAC address to bind it to a community. (not_acceptable)"
|
|
36969
36970
|
],
|
|
36970
|
-
"error": [],
|
|
36971
36971
|
"output": [],
|
|
36972
36972
|
"api_requests": [
|
|
36973
36973
|
{
|
|
@@ -36979,8 +36979,8 @@
|
|
|
36979
36979
|
"ipaddresses": [
|
|
36980
36980
|
{
|
|
36981
36981
|
"macaddress": "",
|
|
36982
|
-
"created_at": "2026-
|
|
36983
|
-
"updated_at": "2026-
|
|
36982
|
+
"created_at": "2026-10-16T12:55:17.277750+02:00",
|
|
36983
|
+
"updated_at": "2026-10-16T12:55:17.277816+02:00",
|
|
36984
36984
|
"ipaddress": "10.0.2.5",
|
|
36985
36985
|
"host": 31
|
|
36986
36986
|
}
|
|
@@ -36989,8 +36989,8 @@
|
|
|
36989
36989
|
"mxs": [],
|
|
36990
36990
|
"txts": [
|
|
36991
36991
|
{
|
|
36992
|
-
"created_at": "2026-
|
|
36993
|
-
"updated_at": "2026-
|
|
36992
|
+
"created_at": "2026-10-16T12:55:17.136938+02:00",
|
|
36993
|
+
"updated_at": "2026-10-16T12:55:17.136998+02:00",
|
|
36994
36994
|
"txt": "v=spf1 -all",
|
|
36995
36995
|
"host": 31
|
|
36996
36996
|
}
|
|
@@ -37008,12 +37008,12 @@
|
|
|
37008
37008
|
"contacts": [
|
|
37009
37009
|
{
|
|
37010
37010
|
"email": "tinierhost@example.org",
|
|
37011
|
-
"created_at": "2026-
|
|
37012
|
-
"updated_at": "2026-
|
|
37011
|
+
"created_at": "2026-10-16T12:55:17.156360+02:00",
|
|
37012
|
+
"updated_at": "2026-10-16T12:55:17.156429+02:00"
|
|
37013
37013
|
}
|
|
37014
37014
|
],
|
|
37015
|
-
"created_at": "2026-
|
|
37016
|
-
"updated_at": "2026-
|
|
37015
|
+
"created_at": "2026-10-16T12:55:17.125199+02:00",
|
|
37016
|
+
"updated_at": "2026-10-16T12:55:17.125265+02:00",
|
|
37017
37017
|
"name": "tinierhost.example.org",
|
|
37018
37018
|
"ttl": null,
|
|
37019
37019
|
"comment": "",
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.12.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 12,
|
|
21
|
+
__version__ = version = '1.12.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 12, 2)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gf1f8228d3'
|
|
@@ -40,7 +40,7 @@ from mreg_cli.commands.zone import ZoneCommands
|
|
|
40
40
|
from mreg_cli.config import MregCliConfig
|
|
41
41
|
|
|
42
42
|
# Import other mreg_cli modules
|
|
43
|
-
from mreg_cli.exceptions import CliError, CliExit, CliWarning,
|
|
43
|
+
from mreg_cli.exceptions import CliError, CliExit, CliWarning, handle_and_exit, handle_exception
|
|
44
44
|
from mreg_cli.help_formatter import CustomHelpFormatter
|
|
45
45
|
from mreg_cli.outputmanager import OutputManager
|
|
46
46
|
from mreg_cli.types import CommandFunc, Flag
|
|
@@ -198,7 +198,7 @@ class Command(Completer):
|
|
|
198
198
|
if isinstance(exc, mreg_api.exceptions.ResponseError):
|
|
199
199
|
# Retry command after re-authenticating if we got a 401 Unauthorized
|
|
200
200
|
if exc.response.status_code == 401 and interactive and not retry:
|
|
201
|
-
with
|
|
201
|
+
with handle_and_exit(json=False):
|
|
202
202
|
prompt_for_password_and_try_update_token()
|
|
203
203
|
return self.parse(command, interactive=interactive, retry=True)
|
|
204
204
|
handle_exception(exc)
|
|
@@ -176,7 +176,7 @@ class MregCliClient(MregClient, metaclass=_AutoListenersMeta):
|
|
|
176
176
|
host = getter(ident_str)
|
|
177
177
|
if host is not None:
|
|
178
178
|
return host
|
|
179
|
-
except
|
|
179
|
+
except ValueError: # invalid identifier for this getter
|
|
180
180
|
pass
|
|
181
181
|
|
|
182
182
|
# Fall back to CNAME
|
|
@@ -230,25 +230,18 @@ class MregCliClient(MregClient, metaclass=_AutoListenersMeta):
|
|
|
230
230
|
Resolution order: IP address → CIDR / network address → numeric id.
|
|
231
231
|
"""
|
|
232
232
|
network: Network | None = None
|
|
233
|
+
|
|
233
234
|
try:
|
|
234
|
-
# Try as IP first
|
|
235
235
|
network = self.network.get_by_ip(identifier, required=False)
|
|
236
|
-
except
|
|
236
|
+
except ValueError: # invalid IP address
|
|
237
237
|
pass
|
|
238
238
|
|
|
239
239
|
if network is None:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
network = self.network.get(identifier, required=False)
|
|
243
|
-
except Exception:
|
|
244
|
-
pass
|
|
240
|
+
# Try as CIDR / network address
|
|
241
|
+
network = self.network.get(identifier, required=False)
|
|
245
242
|
|
|
246
243
|
if network is None and identifier.isdecimal():
|
|
247
|
-
|
|
248
|
-
network = self.network.first(id=int(identifier), required=False)
|
|
249
|
-
# network = self.network.get(int(identifier), required=False)
|
|
250
|
-
except Exception:
|
|
251
|
-
pass
|
|
244
|
+
network = self.network.first(id=int(identifier), required=False)
|
|
252
245
|
|
|
253
246
|
if network is None and required:
|
|
254
247
|
raise CliEntityNotFound(f"Network {identifier!r} not found.")
|
|
@@ -106,32 +106,28 @@ class TooManyResults(CliWarning):
|
|
|
106
106
|
"""API returned too many results."""
|
|
107
107
|
|
|
108
108
|
|
|
109
|
-
# FIXME: Inconsistent handling of HTTP errors in the original CLI implementation
|
|
110
|
-
# DELETE errors were considered errors, while other HTTP errors were
|
|
111
|
-
# considered warnings.
|
|
112
109
|
_MREG_API_ERROR_EXCEPTIONS = (
|
|
113
|
-
mreg_api.exceptions.
|
|
110
|
+
mreg_api.exceptions.ResponseError,
|
|
114
111
|
mreg_api.exceptions.InternalError,
|
|
115
112
|
mreg_api.exceptions.MregValidationError,
|
|
116
113
|
)
|
|
117
114
|
|
|
118
115
|
|
|
119
|
-
def is_error(exc:
|
|
116
|
+
def is_error(exc: BaseException) -> bool:
|
|
120
117
|
"""Determine if an exception should produce an error or warning."""
|
|
121
118
|
# mreg_cli errors
|
|
122
119
|
if isinstance(exc, CliError):
|
|
123
120
|
return True
|
|
124
121
|
elif isinstance(exc, CliWarning):
|
|
125
122
|
return False
|
|
126
|
-
|
|
127
123
|
# mreg_api exceptions that should be treated as errors
|
|
128
|
-
|
|
124
|
+
elif isinstance(exc, _MREG_API_ERROR_EXCEPTIONS):
|
|
129
125
|
return True
|
|
130
126
|
|
|
131
127
|
return False
|
|
132
128
|
|
|
133
129
|
|
|
134
|
-
def get_exception_message(exc:
|
|
130
|
+
def get_exception_message(exc: BaseException, *, json: bool = False) -> str:
|
|
135
131
|
"""Get the plain text message from an exception.
|
|
136
132
|
|
|
137
133
|
:param exc: The exception to get the message from.
|
|
@@ -159,14 +155,15 @@ class ExceptionHandler:
|
|
|
159
155
|
is_validation_error: True if the exception is a ValidationError.
|
|
160
156
|
message: The plain text message from the exception.
|
|
161
157
|
formatted_message: HTML-formatted message for prompt_toolkit display.
|
|
158
|
+
json: Whether to display mreg_api exceptions as their original JSON representation.
|
|
162
159
|
|
|
163
160
|
"""
|
|
164
161
|
|
|
165
|
-
def __init__(self, exc:
|
|
162
|
+
def __init__(self, exc: BaseException, *, json: bool = False) -> None:
|
|
166
163
|
"""Initialize the handler with an exception.
|
|
167
164
|
|
|
168
165
|
:param exc: The exception to handle.
|
|
169
|
-
:param json:
|
|
166
|
+
:param json: Display mreg_api exceptions as their original JSON representation.
|
|
170
167
|
"""
|
|
171
168
|
self.original_exception = exc
|
|
172
169
|
self.exception = self._transform_exception(exc)
|
|
@@ -180,7 +177,7 @@ class ExceptionHandler:
|
|
|
180
177
|
self.message = get_exception_message(self.exception, json=self._json)
|
|
181
178
|
self.formatted_message = self.get_formatted_message()
|
|
182
179
|
|
|
183
|
-
def _transform_exception(self, exc:
|
|
180
|
+
def _transform_exception(self, exc: BaseException) -> BaseException:
|
|
184
181
|
"""Transform an exception into an appropriate mreg_cli exception if needed."""
|
|
185
182
|
if isinstance(exc, ValidationError):
|
|
186
183
|
return mreg_api.exceptions.MregValidationError.from_pydantic(exc)
|
|
@@ -235,7 +232,7 @@ class ExceptionHandler:
|
|
|
235
232
|
self.print()
|
|
236
233
|
|
|
237
234
|
|
|
238
|
-
def handle_exception(exc:
|
|
235
|
+
def handle_exception(exc: BaseException, json: bool = False) -> None:
|
|
239
236
|
"""Log and print an exception with appropriate formatting.
|
|
240
237
|
|
|
241
238
|
This is the main entry point for exception handling.
|
|
@@ -244,17 +241,24 @@ def handle_exception(exc: Exception) -> None:
|
|
|
244
241
|
"""
|
|
245
242
|
# TODO: add JSON toggle via config here
|
|
246
243
|
# possibly via verbosity level/debug flag
|
|
247
|
-
ExceptionHandler(exc).handle()
|
|
244
|
+
ExceptionHandler(exc, json=json).handle()
|
|
248
245
|
|
|
249
246
|
|
|
250
247
|
@contextmanager
|
|
251
|
-
def
|
|
248
|
+
def handle_and_exit(
|
|
249
|
+
*exc_cls: type[BaseException], json: bool = False
|
|
250
|
+
) -> Generator[None, None, None]:
|
|
252
251
|
"""Context manager to handle exceptions using ExceptionHandler and exit.
|
|
253
252
|
|
|
253
|
+
Suppresses traceback and shows a formatted message in the console.
|
|
254
|
+
|
|
255
|
+
:param exc_cls: The exception class(es) to handle. Defaults to (Exception,).
|
|
254
256
|
:param json: Whether to include JSON details for mreg_api exceptions.
|
|
255
257
|
"""
|
|
258
|
+
if not exc_cls:
|
|
259
|
+
exc_cls = (Exception,)
|
|
256
260
|
try:
|
|
257
261
|
yield
|
|
258
|
-
except
|
|
259
|
-
|
|
262
|
+
except exc_cls as exc:
|
|
263
|
+
handle_exception(exc, json=json)
|
|
260
264
|
sys.exit(1)
|
|
@@ -14,7 +14,7 @@ from mreg_cli.__about__ import __version__
|
|
|
14
14
|
from mreg_cli.cli import cli, get_cli_history, source
|
|
15
15
|
from mreg_cli.client import init_client
|
|
16
16
|
from mreg_cli.config import MregCliConfig
|
|
17
|
-
from mreg_cli.exceptions import CliException,
|
|
17
|
+
from mreg_cli.exceptions import CliException, handle_and_exit, handle_exception
|
|
18
18
|
from mreg_cli.log import MregCliLogger
|
|
19
19
|
from mreg_cli.outputmanager import OutputManager
|
|
20
20
|
from mreg_cli.prompt import get_prompt_message
|
|
@@ -183,18 +183,12 @@ def main():
|
|
|
183
183
|
# Bootstrap the application-wide client object
|
|
184
184
|
client = init_client(config)
|
|
185
185
|
|
|
186
|
-
|
|
186
|
+
with handle_and_exit(Exception, KeyboardInterrupt):
|
|
187
187
|
try_token_or_login(
|
|
188
188
|
config.user,
|
|
189
189
|
config.url,
|
|
190
190
|
fail_without_token=config.token_only,
|
|
191
191
|
)
|
|
192
|
-
except (EOFError, KeyboardInterrupt, LoginFailedError) as e:
|
|
193
|
-
if isinstance(e, LoginFailedError):
|
|
194
|
-
handle_exception(e)
|
|
195
|
-
else:
|
|
196
|
-
print(e)
|
|
197
|
-
raise SystemExit() from None
|
|
198
192
|
|
|
199
193
|
if not client.get_token():
|
|
200
194
|
logger.error("No valid token after login, exiting")
|
|
@@ -117,7 +117,9 @@ def auth_and_update_token(username: str, password: str) -> None:
|
|
|
117
117
|
except httpx.HTTPError as e:
|
|
118
118
|
raise CliError(str(e)) from e # should be unreachable
|
|
119
119
|
except mreg_api.exceptions.LoginFailedError as e:
|
|
120
|
+
# wrap the server API error in a CliError to classify as error + hide URL & drf details
|
|
120
121
|
raise LoginFailedError(e.error_message) from e
|
|
122
|
+
# Other MREG API exceptions fall through
|
|
121
123
|
else:
|
|
122
124
|
TokenFile.set_entry(username, base_url, token)
|
|
123
125
|
logger.info("Token updated for %s @ %s", username, tokenurl)
|