cmdbsyncer 4.3.4__tar.gz → 4.3.5__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.
- {cmdbsyncer-4.3.4/cmdbsyncer.egg-info → cmdbsyncer-4.3.5}/PKG-INFO +1 -1
- cmdbsyncer-4.3.5/application/buildinfo.txt +1 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v4.3.md +9 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/runner.py +63 -1
- cmdbsyncer-4.3.5/application/plugins/ansible/tests/__init__.py +1 -0
- cmdbsyncer-4.3.5/application/plugins/ansible/tests/test_runner_ssh_env.py +86 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/__init__.py +5 -2
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/cmk2.py +16 -2
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/cmk_rules.py +134 -3
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/inits.py +8 -2
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/syncer.py +303 -26
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_cmk2.py +36 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_cmk_rules.py +260 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_syncer.py +257 -3
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/csv/csv.py +2 -5
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jdisc/devices.py +2 -3
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ldap/ldap.py +14 -4
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/mysql/mysql.py +2 -6
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/pyodbc/pyodbc.py +3 -9
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rest/rest.py +2 -5
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/yml/yml.py +2 -5
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5/cmdbsyncer.egg-info}/PKG-INFO +1 -1
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/cmdbsyncer.egg-info/SOURCES.txt +3 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/pyproject.toml +1 -1
- cmdbsyncer-4.3.5/tests/test_inventorize_rewrite_once.py +190 -0
- cmdbsyncer-4.3.4/application/buildinfo.txt +0 -1
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/LICENSE +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/README.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/_version.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/api/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/api/inventory.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/api/objects.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/api/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/api/syncer.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/api/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/auth/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/.pages +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.10.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.11.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.12.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.5.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.7.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.8.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v3.9.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v4.0.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v4.1.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/changelog/v4.2.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/cli.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/config.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/docu_links.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/enterprise.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/audit.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/cron.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/db_analysis.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/get_account.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/host_maintenance.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/inventory.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/label_hash.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/label_history.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/local_config_file.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/local_config_presets.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/mongo_keys.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/notification_channels.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/notification_dispatch.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/plugins.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/retention.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/sates.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/sql.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/stale_indexes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/syncer_jinja.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/tablib_formater.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/tests/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/helpers/tests/test_sql.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/mcp_server.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/account.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/config.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/cron.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/field_approval.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/forms.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/host.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/host_cleanup.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/host_inventory_tree.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/host_label_event.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/host_templates.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/notification_channel.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/notification_rule.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/notification_state.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/project.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/saved_search.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/states.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/models/user.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/module_registry.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/custom_attributes/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/custom_attributes/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/custom_attributes/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/debug.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/email.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/inventory/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/log/command_output.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/log/log.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/log/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/log/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/plugin.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/filter.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/match.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/rewrite.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/rule.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/rule/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/search_parser.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/modules/statefile.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/notices/strict_certificate_verification.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/inventory.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/playbook_rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/seed.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/site_syncer.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ansible/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/bmc_remedy/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/bmc_remedy/bmc_remedy.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/bmc_remedy/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/bi.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/data_quality.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/dcd.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/downtimes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/folder_attributes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/groups.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/helpers.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/import_v1.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/import_v2.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/inventorize.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/notification_rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/passwords.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/poolfolder.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/rule_analysis_runner.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/rule_passwords.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/rulesets_catalog.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/sitepool.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/sites.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tags.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_assign_template.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_bi.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_cmk_conditions.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_data_quality.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_dcd.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_downtimes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_groups.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_helpers.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_import_v1.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_import_v2.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_inventorize.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_notification_rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_passwords.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_poolfolder.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_rule_analysis_runner.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_rule_passwords.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_sitepool.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_sites.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_tags.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/tests/test_users.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/users.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/checkmk/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/cisco_dna/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/cisco_dna/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/cisco_dna/syncer.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/cron.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/csv/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/csv/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/file_requests.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/syncer.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/idoit/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jdisc/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jdisc/applications.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jdisc/executables.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jdisc/jdisc.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jdisc/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira/jira.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/export.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/jira_cloud.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/schema_sync.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/tests/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/tests/test_attribute_value.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/jira_cloud/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/json/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/json/json.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/json/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ldap/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ldap/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ldap/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/ldap/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/maintenance/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/maintenance/db_commands.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/maintenance/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/maintenance/tests/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/maintenance/tests/test_delete_all_hosts.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/maintenance/tests/test_delete_inventory.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/mssql/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/mssql/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/mysql/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/mysql/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/cluster.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/contacts.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/dataflow.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/devices.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/interfaces.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/ips.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/netbox.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/networks.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/prefixes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/tests/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/tests/test_import_filter.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/utils.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/netbox/virtualmachines.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/prtg/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/prtg/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/prtg/prtg.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/pyodbc/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/pyodbc/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rest/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rest/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/autorules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/rule_definitions.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/rule_import_export.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/rules/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/syncer.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/tests/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/tests/test_table_request.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/servicenow/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/syncer_shell.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/admin_views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/custom_attributes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/models.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/rules.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/views.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/vmware/vmware.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/yml/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins/yml/plugin.json +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/plugins_cli.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/cmdbsyncer_mark.png +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/css/cmdbsyncer.css +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/favicon.png +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/js/Sortable.min.js +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/js/main.js +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/logo_white.png +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/README.md +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/ansible.svg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/checkmk.svg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/idoit.svg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/jira.svg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/netbox.svg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/static/vendor/vmware.svg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/_brand.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/_theme.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/_host_tabs.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/account_create.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/account_edit.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/account_field_help.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/account_pick_type.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/ansible_playbook_run.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/ansible_project_detail.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/ansible_rule_list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/ansible_run_details.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/assign_project_form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/bulk_label_form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/changelog_archive.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/checkmk_data_quality.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/checkmk_rule_mngmt_list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/checkmk_rule_optimization.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/checkmk_settings_list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/checkmk_test_folder_scope.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/copy_as_new_form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/data_quality.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/data_quality_lowercase_preview.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/file/list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/file/modals/form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/first_steps.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_csv_import_preview.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_details.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_edit.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_inventory_tree.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_relations_graph.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/host_timeline.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/index.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/ldap_search.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/local_config_editor.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/master.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/_action_picker.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/_folder_builder.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/_notification_plugin_picker.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/_ruleset_autocomplete.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/checkmk_notification_rule_create.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/checkmk_notification_rule_edit.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/checkmk_rule_create.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/checkmk_rule_edit.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/checkmk_rule_mngmt_create.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/checkmk_rule_mngmt_edit.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/clone_confirm.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/model/inline_list_base.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/module_overview.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/object_list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/project_edit.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/project_import.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/project_import_cmk.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/project_list.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/project_overview.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/servicenow_query.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/set_account_form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/set_cmk_version_form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/admin/set_template_form.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/api_tokens.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/base.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/change_password.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/csrf_error.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/debug.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/debug_host.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/email/newuser.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/email/notification.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/email/resetpassword.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/formular.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/license_info.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/login.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/logout_confirm.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/request_password.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/set_2fa.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/templates/set_theme.html +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/themes/dracula.css +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/themes/gruvbox-dark.css +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/themes/gruvbox-light.css +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/themes/nord.css +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/themes_registry.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/_form_fields.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/_form_sections.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/account.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/account_select.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/config.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/cron.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/data_quality.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/default.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/field_approval.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/fileadmin.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/first_steps.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/host.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/host_filters.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/host_inventory_grid.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/host_renderers.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/host_widgets.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/license.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/menu_links.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/module_overview.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/notification_channel.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/notification_rule.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/project.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/saved_search.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/template_select.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/application/views/user.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/cmdbsyncer.egg-info/dependency_links.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/cmdbsyncer.egg-info/entry_points.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/cmdbsyncer.egg-info/requires.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/cmdbsyncer.egg-info/top_level.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/requirements-ansible-windows.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/requirements-ansible.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/requirements-extras.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/requirements.txt +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/setup.cfg +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/syncerapi/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/syncerapi/v1/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/syncerapi/v1/core/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/syncerapi/v1/inventory/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/syncerapi/v1/rest/__init__.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_account_macro.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_api.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_api_csrf_invariant.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_config_dir.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_cron_missing_account.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_csrf_config.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_data_quality_duplicates.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_default_view.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_disabled_row_style.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_enterprise_quiet.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_folder_builder_js.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_global_account_presets.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_host_cleanup.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_host_label_edit.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_host_template_filter.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_host_template_resync.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_jinja_get_list.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_jinja_hash.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_label_history.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_local_config_presets.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_logging_config.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_model_indexes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_mongo_keys.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_plugin.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_plugin_ssti.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_plugins_cli.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_regex_condition_limits.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_rule.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_rule_export_templates.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_rule_filename_detect.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_rule_import_override.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_rule_match.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_rule_registry_complete.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_search_parser.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_security_fixes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_stale_indexes.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_template_merge_fields.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_user_scope_smoke.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_view_permission_flags.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_web_boot_smoke.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_web_requests_smoke.py +0 -0
- {cmdbsyncer-4.3.4 → cmdbsyncer-4.3.5}/tests/test_webhook_token_hash.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cmdbsyncer
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.5
|
|
4
4
|
Summary: Rule-based modular synchronizer for Checkmk, Netbox, Ansible, I-DOIT, Jira CMDB and 15+ other CMDB/monitoring systems
|
|
5
5
|
Author-email: Kuhn & Ruess GmbH <info@kuhn-ruess.de>
|
|
6
6
|
Maintainer-email: Bastian Kuhn <mail@bastian-kuhn.de>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
BUILD_DATE=2026-10-07T14:27:29Z
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Version 4.3
|
|
2
2
|
|
|
3
|
+
## Version 4.3.5
|
|
4
|
+
- FIX: Inventorize applied `rewrite_hostname` twice for CSV, JSON, REST, YML, MySQL, ODBC, JDisc and LDAP accounts, so a template that appends something to the name, a domain for example, missed the host the import had created
|
|
5
|
+
- FIX: When Checkmk applies a bulk host update or create only in part ("Some actions failed"), the log now names each skipped host with the reason Checkmk gives, in one entry, instead of only the host names. A host is also no longer edited several times per export, so the Checkmk audit log no longer fills up with "Nothing was changed" entries, and a host whose attribute was removed is no longer reported as faulty although the removal worked. A bulk update request carries as many hosts as CMK_BULK_UPDATE_OPERATIONS allows, so this needs no more requests than before
|
|
6
|
+
- FIX: A Move to Folder rule whose folder option has no value for a host (it renders to False, True or None, for example a city the host does not have) no longer writes that into the Checkmk folder: Checkmk 2.5 then failed to list any folder and every export stopped with "Mismatch between endpoint and internal data format". The option is left out with a warning naming folder and attribute, a value like this already in a folder is removed, and when Checkmk can no longer list its folders the export continues and repairs the folders its rules manage
|
|
7
|
+
- FIX: A playbook run with an SSH password no longer fails on every host with "Invalid/incorrect password" when the application runs as the web server user — ssh was trying to write its known_hosts into that user's home directory, which is not writable; each run now keeps its known_hosts with its other temporary files, and a run that still hits this says so in the log instead of blaming the password
|
|
8
|
+
- FIX: A Checkmk rule that Checkmk refuses to update is left in place instead of being deleted — a value the target rejects (for example a password store reference written in a format a newer Checkmk no longer accepts) made the export delete the rule and then fail to recreate it, so the rule was gone after every run
|
|
9
|
+
- FEAT: The Checkmk rule export can be tried out before it runs: `export_rules --dry-run` reads the site and prints every rule it would create, update and delete, with the value it would write and the reason behind every deletion, and sends nothing to Checkmk
|
|
10
|
+
- FIX: `--debug` on the Checkmk rule export now shows the full error of a failed run, the same as the other export commands do, instead of only the difference behind each deletion
|
|
11
|
+
|
|
3
12
|
## Version 4.3.4
|
|
4
13
|
- FIX: A user the directory created can now log in — a successful directory bind ended in a server error for anybody who has no local password, which is every user created on first login
|
|
5
14
|
- FIX: A directory login that fails records what went wrong, so an unreachable server, a service account with the wrong password and a group mapping naming a role that does not exist can be told apart in Settings → Log
|
|
@@ -263,6 +263,66 @@ def _write_run_inventory_spec(directory: str, provider: str, mode: str,
|
|
|
263
263
|
return spec_path
|
|
264
264
|
|
|
265
265
|
|
|
266
|
+
def _apply_ssh_env(env: dict, run_tmp: str) -> None:
|
|
267
|
+
"""
|
|
268
|
+
Point OpenSSH at a writable known_hosts file inside the run's temp dir.
|
|
269
|
+
|
|
270
|
+
Setting $HOME (see `_execute`) covers Ansible's own scratch files but
|
|
271
|
+
does not reach ssh: OpenSSH expands the `~` of `~/.ssh` and
|
|
272
|
+
`known_hosts` through the passwd database, not $HOME. Under mod_wsgi /
|
|
273
|
+
gunicorn the process runs as the web user, whose home (e.g.
|
|
274
|
+
`/usr/share/httpd`) is not writable, so every host fails with
|
|
275
|
+
|
|
276
|
+
Could not create directory '/usr/share/httpd/.ssh'.
|
|
277
|
+
Failed to add the host to the list of known hosts
|
|
278
|
+
|
|
279
|
+
and with a password sshpass exits 5, which Ansible reports as
|
|
280
|
+
"Invalid/incorrect password" — hiding the real cause entirely.
|
|
281
|
+
|
|
282
|
+
Host key checking is turned off because an unknown host key makes ssh
|
|
283
|
+
ask a question nobody can answer in a background run (the run would
|
|
284
|
+
hang or fail instead of reporting anything useful). Operator settings
|
|
285
|
+
win: ANSIBLE_HOST_KEY_CHECKING is only defaulted, and our ssh options
|
|
286
|
+
are appended *after* any configured ANSIBLE_SSH_EXTRA_ARGS — ssh keeps
|
|
287
|
+
the first value it is given for an option, so an own
|
|
288
|
+
`-o UserKnownHostsFile=...` (a persistent known_hosts) takes precedence.
|
|
289
|
+
"""
|
|
290
|
+
env.setdefault('ANSIBLE_HOST_KEY_CHECKING', 'False')
|
|
291
|
+
known_hosts = os.path.join(run_tmp, 'known_hosts')
|
|
292
|
+
configured = (env.get('ANSIBLE_SSH_EXTRA_ARGS') or '').strip()
|
|
293
|
+
ours = f'-o UserKnownHostsFile={known_hosts} -o StrictHostKeyChecking=no'
|
|
294
|
+
env['ANSIBLE_SSH_EXTRA_ARGS'] = f'{configured} {ours}'.strip()
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def _connection_hint(log: str) -> str:
|
|
298
|
+
"""
|
|
299
|
+
Explain an "Invalid/incorrect password" that is not one.
|
|
300
|
+
|
|
301
|
+
sshpass reports every failure it cannot classify as a wrong password,
|
|
302
|
+
and Ansible prints ssh's stderr behind that message. When that stderr
|
|
303
|
+
says ssh could not write into the home directory of the user the
|
|
304
|
+
application runs as, the password is a red herring — so say that in
|
|
305
|
+
the log instead of sending the next reader hunting for credentials.
|
|
306
|
+
Returns an empty string when the log shows no such combination.
|
|
307
|
+
"""
|
|
308
|
+
if 'Invalid/incorrect password' not in log:
|
|
309
|
+
return ''
|
|
310
|
+
if not any(marker in log for marker in (
|
|
311
|
+
"Could not create directory",
|
|
312
|
+
"Failed to add the host to the list of known hosts",
|
|
313
|
+
)):
|
|
314
|
+
return ''
|
|
315
|
+
return (
|
|
316
|
+
"\n--- CMDBsyncer ---\n"
|
|
317
|
+
"This is most likely NOT a wrong password. The ssh output above shows "
|
|
318
|
+
"that ssh could not write into the home directory of the user this "
|
|
319
|
+
"application runs as (no writable ~/.ssh), and sshpass reports that as "
|
|
320
|
+
"'Invalid/incorrect password'. Give the process a writable home "
|
|
321
|
+
"directory, or set ANSIBLE_SSH_EXTRA_ARGS with "
|
|
322
|
+
"-o UserKnownHostsFile=<writable file> in its environment.\n"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
|
|
266
326
|
def cancel_run(stats) -> bool:
|
|
267
327
|
"""
|
|
268
328
|
Stop a still-running playbook by signalling its process group.
|
|
@@ -361,6 +421,7 @@ def _execute(stats_id, run_params: dict, cwd: Path, provider: str):
|
|
|
361
421
|
# local-delegated tasks work; real SSH hosts just create this path
|
|
362
422
|
# under their own /tmp.
|
|
363
423
|
env['ANSIBLE_REMOTE_TEMP'] = run_tmp
|
|
424
|
+
_apply_ssh_env(env, run_tmp)
|
|
364
425
|
inventory_path = _write_run_inventory_spec(
|
|
365
426
|
run_tmp, provider, env['CMDBSYNCER_INVENTORY_MODE'],
|
|
366
427
|
cmdbsyncer_bin=_cmdbsyncer_bin(),
|
|
@@ -387,7 +448,8 @@ def _execute(stats_id, run_params: dict, cwd: Path, provider: str):
|
|
|
387
448
|
)
|
|
388
449
|
stats.pid = proc.pid
|
|
389
450
|
stats.save()
|
|
390
|
-
|
|
451
|
+
captured = _stream_output(proc, stats)
|
|
452
|
+
stats.log = captured + _connection_hint(captured)
|
|
391
453
|
stats.exit_code = proc.returncode
|
|
392
454
|
# A negative return code means the process was killed by a signal
|
|
393
455
|
# — that is how cancel_run() stops a run, so report it as
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Test package for the Ansible plugin."""
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The playbook runner has to work under a web user without a writable home.
|
|
3
|
+
"""
|
|
4
|
+
# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import unittest
|
|
8
|
+
from types import ModuleType
|
|
9
|
+
from unittest.mock import MagicMock
|
|
10
|
+
|
|
11
|
+
from tests import _load_real_module
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _load_runner():
|
|
15
|
+
"""Load the runner with its model import stubbed."""
|
|
16
|
+
name = 'application.plugins.ansible.runner'
|
|
17
|
+
if name in sys.modules:
|
|
18
|
+
return sys.modules[name]
|
|
19
|
+
models = sys.modules.setdefault(
|
|
20
|
+
'application.plugins.ansible.models',
|
|
21
|
+
ModuleType('application.plugins.ansible.models'))
|
|
22
|
+
if not hasattr(models, 'AnsibleRunStats'):
|
|
23
|
+
models.AnsibleRunStats = MagicMock()
|
|
24
|
+
return _load_real_module(name, os.path.join(
|
|
25
|
+
'plugins', 'ansible', 'runner.py'))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SshEnvTest(unittest.TestCase):
|
|
29
|
+
"""
|
|
30
|
+
$HOME does not reach OpenSSH — it expands `~/.ssh` via the passwd
|
|
31
|
+
database — so the run has to name a writable known_hosts itself.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def setUpClass(cls):
|
|
36
|
+
cls.runner = _load_runner()
|
|
37
|
+
|
|
38
|
+
def test_known_hosts_points_into_the_run_dir(self):
|
|
39
|
+
env = {}
|
|
40
|
+
self.runner._apply_ssh_env(env, '/tmp/run-1')
|
|
41
|
+
self.assertIn('-o UserKnownHostsFile=/tmp/run-1/known_hosts',
|
|
42
|
+
env['ANSIBLE_SSH_EXTRA_ARGS'])
|
|
43
|
+
self.assertEqual(env['ANSIBLE_HOST_KEY_CHECKING'], 'False')
|
|
44
|
+
|
|
45
|
+
def test_operator_settings_keep_precedence(self):
|
|
46
|
+
env = {
|
|
47
|
+
'ANSIBLE_HOST_KEY_CHECKING': 'True',
|
|
48
|
+
'ANSIBLE_SSH_EXTRA_ARGS': '-o UserKnownHostsFile=/etc/ansible/known_hosts',
|
|
49
|
+
}
|
|
50
|
+
self.runner._apply_ssh_env(env, '/tmp/run-2')
|
|
51
|
+
self.assertEqual(env['ANSIBLE_HOST_KEY_CHECKING'], 'True')
|
|
52
|
+
# ssh keeps the first value given for an option, so the configured
|
|
53
|
+
# file has to come before ours.
|
|
54
|
+
args = env['ANSIBLE_SSH_EXTRA_ARGS']
|
|
55
|
+
self.assertLess(args.index('/etc/ansible/known_hosts'),
|
|
56
|
+
args.index('/tmp/run-2/known_hosts'))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ConnectionHintTest(unittest.TestCase):
|
|
60
|
+
"""
|
|
61
|
+
sshpass calls a non-writable home a wrong password. The log must not
|
|
62
|
+
leave it at that.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def setUpClass(cls):
|
|
67
|
+
cls.runner = _load_runner()
|
|
68
|
+
|
|
69
|
+
def test_hint_added_for_unwritable_home(self):
|
|
70
|
+
log = ('fatal: [host]: UNREACHABLE! => {"msg": "Invalid/incorrect '
|
|
71
|
+
'password: Could not create directory \'/usr/share/httpd/.ssh\'."}')
|
|
72
|
+
hint = self.runner._connection_hint(log)
|
|
73
|
+
self.assertIn('NOT a wrong password', hint)
|
|
74
|
+
|
|
75
|
+
def test_no_hint_for_a_real_password_failure(self):
|
|
76
|
+
log = ('fatal: [host]: UNREACHABLE! => {"msg": "Invalid/incorrect '
|
|
77
|
+
'password: Permission denied, please try again."}')
|
|
78
|
+
self.assertEqual(self.runner._connection_hint(log), '')
|
|
79
|
+
|
|
80
|
+
def test_no_hint_without_the_password_message(self):
|
|
81
|
+
log = "Could not create directory '/usr/share/httpd/.ssh'."
|
|
82
|
+
self.assertEqual(self.runner._connection_hint(log), '')
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == '__main__':
|
|
86
|
+
unittest.main()
|
|
@@ -459,19 +459,22 @@ def cli_missing_hosts(account):
|
|
|
459
459
|
|
|
460
460
|
@cli_cmk.command('export_rules')
|
|
461
461
|
@click.argument("account")
|
|
462
|
+
@click.option("--dry-run", default=False, is_flag=True)
|
|
462
463
|
@click.option("--debug", is_flag=True)
|
|
463
|
-
def cli_export_rules(account, debug):
|
|
464
|
+
def cli_export_rules(account, dry_run, debug):
|
|
464
465
|
"""
|
|
465
466
|
Export all configured Rules to given Checkmk Installations
|
|
466
467
|
|
|
467
468
|
### Example
|
|
468
469
|
_./cmdbsyncer checkmk export_rules SITEACCOUNT_
|
|
470
|
+
_./cmdbsyncer checkmk export_rules SITEACCOUNT --dry-run_
|
|
469
471
|
|
|
470
472
|
|
|
471
473
|
Args:
|
|
472
474
|
account (string): Name Checkmk Account Config
|
|
475
|
+
dry_run (bool): Only print what would change ( default is False )
|
|
473
476
|
"""
|
|
474
|
-
export_rules(account, debug)
|
|
477
|
+
export_rules(account, dry_run=dry_run, debug=debug)
|
|
475
478
|
|
|
476
479
|
#.
|
|
477
480
|
# .-- Command: Analyse Rule Optimization
|
|
@@ -18,7 +18,17 @@ FALLBACK_CMK_VERSION = '2.4.0'
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class CmkException(Exception):
|
|
21
|
-
"""
|
|
21
|
+
"""
|
|
22
|
+
Cmk Errors
|
|
23
|
+
|
|
24
|
+
``failed_hosts`` holds the per host reasons Checkmk sends with a
|
|
25
|
+
partly failed bulk request ("Some actions failed"), as
|
|
26
|
+
``{hostname: reason}``. It is empty for every other error.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, *args, failed_hosts=None):
|
|
30
|
+
super().__init__(*args)
|
|
31
|
+
self.failed_hosts = failed_hosts or {}
|
|
22
32
|
|
|
23
33
|
class CMK2(Plugin): # pylint: disable=too-many-instance-attributes
|
|
24
34
|
"""
|
|
@@ -248,7 +258,11 @@ class CMK2(Plugin): # pylint: disable=too-many-instance-attributes
|
|
|
248
258
|
message = " ".join(str(x) for x in (title, detail) if x is not None)
|
|
249
259
|
if fields is not None:
|
|
250
260
|
message += str(fields)
|
|
251
|
-
|
|
261
|
+
# A bulk request that failed for single hosts names
|
|
262
|
+
# them in `detail`, but only `ext.failed_hosts` says why.
|
|
263
|
+
ext = response_json.get('ext')
|
|
264
|
+
failed_hosts = ext.get('failed_hosts') if isinstance(ext, dict) else None
|
|
265
|
+
raise CmkException(message, failed_hosts=failed_hosts)
|
|
252
266
|
return {}, {'status_code': response.status_code}
|
|
253
267
|
resp_header['status_code'] = response.status_code
|
|
254
268
|
|
|
@@ -952,6 +952,10 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
952
952
|
# rule_type -> set of content signatures already collected into
|
|
953
953
|
# rulsets_by_type, so the duplicate check does not rescan the list.
|
|
954
954
|
self._rule_signatures = {}
|
|
955
|
+
# Changes a dry run decided on but did not send, as
|
|
956
|
+
# (action, target, detail lines). Filled by _plan, printed by
|
|
957
|
+
# _report_dry_run at the end of the run.
|
|
958
|
+
self.dry_run_plan = []
|
|
955
959
|
|
|
956
960
|
@property
|
|
957
961
|
def rule_marker(self):
|
|
@@ -1467,7 +1471,15 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
1467
1471
|
def export_cmk_rules(self):
|
|
1468
1472
|
"""
|
|
1469
1473
|
Export config rules to checkmk
|
|
1474
|
+
|
|
1475
|
+
With ``dry_run`` set, every step still runs and still reads
|
|
1476
|
+
Checkmk, but no create, update, delete or move is sent: the
|
|
1477
|
+
decisions are collected and printed instead, so the run can be
|
|
1478
|
+
read before it is made for real.
|
|
1470
1479
|
"""
|
|
1480
|
+
if self.dry_run:
|
|
1481
|
+
print(f"{CC.WARNING} !! {CC.ENDC}Dry run: nothing will be sent "
|
|
1482
|
+
"to Checkmk")
|
|
1471
1483
|
self.calculate_rules()
|
|
1472
1484
|
self.calculate_static_rules()
|
|
1473
1485
|
self.optimize_rules()
|
|
@@ -1476,6 +1488,45 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
1476
1488
|
self.clean_orphaned_rules()
|
|
1477
1489
|
self.create_rules()
|
|
1478
1490
|
self.sort_rules()
|
|
1491
|
+
if self.dry_run:
|
|
1492
|
+
self._report_dry_run()
|
|
1493
|
+
|
|
1494
|
+
def _plan(self, action, target, *lines):
|
|
1495
|
+
"""
|
|
1496
|
+
Record a change a dry run does not send.
|
|
1497
|
+
|
|
1498
|
+
``target`` names the ruleset and, for a rule Checkmk already
|
|
1499
|
+
has, its rule id. ``lines`` carry what an operator has to see
|
|
1500
|
+
before the run happens for real — the value above everything
|
|
1501
|
+
else.
|
|
1502
|
+
"""
|
|
1503
|
+
detail = [str(line) for line in lines]
|
|
1504
|
+
self.dry_run_plan.append((action, target, detail))
|
|
1505
|
+
self.log_details.append(
|
|
1506
|
+
("INFO", f"[dry-run] would {action} {target}: {'; '.join(detail)}"))
|
|
1507
|
+
|
|
1508
|
+
def _report_dry_run(self):
|
|
1509
|
+
"""
|
|
1510
|
+
Print what the run would have changed, values included.
|
|
1511
|
+
|
|
1512
|
+
A dry run is only worth something if the value is in the output:
|
|
1513
|
+
the point of it is to read the rule Checkmk would receive before
|
|
1514
|
+
Checkmk receives it.
|
|
1515
|
+
"""
|
|
1516
|
+
print(f"\n{CC.HEADER}Dry run — nothing was sent to Checkmk{CC.ENDC}")
|
|
1517
|
+
if not self.dry_run_plan:
|
|
1518
|
+
print(f"{CC.OKGREEN} ** {CC.ENDC}Checkmk already matches the "
|
|
1519
|
+
"generated rules — nothing would change")
|
|
1520
|
+
return
|
|
1521
|
+
for action, target, detail in self.dry_run_plan:
|
|
1522
|
+
print(f"{CC.OKBLUE} *{CC.ENDC} would {action} {target}")
|
|
1523
|
+
for line in detail:
|
|
1524
|
+
print(f"{CC.OKCYAN} {line}{CC.ENDC}")
|
|
1525
|
+
counts = Counter(entry[0] for entry in self.dry_run_plan)
|
|
1526
|
+
summary = ", ".join(f"{count}x {action}" for action, count
|
|
1527
|
+
in sorted(counts.items()))
|
|
1528
|
+
print(f"{CC.WARNING} ** {CC.ENDC}{len(self.dry_run_plan)} "
|
|
1529
|
+
f"change(s) pending: {summary}")
|
|
1479
1530
|
|
|
1480
1531
|
def _export_hosts(self):
|
|
1481
1532
|
"""
|
|
@@ -2220,6 +2271,13 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2220
2271
|
a pending change, and on a large ruleset that is the slowest
|
|
2221
2272
|
part of the export by far.
|
|
2222
2273
|
"""
|
|
2274
|
+
if self.dry_run:
|
|
2275
|
+
# Every move is a POST, and the move chain is built from the
|
|
2276
|
+
# ids Checkmk hands back for the rules created in this run —
|
|
2277
|
+
# which a dry run never creates. There is nothing truthful to
|
|
2278
|
+
# plan here.
|
|
2279
|
+
print(f"{CC.OKGREEN} -- {CC.ENDC} Reorder skipped (dry run)")
|
|
2280
|
+
return
|
|
2223
2281
|
if self.config.get('skip_rule_reorder'):
|
|
2224
2282
|
print(f"{CC.OKGREEN} -- {CC.ENDC} Reorder skipped "
|
|
2225
2283
|
"(skip_rule_reorder is set on the account)")
|
|
@@ -2392,6 +2450,12 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2392
2450
|
# place update). No POST needed; the captured
|
|
2393
2451
|
# ``_cmk_id`` is what ``sort_rules`` will move.
|
|
2394
2452
|
continue
|
|
2453
|
+
if self.dry_run:
|
|
2454
|
+
self._plan('CREATE', f"a rule in {ruleset_name}",
|
|
2455
|
+
f"folder: {rule['folder']}",
|
|
2456
|
+
f"condition: {rule['condition']}",
|
|
2457
|
+
f"value: {rule['value']}")
|
|
2458
|
+
continue
|
|
2395
2459
|
print(f"{CC.OKBLUE} *{CC.ENDC} Create Rule in {ruleset_name} " \
|
|
2396
2460
|
f"({rule['condition']})")
|
|
2397
2461
|
url = "domain-types/rule/collections/all"
|
|
@@ -2469,7 +2533,8 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2469
2533
|
"""
|
|
2470
2534
|
wanted = rule.get('description') or self.rule_marker
|
|
2471
2535
|
properties = dict(cmk_rule['extensions']['properties'])
|
|
2472
|
-
|
|
2536
|
+
current = properties.get('description', '')
|
|
2537
|
+
if current == wanted:
|
|
2473
2538
|
return
|
|
2474
2539
|
properties['description'] = wanted
|
|
2475
2540
|
rule_id = cmk_rule['id']
|
|
@@ -2478,6 +2543,10 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2478
2543
|
"conditions": cmk_rule['extensions']['conditions'],
|
|
2479
2544
|
"value_raw": cmk_rule['extensions']['value_raw'],
|
|
2480
2545
|
}
|
|
2546
|
+
if self.dry_run:
|
|
2547
|
+
self._plan('UPDATE', f"{ruleset_name} {rule_id}",
|
|
2548
|
+
f"description: {current!r} -> {wanted!r}")
|
|
2549
|
+
return
|
|
2481
2550
|
try:
|
|
2482
2551
|
self.update_rule(rule_id, payload)
|
|
2483
2552
|
print(f"{CC.OKBLUE} *{CC.ENDC} UPDATE description of Rule in "
|
|
@@ -2559,6 +2628,25 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2559
2628
|
reason = ' and '.join(part.split(':', 1)[0] for part in mismatches)
|
|
2560
2629
|
return (f'{reason} changed', '; '.join(mismatches))
|
|
2561
2630
|
|
|
2631
|
+
@staticmethod
|
|
2632
|
+
def _keep_after_failed_update(our_rule, rule_id):
|
|
2633
|
+
"""
|
|
2634
|
+
Pair a rule Checkmk refused to update with the existing Checkmk rule
|
|
2635
|
+
instead of deleting it.
|
|
2636
|
+
|
|
2637
|
+
A rejected update means Checkmk does not accept the value we send —
|
|
2638
|
+
a create of the very same value fails for the same reason. Deleting
|
|
2639
|
+
the rule and letting the create fail afterwards leaves the target
|
|
2640
|
+
without any rule at all, and every following run repeats it. Keeping
|
|
2641
|
+
both sides untouched loses nothing: the error is reported, the
|
|
2642
|
+
existing rule keeps working, and the next run retries the update.
|
|
2643
|
+
|
|
2644
|
+
Returns True so the caller treats the rule as found.
|
|
2645
|
+
"""
|
|
2646
|
+
our_rule['_cmk_id'] = rule_id
|
|
2647
|
+
our_rule['_skip_create'] = True
|
|
2648
|
+
return True
|
|
2649
|
+
|
|
2562
2650
|
# pylint: disable=too-many-locals,too-many-branches,too-many-statements
|
|
2563
2651
|
def clean_rules(self):
|
|
2564
2652
|
"""
|
|
@@ -2709,6 +2797,19 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2709
2797
|
"conditions": our_rule['condition'],
|
|
2710
2798
|
"value_raw": our_rule['value'],
|
|
2711
2799
|
}
|
|
2800
|
+
if self.dry_run:
|
|
2801
|
+
self._plan(
|
|
2802
|
+
'UPDATE', f"{ruleset_name} {rule_id}",
|
|
2803
|
+
f"value: {our_rule['value']}",
|
|
2804
|
+
"changed: " + analyze_value_differences(
|
|
2805
|
+
condition_matches[0]['expected_value'],
|
|
2806
|
+
condition_matches[0]['actual_value']))
|
|
2807
|
+
# Pair it with the Checkmk rule the same way a
|
|
2808
|
+
# real update does, so the create step does not
|
|
2809
|
+
# plan a second rule for the same outcome.
|
|
2810
|
+
our_rule['_cmk_id'] = rule_id
|
|
2811
|
+
our_rule['_skip_create'] = True
|
|
2812
|
+
continue
|
|
2712
2813
|
try:
|
|
2713
2814
|
self.update_rule(rule_id, update_payload)
|
|
2714
2815
|
print(f"{CC.OKBLUE} *{CC.ENDC} UPDATE Rule in "
|
|
@@ -2725,6 +2826,8 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2725
2826
|
self.log_error(
|
|
2726
2827
|
f"Could not update Rule {rule_id} in "
|
|
2727
2828
|
f"{ruleset_name}: {error}")
|
|
2829
|
+
rule_found = self._keep_after_failed_update(
|
|
2830
|
+
our_rule, rule_id)
|
|
2728
2831
|
|
|
2729
2832
|
# A host entering or leaving a coalesced rule changed
|
|
2730
2833
|
# its condition, which used to read as "this rule is
|
|
@@ -2750,6 +2853,15 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2750
2853
|
"conditions": our_rule['condition'],
|
|
2751
2854
|
"value_raw": our_rule['value'],
|
|
2752
2855
|
}
|
|
2856
|
+
if self.dry_run:
|
|
2857
|
+
self._plan(
|
|
2858
|
+
'UPDATE', f"{ruleset_name} {rule_id}",
|
|
2859
|
+
f"host list: {len(cmk_hosts)} -> "
|
|
2860
|
+
f"{len(our_hosts)} hosts",
|
|
2861
|
+
f"value: {our_rule['value']}")
|
|
2862
|
+
our_rule['_cmk_id'] = rule_id
|
|
2863
|
+
our_rule['_skip_create'] = True
|
|
2864
|
+
continue
|
|
2753
2865
|
try:
|
|
2754
2866
|
self.update_rule(rule_id, update_payload)
|
|
2755
2867
|
print(f"{CC.OKBLUE} *{CC.ENDC} UPDATE host list of "
|
|
@@ -2768,6 +2880,8 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2768
2880
|
self.log_error(
|
|
2769
2881
|
f"Could not update host list of Rule {rule_id} "
|
|
2770
2882
|
f"in {ruleset_name}: {error}")
|
|
2883
|
+
rule_found = self._keep_after_failed_update(
|
|
2884
|
+
our_rule, rule_id)
|
|
2771
2885
|
|
|
2772
2886
|
# Only warn about flapping when there really are multiple
|
|
2773
2887
|
# conflicting matches — a single value drift is handled
|
|
@@ -2810,6 +2924,15 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2810
2924
|
rules, cmk_facts)
|
|
2811
2925
|
delete_reasons[reason] = \
|
|
2812
2926
|
delete_reasons.get(reason, 0) + 1
|
|
2927
|
+
if self.dry_run:
|
|
2928
|
+
detail = [f"reason: {reason}",
|
|
2929
|
+
f"detail: {reason_detail}",
|
|
2930
|
+
f"value: {value}"]
|
|
2931
|
+
if deletion_details:
|
|
2932
|
+
detail.append(deletion_details)
|
|
2933
|
+
self._plan('DELETE', f"{ruleset_name} {rule_id}",
|
|
2934
|
+
*detail)
|
|
2935
|
+
continue
|
|
2813
2936
|
print(f"{CC.OKBLUE} *{CC.ENDC} DELETE Rule in "
|
|
2814
2937
|
f"{ruleset_name} {rule_id} ({reason})")
|
|
2815
2938
|
if self.debug:
|
|
@@ -2852,9 +2975,12 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2852
2975
|
summary = ", ".join(
|
|
2853
2976
|
f"{count}x {reason}" for reason, count
|
|
2854
2977
|
in sorted(delete_reasons.items(), key=lambda x: -x[1]))
|
|
2855
|
-
|
|
2978
|
+
verb = "Would remove" if self.dry_run else "Removing"
|
|
2979
|
+
message = f"{verb} {total} rule(s) — reasons: {summary}"
|
|
2856
2980
|
print(f"{CC.WARNING} ** {CC.ENDC}{message}")
|
|
2857
|
-
if not self.debug:
|
|
2981
|
+
if not self.debug and not self.dry_run:
|
|
2982
|
+
# A dry run already prints the difference behind every
|
|
2983
|
+
# planned deletion in its report.
|
|
2858
2984
|
print(f"{CC.OKCYAN} ** {CC.ENDC}Run with --debug to see the "
|
|
2859
2985
|
f"difference behind each deletion")
|
|
2860
2986
|
self.log_details.append(("INFO", message))
|
|
@@ -2897,6 +3023,11 @@ class CheckmkRuleSync(CMK2): # pylint: disable=too-many-instance-attributes
|
|
|
2897
3023
|
if not self._owns_rule(cmk_rule):
|
|
2898
3024
|
continue
|
|
2899
3025
|
rule_id = cmk_rule['id']
|
|
3026
|
+
if self.dry_run:
|
|
3027
|
+
self._plan('DELETE', f"{ruleset_name} {rule_id}",
|
|
3028
|
+
"reason: orphaned, this ruleset is not "
|
|
3029
|
+
"generated any more")
|
|
3030
|
+
continue
|
|
2900
3031
|
print(f"{CC.OKBLUE} *{CC.ENDC} DELETE orphaned Rule in "
|
|
2901
3032
|
f"{ruleset_name} {rule_id}")
|
|
2902
3033
|
try:
|
|
@@ -420,7 +420,7 @@ def projects_for_account(account):
|
|
|
420
420
|
]
|
|
421
421
|
|
|
422
422
|
|
|
423
|
-
def export_rules(account, debug=False):
|
|
423
|
+
def export_rules(account, dry_run=False, debug=False):
|
|
424
424
|
"""
|
|
425
425
|
Create Rules in Checkmk
|
|
426
426
|
"""
|
|
@@ -429,6 +429,7 @@ def export_rules(account, debug=False):
|
|
|
429
429
|
rules = _load_rules()
|
|
430
430
|
syncer = CheckmkRuleSync(account)
|
|
431
431
|
syncer.debug = debug
|
|
432
|
+
syncer.dry_run = dry_run
|
|
432
433
|
syncer.filter = rules['filter']
|
|
433
434
|
syncer.rewrite = rules['rewrite']
|
|
434
435
|
|
|
@@ -462,7 +463,12 @@ def export_rules(account, debug=False):
|
|
|
462
463
|
syncer.source = "cmk_rule_sync"
|
|
463
464
|
syncer.export_cmk_rules()
|
|
464
465
|
except CmkException as error_obj:
|
|
465
|
-
|
|
466
|
+
# Same contract as the other export commands: --debug gives the
|
|
467
|
+
# traceback instead of the one-line message, so a failing export
|
|
468
|
+
# can be debugged without editing code.
|
|
469
|
+
if debug:
|
|
470
|
+
raise
|
|
471
|
+
print(f'{ColorCodes.FAIL}CMK Connection Error: {error_obj} {ColorCodes.ENDC}')
|
|
466
472
|
if syncer is not None:
|
|
467
473
|
syncer.record_exception(error_obj)
|
|
468
474
|
else:
|