Skip to content

Commit 2455b11

Browse files
committed
Add config tables for all configurable commands
1 parent 89a4eac commit 2455b11

File tree

15 files changed

+568
-209
lines changed

15 files changed

+568
-209
lines changed

CHANGELOG

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
<!-- released start -->
99

10-
<!-- ## [Unreleased] -->
10+
## [Unreleased]
11+
12+
### Added
13+
14+
- Configuration file tables for the following commands:
15+
- `create_host`: `[app.commands.create_host]`
16+
- `create_user`: `[app.commands.create_user]`
17+
- `create_notification_user`: `[app.commands.create_notification_user]`
18+
- `export_configuration`: `[app.commands.export]`
19+
- `import_configuration`: `[app.commands.export]`
20+
- **NOTE:** `export_configuration` and `import_configuration` share the same configuration table.
21+
- New option `create_user --default-usergroups/--no-default-usergroups`
22+
- New option `create_notification_user --default-usergroups/--no-default-usergroups`
23+
24+
### Changed
25+
26+
- Moved the following config options to the new `[app.commands]` table:
27+
- `app.default_hostgroups` → `app.commands.create_host.hostgroups`
28+
- `app.default_admin_usergroups` → `app.commands.create_hostgroup.rw_groups`
29+
- `app.default_create_user_usergroups` → `app.commands.create_user.usergroups` & `app.commands.create_hostgroup.ro_groups`
30+
- `app.default_notification_users_usergroups` → `app.commands.create_notification_user.usergroups`
31+
- `app.export_directory` → `app.commands.export.directory`
32+
- `app.export_format` → `app.commands.export.format`
33+
- `app.export_timestamps` → `app.commands.export.timestamps`
34+
- Removed default value in config for notification user groups (`All-notification-users`).
35+
- `create_notification_user` no longer uses the same default user groups as `create_user`.
36+
- The default user groups is now set by `app.commands.create_notification_user.usergroups` in the config file.
37+
38+
### Deprecated
39+
40+
- Deprecated the following config options (moved to the new `[app.commands]` table):
41+
- `app.default_hostgroups`
42+
- `app.default_admin_usergroups`
43+
- `app.default_create_user_usergroups`
44+
- `app.default_notification_users_usergroups`
45+
- `app.export_directory`
46+
- `app.export_format`
47+
- `app.export_timestamps`
1148

1249
## [3.5.2](https://github.com/unioslo/zabbix-cli/releases/tag/3.5.2) - 2025-04-24
1350

docs/scripts/gen_config_data.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,20 @@ def validate_type(cls, value: Any) -> str:
181181
def type_to_str(t: type[Any]) -> str:
182182
if lenient_issubclass(value, str):
183183
return "str"
184+
184185
if lenient_issubclass(value, Enum):
185186
# Get the name of the first enum member type
186-
# Will fail if enum has no members
187+
# NOTE: Will fail if enum has no members
187188
return str(list(value)[0]) # pyright: ignore[reportUnknownArgumentType]
189+
188190
# Types that are represented as strings in config (paths, secrets, etc.)
189191
if typ := TYPE_MAP.get(t):
190192
return typ
193+
191194
# Primitives and built-in generics (str, int, list[str], dict[str, int], etc.)
192195
if origin in TYPE_CAN_STR:
193196
return str(value)
197+
194198
# Fall back on the string representation of the type
195199
return getattr(value, "__name__", str(value))
196200

@@ -303,6 +307,8 @@ def get_config_options(
303307
continue
304308
if field.default is None:
305309
continue
310+
if field.deprecated:
311+
continue
306312

307313
if lenient_issubclass(field.annotation, RootModel):
308314
logging.debug("Skipping %s. It is a root model.", field_name)

tests/data/zabbix-cli-old-v3.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[api]
2+
url = "https:/zabbix.example.com"
3+
username = "Admin"
4+
password = ""
5+
auth_token = ""
6+
verify_ssl = true
7+
8+
[app]
9+
default_hostgroups = ["All-hosts"]
10+
default_admin_usergroups = ["All-admin-users"]
11+
default_create_user_usergroups = ["All-users"]
12+
default_notification_users_usergroups = ["All-notification-users"]
13+
export_directory = "/path/to/data_dir/exports"
14+
export_format = "json"
15+
export_timestamps = false
16+
use_session_file = true
17+
session_file = "/path/to/data_dir/.zabbix-cli_session.json"
18+
auth_token_file = "/path/to/data_dir/.zabbix-cli_auth_token"
19+
auth_file = "/path/to/data_dir/.zabbix-cli_auth"
20+
allow_insecure_auth_file = true
21+
history = true
22+
history_file = "/path/to/data_dir/history"
23+
bulk_mode = "strict"
24+
legacy_json_format = false
25+
use_color = true
26+
use_paging = false
27+
output_format = "table"
28+
29+
30+
[logging]
31+
enabled = true
32+
log_level = "INFO"
33+
log_file = "/path/to/logs_dir/zabbix-cli.log"
34+
35+
[plugins]

tests/data/zabbix-cli.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ legacy_json_format = false
2323

2424
[app.commands.create_host]
2525
create_interface = true
26+
hostgroups = []
27+
28+
[app.commands.create_hostgroup]
29+
ro_groups = []
30+
rw_groups = []
31+
32+
[app.commands.create_notification_user]
33+
usergroups = []
34+
35+
[app.commands.create_user]
36+
usergroups = []
37+
38+
[app.commands.export]
39+
directory = "/path/to/exports"
40+
format = "json"
41+
timestamps = false
2642

2743
[app.output]
2844
format = "table"

tests/test_config.py

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -305,22 +305,22 @@ def test_deprecated_field_warnings(caplog: pytest.LogCaptureFixture) -> None:
305305
(
306306
"zabbix_cli",
307307
30,
308-
"Config option [configopt]output_format[/] is deprecated. Use [configopt]app.output.format[/] instead.",
308+
"Config option [configopt]output_format[/] is deprecated. Replaced by: [configopt]app.output.format[/].",
309309
),
310310
(
311311
"zabbix_cli",
312312
30,
313-
"Config option [configopt]system_id[/] is deprecated. Use [configopt]api.username[/] instead.",
313+
"Config option [configopt]system_id[/] is deprecated. Replaced by: [configopt]api.username[/].",
314314
),
315315
(
316316
"zabbix_cli",
317317
30,
318-
"Config option [configopt]use_colors[/] is deprecated. Use [configopt]app.output.color[/] instead.",
318+
"Config option [configopt]use_colors[/] is deprecated. Replaced by: [configopt]app.output.color[/].",
319319
),
320320
(
321321
"zabbix_cli",
322322
30,
323-
"Config option [configopt]use_paging[/] is deprecated. Use [configopt]app.output.paging[/] instead.",
323+
"Config option [configopt]use_paging[/] is deprecated. Replaced by: [configopt]app.output.paging[/].",
324324
),
325325
(
326326
"zabbix_cli",
@@ -351,18 +351,22 @@ def test_get_deprecated_fields_set() -> None:
351351
DeprecatedField(
352352
field_name="app.output_format",
353353
value=OutputFormat.JSON,
354-
replacement="app.output.format",
354+
replacement=["app.output.format"],
355355
),
356356
DeprecatedField(
357357
field_name="app.system_id",
358358
value="System-User",
359-
replacement="api.username",
359+
replacement=["api.username"],
360360
),
361361
DeprecatedField(
362-
field_name="app.use_colors", value=True, replacement="app.output.color"
362+
field_name="app.use_colors",
363+
value=True,
364+
replacement=["app.output.color"],
363365
),
364366
DeprecatedField(
365-
field_name="app.use_paging", value=True, replacement="app.output.paging"
367+
field_name="app.use_paging",
368+
value=True,
369+
replacement=["app.output.paging"],
366370
),
367371
]
368372
)
@@ -404,7 +408,7 @@ def _set_deprecated_fields_in_new_location(self) -> Self:
404408
DeprecatedField(
405409
field_name="bar.qux_deprecated",
406410
value="test123",
407-
replacement="bar.baz.qux",
411+
replacement=["bar.baz.qux"],
408412
)
409413
]
410414
)
@@ -466,6 +470,13 @@ def test_get_deprecated_fields() -> None:
466470
"app.use_colors",
467471
"app.use_paging",
468472
"app.system_id",
473+
"app.default_hostgroups",
474+
"app.default_admin_usergroups",
475+
"app.default_create_user_usergroups",
476+
"app.default_notification_users_usergroups",
477+
"app.export_directory",
478+
"app.export_format",
479+
"app.export_timestamps",
469480
]
470481
)
471482

@@ -484,13 +495,6 @@ def test_load_deprecated_config(tmp_path: Path) -> None:
484495
verify_ssl = true
485496
486497
[app]
487-
default_hostgroups = ["All-hosts"]
488-
default_admin_usergroups = []
489-
default_create_user_usergroups = []
490-
default_notification_users_usergroups = ["All-notification-users"]
491-
export_directory = "{tmp_path}/exports"
492-
export_format = "json"
493-
export_timestamps = false
494498
use_session_file = true
495499
auth_token_file = "{tmp_path}/.zabbix-cli_auth_token"
496500
auth_file = "{tmp_path}/.zabbix-cli_auth"
@@ -499,6 +503,13 @@ def test_load_deprecated_config(tmp_path: Path) -> None:
499503
bulk_mode = "strict"
500504
501505
# Deprecated options (moved)
506+
default_hostgroups = ["All-hosts"]
507+
default_admin_usergroups = ["All-admin-users"]
508+
default_create_user_usergroups = ["All-users"]
509+
default_notification_users_usergroups = ["All-notification-users"]
510+
export_directory = "{tmp_path}/exports"
511+
export_format = "json"
512+
export_timestamps = false
502513
use_colors = false
503514
use_paging = true
504515
output_format = "json"
@@ -522,10 +533,21 @@ def test_load_deprecated_config(tmp_path: Path) -> None:
522533
config = Config.from_file(conf)
523534

524535
# Check that the deprecated fields are assigned to the new fields
536+
assert config.app.commands.create_host.hostgroups == ["All-hosts"]
537+
assert config.app.commands.create_hostgroup.rw_groups == ["All-admin-users"]
538+
assert config.app.commands.create_hostgroup.ro_groups == ["All-users"]
539+
assert config.app.commands.create_notification_user.usergroups == [
540+
"All-notification-users"
541+
]
542+
assert config.app.commands.create_user.usergroups == ["All-users"]
543+
assert config.app.commands.export.directory == tmp_path / "exports"
544+
assert config.app.commands.export.format == OutputFormat.JSON
545+
assert config.app.commands.export.timestamps is False
546+
525547
assert config.app.output.color is False
526548
assert config.app.output.paging is True
527549
assert config.app.output.format == OutputFormat.JSON
528-
assert config.api.username == "System-User"
550+
assert config.api.username == "System-User" # assigned from app.system_id
529551

530552

531553
def test_load_deprecated_config_with_new_and_old_options(tmp_path: Path) -> None:
@@ -536,16 +558,45 @@ def test_load_deprecated_config_with_new_and_old_options(tmp_path: Path) -> None
536558
"""
537559
conf = tmp_path / "zabbix-cli.toml"
538560
conf.write_text(
539-
"""
540-
[api]
541-
username = "Admin"
561+
f"""
562+
##### Deprecated options (should be ignored) #####
542563
543564
[app]
565+
default_hostgroups = ["All-hosts-deprecated"]
566+
default_admin_usergroups = ["All-admin-users-deprecated"]
567+
default_create_user_usergroups = ["All-users-deprecated"]
568+
default_notification_users_usergroups = ["All-notification-users-deprecated"]
569+
export_directory = "{tmp_path}/exports_deprecated"
570+
export_format = "yaml"
571+
export_timestamps = true
544572
use_colors = false
545573
use_paging = true
546574
output_format = "json"
547575
system_id = "System-User"
548576
577+
##### New options (should be used) #####
578+
579+
[api]
580+
username = "Admin"
581+
582+
[app.commands.create_user]
583+
usergroups = ["All-users"]
584+
585+
[app.commands.create_notification_user]
586+
usergroups = ["All-notification-users"]
587+
588+
[app.commands.create_host]
589+
hostgroups = ["All-hosts"]
590+
591+
[app.commands.create_hostgroup]
592+
ro_groups = ["All-users"]
593+
rw_groups = ["All-admin-users"]
594+
595+
[app.commands.export]
596+
directory = "{tmp_path}/exports"
597+
format = "json"
598+
timestamps = false
599+
549600
[app.output]
550601
color = true
551602
format = "table"
@@ -555,6 +606,18 @@ def test_load_deprecated_config_with_new_and_old_options(tmp_path: Path) -> None
555606
config = Config.from_file(conf)
556607

557608
# New fields should NOT be overwritten by deprecated fields
609+
assert config.app.commands.create_host.hostgroups == ["All-hosts"]
610+
assert config.app.commands.create_hostgroup.rw_groups == ["All-admin-users"]
611+
assert config.app.commands.create_hostgroup.ro_groups == ["All-users"]
612+
assert config.app.commands.create_user.usergroups == ["All-users"]
613+
assert config.app.commands.create_notification_user.usergroups == [
614+
"All-notification-users"
615+
]
616+
assert config.app.commands.create_hostgroup.ro_groups == ["All-users"]
617+
assert config.app.commands.create_hostgroup.rw_groups == ["All-admin-users"]
618+
assert config.app.commands.export.directory == tmp_path / "exports"
619+
assert config.app.commands.export.format == OutputFormat.JSON
620+
assert config.app.commands.export.timestamps is False
558621
assert config.api.username == "Admin"
559622
assert config.app.output.color is True
560623
assert config.app.output.paging is False

zabbix_cli/commands/cli.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ def update_config(
376376
if not bool_prompt("Update config file?", default=False):
377377
exit_err("Update cancelled.")
378378

379+
# When we dump the config, we automatically exclude the deprecated fields
380+
# while taking advantage of the validators that update the new fields.
379381
config = app.state.config
380382
config.dump_to_file(config_file, secrets=secrets)
381383
success(f"Config saved to {path_link(config_file)}")

0 commit comments

Comments
 (0)