cmdbsyncer 4.5.0.dev0__py3-none-any.whl → 4.5.0.dev2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
application/buildinfo.txt CHANGED
@@ -1 +1 @@
1
- BUILD_DATE=2026-10-29T12:50:13Z
1
+ BUILD_DATE=2026-10-30T08:47:03Z
@@ -1,6 +1,7 @@
1
1
  # Version 4.4
2
2
 
3
3
  ## Unreleased
4
+ - FIX: Checkmk: Manage OMD Server creates a missing site again, including the initial cmkadmin password, instead of failing on the update step
4
5
  - FIX: REST import: entries without the hostname field are skipped instead of aborting the whole import
5
6
  - FIX: Checkmk users: an empty row under Roles or Contact Groups is no longer sent to Checkmk, which rejected the user because of it
6
7
  - FIX: Files: creating a folder, uploading, renaming or editing a file works again when the syncer runs under a sub-path such as /cmdbsyncer — the dialog sent its form to the address without that path
@@ -2,6 +2,9 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - FEAT: Checkmk Settings: a Run Playbook button on every entry, and the list action Run Manage OMD Server, install or update Checkmk right from the settings, only on the servers of the enabled sites that use them; the list shows only name, documentation, version and server user
6
+ - FEAT: New OP5 Monitor import: `op5 import_hosts` and `op5 inventorize_hosts` read all hosts with address, alias, host groups, contacts, contact groups, parents and custom variables from an account of type OP5 Monitor
7
+ - FEAT: New Ansible playbook `deploy_configs/install/install_redhat.yml` installs the Syncer on RedHat, Rocky or Alma with MongoDB, Gunicorn and Apache, either as its own virtual host or under a sub-path, served over HTTPS
5
8
  - FEAT: API: the cron status (`/api/v1/syncer/cron/`) tells whether a cron group is enabled, so the Checkmk plugin no longer monitors disabled or deleted cron groups
6
9
  - FEAT: Checkmk: new Manage LDAP Connections maintains the LDAP connections Checkmk logs its users in with, including contact groups and roles from directory groups; server and bind password come from an LDAP account, `checkmk export_ldap_connections` creates, updates or removes them
7
10
  - FEAT: `rules export_all_rules --zip` writes the export compressed into a zip archive, and `rules import_rules` reads such an archive back as it is
@@ -26,6 +26,7 @@ from flask_admin.contrib.mongoengine.filters import (
26
26
  from flask import redirect, url_for, request, render_template, flash
27
27
 
28
28
  from flask_login import current_user
29
+ from flask_wtf.csrf import generate_csrf
29
30
  from application import app
30
31
  from application.views.default import DefaultModelView
31
32
  from application.models.account import Account, CustomEntry
@@ -41,6 +42,7 @@ from application.modules.rule.views import (
41
42
  )
42
43
  from application.views._form_sections import modern_form, section
43
44
  from application.models.project import Project
45
+ from application.plugins.ansible.runner import run_playbook
44
46
  from application.helpers.syncer_jinja import check_jinja_syntax
45
47
  from application.modules.rule.list_source import is_list_rule, rule_uses_list
46
48
  from application.modules.rule.list_source_views import (
@@ -1633,6 +1635,20 @@ class CheckmkUserMngmtView(DefaultModelView):
1633
1635
 
1634
1636
 
1635
1637
 
1638
+ def _render_run_server_mngmt(_view, _context, model, _name):
1639
+ """Button that starts Manage OMD Server for the sites of these settings"""
1640
+ run_url = url_for('.run_server_mngmt', settings_id=model.id)
1641
+ return Markup(
1642
+ f'<form method="POST" action="{escape(run_url)}" style="display:inline" '
1643
+ f"onsubmit=\"return confirm('Install or update Checkmk on the servers "
1644
+ f"of the enabled sites that use these settings?');\">"
1645
+ f'<input type="hidden" name="csrf_token" value="{escape(generate_csrf())}">'
1646
+ f'<button class="btn btn-primary btn-sm" type="submit">'
1647
+ f'<i class="fa fa-play"></i> Run Playbook</button>'
1648
+ f'</form>'
1649
+ )
1650
+
1651
+
1636
1652
  class CheckmkSettingsView(DefaultModelView):
1637
1653
  """
1638
1654
  Checkmk Server Settings View
@@ -1748,13 +1764,15 @@ class CheckmkSettingsView(DefaultModelView):
1748
1764
  ),
1749
1765
  ]
1750
1766
 
1751
- column_exclude_list = [
1752
- 'inital_password',
1753
- 'subscription_username',
1754
- 'subscription_password',
1755
- 'download_proxy',
1756
- 'cmk_secret',
1757
- ]
1767
+ column_list = ('name', 'documentation', 'cmk_version', 'server_user', 'run_playbook')
1768
+
1769
+ column_formatters = {
1770
+ 'run_playbook': _render_run_server_mngmt,
1771
+ }
1772
+
1773
+ column_labels = {
1774
+ 'run_playbook': 'Manage OMD Server',
1775
+ }
1758
1776
 
1759
1777
  # Fill-in help for version and filename, see _checkmk_download_help.html
1760
1778
  create_template = 'admin/checkmk_settings_create.html'
@@ -1805,6 +1823,45 @@ class CheckmkSettingsView(DefaultModelView):
1805
1823
  url = url_for('.set_cmk_version_form', ids=','.join(ids))
1806
1824
  return redirect(url)
1807
1825
 
1826
+ @action('run_server_mngmt', 'Run Manage OMD Server',
1827
+ 'Install or update Checkmk on the servers of the enabled sites '
1828
+ 'that use the selected settings?')
1829
+ def action_run_server_mngmt(self, ids):
1830
+ """
1831
+ Action to start Manage OMD Server for the selected Entries
1832
+ """
1833
+ return self._run_server_mngmt(ids)
1834
+
1835
+ @expose('/run/<settings_id>', methods=('POST',))
1836
+ def run_server_mngmt(self, settings_id):
1837
+ """
1838
+ Run button of a single row
1839
+ """
1840
+ return self._run_server_mngmt([settings_id])
1841
+
1842
+ def _run_server_mngmt(self, ids):
1843
+ """
1844
+ Start the Manage OMD Server playbook, limited to the servers of the
1845
+ enabled sites that use the given settings
1846
+ """
1847
+ if not current_user.has_right('ansible'):
1848
+ flash('Running playbooks needs the Ansible right', 'error')
1849
+ return redirect(url_for('.index_view'))
1850
+ settings = list(CheckmkSettings.objects(id__in=ids))
1851
+ servers = sorted({site.server_address for site in
1852
+ CheckmkSite.objects(settings_master__in=settings, enabled=True)})
1853
+ if not servers:
1854
+ flash('No enabled site uses the selected settings', 'error')
1855
+ return redirect(url_for('.index_view'))
1856
+ stats = run_playbook(
1857
+ 'cmk_server_mngmt.yml',
1858
+ target_host=','.join(servers),
1859
+ source='ui',
1860
+ triggered_by=current_user.email,
1861
+ )
1862
+ flash(f"Run started for {', '.join(servers)}", 'success')
1863
+ return redirect(url_for('ansiblerunstats.details_view', id=str(stats.pk)))
1864
+
1808
1865
  @expose('/set_cmk_version_form')
1809
1866
  def set_cmk_version_form(self):
1810
1867
  """
@@ -0,0 +1,42 @@
1
+ """OP5 Monitor plugin."""
2
+ import click
3
+ from application import app
4
+ from application.helpers.plugins import register_cli_group
5
+
6
+ from syncerapi.v1 import register_cronjob
7
+
8
+ from .op5 import inventorize_op5, import_op5
9
+
10
+ op5_cli = register_cli_group(app, 'op5', 'op5', "OP5 Monitor Commands")
11
+
12
+ @op5_cli.command('import_hosts')
13
+ @click.argument("account")
14
+ @click.option("--debug", is_flag=True)
15
+ def cmd_import_op5(account, debug):
16
+ """
17
+ Import Hosts from OP5 Monitor
18
+ """
19
+ try:
20
+ import_op5(account, debug)
21
+ except Exception as error: # pylint: disable=broad-exception-caught
22
+ if debug:
23
+ raise
24
+ print(f"Error: {error}")
25
+
26
+ register_cronjob('OP5 Monitor: Import Hosts', import_op5)
27
+
28
+ @op5_cli.command('inventorize_hosts')
29
+ @click.argument("account")
30
+ @click.option("--debug", is_flag=True)
31
+ def cmd_inventorize_op5(account, debug):
32
+ """
33
+ Inventorize Hosts from OP5 Monitor
34
+ """
35
+ try:
36
+ inventorize_op5(account, debug)
37
+ except Exception as error: # pylint: disable=broad-exception-caught
38
+ if debug:
39
+ raise
40
+ print(f"Error: {error}")
41
+
42
+ register_cronjob('OP5 Monitor: Inventorize Hosts', inventorize_op5)
@@ -0,0 +1,127 @@
1
+ """
2
+ Import Hosts from OP5 Monitor
3
+
4
+ Reads the hosts through the filter API of OP5 Monitor:
5
+ GET /api/filter/query?query=[hosts] all&columns=...&format=json
6
+
7
+ API Output (one entry per host):
8
+ [{'name': 'web01',
9
+ 'alias': 'Webserver 01',
10
+ 'display_name': 'web01',
11
+ 'address': '10.0.0.1',
12
+ 'groups': ['linux', 'web'],
13
+ 'contacts': ['admin'],
14
+ 'contact_groups': ['linux-admins'],
15
+ 'parents': ['switch01'],
16
+ 'notes': '',
17
+ 'custom_variables': {'LOCATION': 'Berlin'}}]
18
+ """
19
+ from syncerapi.v1 import (
20
+ cc,
21
+ )
22
+
23
+ from application.modules.plugin import Plugin
24
+ from application.helpers.inventory import run_inventory
25
+ from application.helpers.import_hostnames import get_import_hosts, update_import_host
26
+
27
+ DEFAULT_COLUMNS = [
28
+ "name", "alias", "display_name", "address", "groups", "contacts",
29
+ "contact_groups", "parents", "notes", "custom_variables",
30
+ ]
31
+
32
+
33
+ class Op5(Plugin):
34
+ """
35
+ OP5 Monitor Import
36
+ """
37
+ page_size = 1000
38
+
39
+ def columns(self):
40
+ """
41
+ Columns to request, the account field `columns` overrides the default.
42
+ The hostname column `name` is always part of the request.
43
+ """
44
+ configured = [x.strip() for x in self.config.get('columns', '').split(',')
45
+ if x.strip()]
46
+ columns = configured or list(DEFAULT_COLUMNS)
47
+ if 'name' not in columns:
48
+ columns.insert(0, 'name')
49
+ return columns
50
+
51
+ @staticmethod
52
+ def prepare_attributes(host):
53
+ """
54
+ Flatten the custom variables of a host into own attributes,
55
+ so they can be used like every other attribute.
56
+ """
57
+ attributes = dict(host)
58
+ custom_variables = attributes.pop('custom_variables', None)
59
+ if isinstance(custom_variables, dict):
60
+ for key, value in custom_variables.items():
61
+ attributes[f'custom_variable_{key.lower()}'] = value
62
+ return attributes
63
+
64
+ def get_hosts(self):
65
+ """
66
+ Return Hostname and Attributes of every host, paging through the API
67
+ """
68
+ url = f"{self.config['address'].rstrip('/')}/api/filter/query"
69
+ auth = (self.config['username'], self.config['password'])
70
+ print(f"{cc.OKGREEN} -- {cc.ENDC}Request: Read all Hosts")
71
+
72
+ offset = 0
73
+ while True:
74
+ params = {
75
+ "query": "[hosts] all",
76
+ "columns": ",".join(self.columns()),
77
+ "format": "json",
78
+ "limit": str(self.page_size),
79
+ "offset": str(offset),
80
+ }
81
+ response = self.inner_request(method="GET", url=url, params=params, auth=auth)
82
+ hosts = response.json()
83
+ if not isinstance(hosts, list):
84
+ raise ValueError(f"Unexpected answer from OP5: {hosts}")
85
+ for host in hosts:
86
+ yield host['name'], self.prepare_attributes(host)
87
+
88
+ if len(hosts) < self.page_size:
89
+ return
90
+ offset += len(hosts)
91
+
92
+ def import_objects(self):
93
+ """
94
+ Import Hosts from OP5
95
+ """
96
+ for hostname, attributes in self.get_hosts():
97
+ for name, host_obj in get_import_hosts(hostname, self.config, attributes):
98
+ print(f" {cc.OKGREEN}** {cc.ENDC} Update {name}")
99
+ update_import_host(host_obj, attributes, self.config)
100
+
101
+ def inventorize_objects(self):
102
+ """
103
+ Inventorize OP5 Hosts
104
+ """
105
+ run_inventory(self.config, self.get_hosts())
106
+
107
+ def import_op5(account, debug=False):
108
+ """
109
+ Import
110
+ """
111
+ op5 = Op5(account)
112
+ op5.debug = debug
113
+ op5.name = "OP5 Monitor: Import Hosts"
114
+ op5.source = "op5_import"
115
+
116
+ op5.import_objects()
117
+
118
+ def inventorize_op5(account, debug=False):
119
+ """
120
+ Inventorize
121
+ """
122
+ op5 = Op5(account)
123
+ op5.debug = debug
124
+ op5.name = "OP5 Monitor: Inventorize Hosts"
125
+ op5.source = "op5_inventorize"
126
+
127
+ op5.inventorize_objects()
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "author": "Kuhn & Rueß GmbH",
4
+ "name": "OP5 Monitor",
5
+ "description": "",
6
+ "ident": "op5",
7
+ "account_presets" : {
8
+ "address": "https://op5server"
9
+ },
10
+ "account_custom_field_presets": {
11
+ "columns": "",
12
+ "rewrite_hostname": ""
13
+ }
14
+ }
@@ -0,0 +1,3 @@
1
+ # pylint: disable=unused-import
2
+ """Bootstrap test stubs before any test in this package runs."""
3
+ import tests # noqa: F401 — triggers MongoDB stub setup
@@ -0,0 +1,68 @@
1
+ """
2
+ Unit tests for the OP5 Monitor import
3
+ """
4
+ # pylint: disable=missing-function-docstring
5
+ import unittest
6
+ from unittest.mock import MagicMock
7
+
8
+ from application.plugins.op5.op5 import Op5, DEFAULT_COLUMNS
9
+
10
+
11
+ def make_op5(columns=''):
12
+ op5 = Op5.__new__(Op5)
13
+ op5.config = {
14
+ 'address': 'https://op5.example.com/',
15
+ 'username': 'user',
16
+ 'password': 'secret',
17
+ 'columns': columns,
18
+ }
19
+ return op5
20
+
21
+
22
+ class TestOp5(unittest.TestCase):
23
+ """Tests for the OP5 host import"""
24
+
25
+ def test_default_columns(self):
26
+ self.assertEqual(make_op5().columns(), DEFAULT_COLUMNS)
27
+
28
+ def test_configured_columns_always_contain_name(self):
29
+ self.assertEqual(make_op5('address, groups').columns(),
30
+ ['name', 'address', 'groups'])
31
+
32
+ def test_custom_variables_are_flattened(self):
33
+ attributes = Op5.prepare_attributes({
34
+ 'name': 'web01',
35
+ 'groups': ['linux'],
36
+ 'custom_variables': {'LOCATION': 'Berlin'},
37
+ })
38
+ self.assertEqual(attributes, {
39
+ 'name': 'web01',
40
+ 'groups': ['linux'],
41
+ 'custom_variable_location': 'Berlin',
42
+ })
43
+
44
+ def test_get_hosts_pages_through_api(self):
45
+ op5 = make_op5()
46
+ op5.page_size = 2
47
+ pages = [
48
+ [{'name': 'a'}, {'name': 'b'}],
49
+ [{'name': 'c'}],
50
+ ]
51
+ op5.inner_request = MagicMock(side_effect=[
52
+ MagicMock(json=MagicMock(return_value=page)) for page in pages
53
+ ])
54
+ hostnames = [name for name, _ in op5.get_hosts()]
55
+ self.assertEqual(hostnames, ['a', 'b', 'c'])
56
+
57
+ first_call = op5.inner_request.call_args_list[0].kwargs
58
+ self.assertEqual(first_call['url'], 'https://op5.example.com/api/filter/query')
59
+ self.assertEqual(first_call['auth'], ('user', 'secret'))
60
+ self.assertEqual(first_call['params']['query'], '[hosts] all')
61
+ self.assertEqual(op5.inner_request.call_args_list[1].kwargs['params']['offset'], '2')
62
+
63
+ def test_error_answer_raises(self):
64
+ op5 = make_op5()
65
+ op5.inner_request = MagicMock(return_value=MagicMock(
66
+ json=MagicMock(return_value={'error': 'Invalid column'})))
67
+ with self.assertRaises(ValueError):
68
+ list(op5.get_hosts())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cmdbsyncer
3
- Version: 4.5.0.dev0
3
+ Version: 4.5.0.dev2
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>
@@ -1,6 +1,6 @@
1
1
  application/__init__.py,sha256=nwF50GpnnZUPxy1kXeGGEs9h6P0gPkSvP6OzBXqhA3Y,42999
2
2
  application/_version.py,sha256=Rp3Xm2D2paRYXafU_J5TeWJQ22T59w3SCa3FT6mLcnU,4984
3
- application/buildinfo.txt,sha256=hrmQks2hk-DH_BLVvSajEn_q_9etGKthZpRwQ2c12CM,32
3
+ application/buildinfo.txt,sha256=hgBzXLLFsEs45rO3TEvovNZeARshO7zpqES3Pm04Ifg,32
4
4
  application/cli.py,sha256=_0tot__uwf5Mca2NzR0UI5FG3nKSG6GRzKfrT076SjI,2796
5
5
  application/config.py,sha256=-I_dMuLRIU4CYdn8CuDnvjiGPICWruPtItYMKSatgWs,18026
6
6
  application/docu_links.py,sha256=m-CLsihNir_ZC65fhsQJHV6-kZUsM3ghmdnLqOufZDU,2321
@@ -28,8 +28,8 @@ application/changelog/v4.0.md,sha256=RfQYUXPCMQH3XtmCIh3TWrmOpS0B3H6OHj2iUd26bQs
28
28
  application/changelog/v4.1.md,sha256=KOF_PehHHb6-Caba20OGMX0fhiWOQj9rCLiLQOkOTAU,18480
29
29
  application/changelog/v4.2.md,sha256=nixJTe0YmqNSDDZsWWmliYd7jP_25i7x_c8lL0Z2c68,28174
30
30
  application/changelog/v4.3.md,sha256=Zz10d4gqVYA3FlZhQS-lHvxklDoGkDzrrj-KRdz2C1I,53518
31
- application/changelog/v4.4.md,sha256=QAkjtLkT6cFGQPr85ONuwggssZKM5g_8tG9OCVklxl0,13368
32
- application/changelog/v4.5.md,sha256=WajBAhKCyfm8zK3YDzWuL9N9a5QyCZZw7Uinz7ZEoWI,6458
31
+ application/changelog/v4.4.md,sha256=bNX7cGY0avWyIgqYWnYOw3WmqedqFbB0KOhdS3wHeR0,13511
32
+ application/changelog/v4.5.md,sha256=WbaC1MLzcZTMoJz-NYCKuBVU3lIZxLq-4iWD_QDMY-4,7179
33
33
  application/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  application/helpers/audit.py,sha256=wwhQY8dYEmjHn_ofXTJml7177dBmJVVjB9bCDOcMBcQ,2763
35
35
  application/helpers/cron.py,sha256=PO0O3nZSserEEvquGDzQzvJGqOjLHOz1oQfbJd8FVeg,1523
@@ -165,7 +165,7 @@ application/plugins/checkmk/tags.py,sha256=yuyT4-kNSmGMu79cav0HuMfUnnbrEVfXGcaeJ
165
165
  application/plugins/checkmk/user_generation.py,sha256=3YaF07sVpJtzGcmyx1lVy3VdnVNiplJcXJ9V3Kh3ZiI,16644
166
166
  application/plugins/checkmk/user_models.py,sha256=BxfZ3d9SRaim4sbBwUpQCp1VoKCBItzGdPmNfrUupVQ,3424
167
167
  application/plugins/checkmk/users.py,sha256=Mo5DhK0hPQuQUOk-kf4-xiE_FzIsKA08hqRllr1Dr-k,5012
168
- application/plugins/checkmk/views.py,sha256=J8pEVMOAt9NsyBKkDsg1WokQ-ksIMVOnC6MnB5WPsT4,132236
168
+ application/plugins/checkmk/views.py,sha256=hPjopHzB-oYsQ7K2Nzc7591vqJYFRylVHhrUGfR7eRE,134727
169
169
  application/plugins/checkmk/config_checks/__init__.py,sha256=NVBl0yf06RKNoR2XC2cWrv-d-DZlaMgwDhMXBCwJHfo,2534
170
170
  application/plugins/checkmk/config_checks/base.py,sha256=ZkRnOljleB5TQFbMz9GTl4zYGP6tObtQLCKmNO_xhKI,7207
171
171
  application/plugins/checkmk/config_checks/httpv2.py,sha256=Z36CZFk_9CTyWiGhYLvhCaqGbXwv2Zgs7AP3tmhhwB0,18757
@@ -286,6 +286,11 @@ application/plugins/netbox/views.py,sha256=D9CkKtVlc3QsG1R7L6ru946RZpCTkYDW8LVGc
286
286
  application/plugins/netbox/virtualmachines.py,sha256=gCJJEJmP_qVUYkLlzyOlWUsA-VsIPHNS7LOx9T9-W2I,8455
287
287
  application/plugins/netbox/tests/__init__.py,sha256=CGtM5yR5jhAqYPKQ3QMeypStf8rV5uMYBlvFL2g-m8o,179
288
288
  application/plugins/netbox/tests/test_import_filter.py,sha256=fhTXZkeN7I1MUnk5j0gd0hJpe8OuxwWfPparqpv1NZo,1518
289
+ application/plugins/op5/__init__.py,sha256=DtlDqq_76ZQJN9H36X1T-bo2qYA0hVDZfJ5tBjAPS7o,1180
290
+ application/plugins/op5/op5.py,sha256=xH0prYaSu6EttG1ljfTBWQ-NohUTiMT76AFEsdIzmXg,3906
291
+ application/plugins/op5/plugin.json,sha256=5rFZF97dfkRBiAEjXWut9IuZny0LYDnAQed7zVqNZBo,303
292
+ application/plugins/op5/tests/__init__.py,sha256=Tmpw63lKGMB8wOVwpYaSYSZBrd7G0SiuKPccGY0UyeU,156
293
+ application/plugins/op5/tests/test_op5.py,sha256=wq20NrlS8iDlXRaRasxYs0DQu4cmb_RMsMHqKjPmxTE,2289
289
294
  application/plugins/prtg/__init__.py,sha256=lk4bBeaAmdPTxoZQcVXs146B6dyPWjzIaN8eGte4bfA,1208
290
295
  application/plugins/prtg/plugin.json,sha256=G_6cYQ7JdaKmRuzyPgg41amd4ltSxVIiy-lmFJ3Vzxs,203
291
296
  application/plugins/prtg/prtg.py,sha256=51vABi8hJhHQ1FIR5VBotACrwIqOh36jULrMoDrFlg4,5356
@@ -463,14 +468,14 @@ application/views/saved_search.py,sha256=74neyShEo6Un9_QidWlnq1AP4mRVwJU81jmhb_L
463
468
  application/views/secret.py,sha256=P6zBz7XHnIP0Bzm-i25RlZsk2AW6z5MdliVvq05l2tQ,9189
464
469
  application/views/template_select.py,sha256=r47g73G12ns0Jy1yFIdk29GRQcyz0iKOoG0RoxF84OA,1400
465
470
  application/views/user.py,sha256=v2EgNpIdFS5mkh6o_twwOtsYr9wjFsZYhvheV0ksyS0,7452
466
- cmdbsyncer-4.5.0.dev0.dist-info/licenses/LICENSE,sha256=DVv8r0UqeEvN8her1jX1q6YN6LrvH3-ShkMyqrR6GfE,1074
471
+ cmdbsyncer-4.5.0.dev2.dist-info/licenses/LICENSE,sha256=DVv8r0UqeEvN8her1jX1q6YN6LrvH3-ShkMyqrR6GfE,1074
467
472
  syncerapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
468
473
  syncerapi/v1/__init__.py,sha256=9oXSdm0IaMWVocloHTHz_uENT9jkg2cvkxHwdsE9ZHw,373
469
474
  syncerapi/v1/core/__init__.py,sha256=XEMuQk__Al5xaAoTblE3oA_5Nm5mhiPFh42XzBguz4I,145
470
475
  syncerapi/v1/inventory/__init__.py,sha256=ha42PlENxRMxcby2dEln5gi1QNXslN7JobfJDwqUNV8,56
471
476
  syncerapi/v1/rest/__init__.py,sha256=oZyMxM2GR_HZqJwwKA792R7_WIyC7c7pjNKmojuQVyE,80
472
- cmdbsyncer-4.5.0.dev0.dist-info/METADATA,sha256=KGyTCXXGhbp4y792NxoIYuC43ki0Hfk0tvvWyGIvQ1o,16176
473
- cmdbsyncer-4.5.0.dev0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
474
- cmdbsyncer-4.5.0.dev0.dist-info/entry_points.txt,sha256=7a8-5HWHxYmAtsHXjHeulkt-WuiSmOxY-rUeVJkCJsU,146
475
- cmdbsyncer-4.5.0.dev0.dist-info/top_level.txt,sha256=_pz8teBZyHwwtYWSkgCZSlIhASrTDxQ_PcmUdHe3cnE,22
476
- cmdbsyncer-4.5.0.dev0.dist-info/RECORD,,
477
+ cmdbsyncer-4.5.0.dev2.dist-info/METADATA,sha256=urz9m6J2rCVRzrZFujDtFU3DfMSsySy-aJ2khwnAuiY,16176
478
+ cmdbsyncer-4.5.0.dev2.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
479
+ cmdbsyncer-4.5.0.dev2.dist-info/entry_points.txt,sha256=7a8-5HWHxYmAtsHXjHeulkt-WuiSmOxY-rUeVJkCJsU,146
480
+ cmdbsyncer-4.5.0.dev2.dist-info/top_level.txt,sha256=_pz8teBZyHwwtYWSkgCZSlIhASrTDxQ_PcmUdHe3cnE,22
481
+ cmdbsyncer-4.5.0.dev2.dist-info/RECORD,,