Skip to content

Commit cc1337b

Browse files
committed
Merge branch 'build/checkmk-24-support' of github.com:Checkmk/ansible-collection-checkmk.general into build/checkmk-24-support
2 parents 52dc3f5 + 71ebf30 commit cc1337b

File tree

9 files changed

+1089
-289
lines changed

9 files changed

+1089
-289
lines changed

plugins/module_utils/api.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626
class CheckmkAPI:
2727
"""Base class to contact a Checkmk server"""
2828

29-
def __init__(self, module):
29+
def __init__(self, module, logger=None):
3030
self.module = module
31+
self.logger = logger
3132
self.params = self.module.params
3233
server = self.params.get("server_url")
3334
site = self.params.get("site")
@@ -47,6 +48,18 @@ def __init__(self, module):
4748
def _fetch(
4849
self, code_mapping="", endpoint="", data=None, method="GET", logger=None
4950
):
51+
if not logger:
52+
logger = self.logger
53+
54+
if logger:
55+
logger.debug(
56+
"_fetch(): endpoint: %s, data: %s, method: %s"
57+
% (
58+
endpoint,
59+
str(data),
60+
method,
61+
)
62+
)
5063
http_mapping = GENERIC_HTTP_CODES.copy()
5164
http_mapping.update(code_mapping)
5265

@@ -100,6 +113,8 @@ def _fetch(
100113
logger=logger,
101114
)
102115
# self.module.fail_json(**result_as_dict(result))
116+
if logger:
117+
logger.debug("_fetch(): result: %s" % str(result))
103118
return result
104119

105120
def getversion(self):

plugins/module_utils/discovery.py

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8; py-indent-offset: 4 -*-
3+
4+
# Copyright: (c) 2022, Michael Sekania &
5+
# Robin Gierse <[email protected]>
6+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
7+
from __future__ import absolute_import, division, print_function
8+
9+
__metaclass__ = type
10+
11+
from ansible_collections.checkmk.general.plugins.module_utils.version import (
12+
CheckmkVersion,
13+
)
14+
15+
# from .version import CheckmkVersion
16+
17+
HTTP_CODES = {
18+
# http_code: (changed, failed, "Message")
19+
200: (True, False, "Discovery successful."),
20+
302: (
21+
True,
22+
False,
23+
(
24+
"The service discovery background job has been initialized. "
25+
"Redirecting to the 'Wait for service discovery completion' endpoint."
26+
),
27+
),
28+
404: (False, True, "Not Found: Host could not be found."),
29+
409: (False, False, "Conflict: A discovery background job is already running"),
30+
}
31+
32+
HTTP_CODES_SC = {
33+
# http_code: (changed, failed, "Message")
34+
200: (True, False, "The service discovery has been completed."),
35+
302: (
36+
True,
37+
False,
38+
(
39+
"The service discovery is still running. "
40+
"Redirecting to the 'Wait for completion' endpoint."
41+
),
42+
),
43+
404: (False, False, "Not Found: There is no running service discovery"),
44+
}
45+
46+
HTTP_CODES_BULK = {
47+
# http_code: (changed, failed, "Message")
48+
200: (True, False, "Discovery successful."),
49+
409: (False, False, "Conflict: A bulk discovery job is already active"),
50+
}
51+
52+
HTTP_CODES_BULK_SC = {
53+
# http_code: (changed, failed, "Message")
54+
200: (True, False, "The service discovery has been completed."),
55+
404: (False, False, "Not Found: There is no running bulk_discovery job"),
56+
}
57+
58+
SUPPORTED_VERSIONS = {
59+
"min": "2.1.0",
60+
"max": "2.5.0",
61+
}
62+
63+
64+
class Discovery:
65+
def __init__(self, module, logger):
66+
self.module = module
67+
self.logger = logger
68+
self.timeout = module.params.get("wait_timeout", -1)
69+
self.wait_for_previous = module.params.get("wait_for_previous", True)
70+
self.wait_for_completion = module.params.get("wait_for_completion", True)
71+
self.single_mode = self._single_mode()
72+
self.bulk_mode = not self.single_mode
73+
self.supported_versions = SUPPORTED_VERSIONS
74+
75+
def _single_mode(self):
76+
return not (
77+
"hosts" in self.module.params
78+
and self.module.params.get("hosts")
79+
and len(self.module.params.get("hosts", [])) > 0
80+
)
81+
82+
def _min_version(self):
83+
return CheckmkVersion(self.supported_versions["min"])
84+
85+
def _max_version(self):
86+
return CheckmkVersion(self.supported_versions["max"])
87+
88+
def compatible(self, version):
89+
return self._min_version() <= version <= self._max_version()
90+
91+
def start_discovery(self):
92+
raise NotImplementedError

plugins/module_utils/discovery_210.py

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8; py-indent-offset: 4 -*-
3+
4+
# Copyright: (c) 2022 - 2025,
5+
# Michael Sekania &
6+
# Robin Gierse <[email protected]> &
7+
# Max Sickora <[email protected]> &
8+
# Lars Getwan <[email protected]>
9+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
10+
11+
from __future__ import absolute_import, division, print_function
12+
13+
__metaclass__ = type
14+
15+
import json
16+
import time
17+
18+
from ansible_collections.checkmk.general.plugins.module_utils.api import CheckmkAPI
19+
from ansible_collections.checkmk.general.plugins.module_utils.discovery import (
20+
HTTP_CODES,
21+
HTTP_CODES_BULK,
22+
HTTP_CODES_BULK_SC,
23+
HTTP_CODES_SC,
24+
Discovery,
25+
)
26+
from ansible_collections.checkmk.general.plugins.module_utils.types import (
27+
generate_result,
28+
)
29+
30+
COMPATIBLE_MODES = [
31+
"new",
32+
"remove",
33+
"fix_all",
34+
"refresh",
35+
"only_host_labels",
36+
]
37+
38+
SUPPORTED_VERSIONS = {
39+
"min": "2.1.0",
40+
"max": "2.1.0p99",
41+
}
42+
43+
44+
class ServiceDiscoveryAPI(CheckmkAPI):
45+
def post(self):
46+
mode = self.params.get("state")
47+
if mode not in COMPATIBLE_MODES:
48+
return generate_result(
49+
msg="State %s is not supported with this Checkmk version." % mode
50+
)
51+
52+
data = {
53+
"host_name": self.params.get("host_name"),
54+
"mode": mode,
55+
}
56+
57+
return self._fetch(
58+
code_mapping=HTTP_CODES,
59+
endpoint="domain-types/service_discovery_run/actions/start/invoke",
60+
data=data,
61+
method="POST",
62+
logger=self.logger,
63+
)
64+
65+
66+
class ServiceBulkDiscoveryAPI(CheckmkAPI):
67+
def post(self):
68+
mode = self.params.get("state")
69+
if mode not in COMPATIBLE_MODES:
70+
return generate_result(
71+
msg="State %s is not supported with this Checkmk version." % mode
72+
)
73+
74+
data = {
75+
"hostnames": self.params.get("hosts", []),
76+
"mode": self.params.get("state"),
77+
"do_full_scan": self.params.get("do_full_scan", True),
78+
"bulk_size": self.params.get("bulk_size", 1),
79+
"ignore_errors": self.params.get("ignore_errors", True),
80+
}
81+
82+
return self._fetch(
83+
code_mapping=HTTP_CODES_BULK,
84+
endpoint="domain-types/discovery_run/actions/bulk-discovery-start/invoke",
85+
data=data,
86+
method="POST",
87+
)
88+
89+
90+
class ServiceCompletionAPI(CheckmkAPI):
91+
def get(self):
92+
data = {}
93+
94+
return self._fetch(
95+
code_mapping=HTTP_CODES_SC,
96+
endpoint=("objects/service_discovery_run/" + self.params.get("host_name")),
97+
data=data,
98+
method="GET",
99+
)
100+
101+
102+
class ServiceCompletionBulkAPI(CheckmkAPI):
103+
def get(self):
104+
data = {}
105+
106+
return self._fetch(
107+
code_mapping=HTTP_CODES_BULK_SC,
108+
endpoint=("objects/discovery_run/bulk_discovery"),
109+
data=data,
110+
method="GET",
111+
)
112+
113+
114+
class Discovery210(Discovery):
115+
def __init__(self, module, logger):
116+
super().__init__(module, logger)
117+
118+
self.discovery_single = ServiceDiscoveryAPI(self.module, self.logger)
119+
self.discovery_bulk = ServiceBulkDiscoveryAPI(self.module, self.logger)
120+
self.completion_single = ServiceCompletionAPI(self.module, self.logger)
121+
self.completion_bulk = ServiceCompletionBulkAPI(self.module, self.logger)
122+
123+
self.discovery_api = self._discovery_api()
124+
self.service_completion_api = self._service_completion_api()
125+
126+
self.supported_versions = SUPPORTED_VERSIONS
127+
128+
def _discovery_api(self):
129+
if self.single_mode:
130+
return self.discovery_single
131+
132+
return self.discovery_bulk
133+
134+
def _service_completion_api(self):
135+
if self.single_mode:
136+
return self.completion_single
137+
138+
return self.completion_bulk
139+
140+
def _wait_for_completion(self, what):
141+
now = time.time()
142+
if self.timeout > 0:
143+
deadline = now + self.timeout
144+
else:
145+
deadline = 0 # In case of infinite timeout
146+
147+
while True:
148+
now = time.time()
149+
if self.timeout > 0 and now > deadline:
150+
return generate_result(
151+
msg="Timeout reached while waiting for %s discovery" % what
152+
)
153+
154+
result = self.service_completion_api.get()
155+
156+
# The completion api shows the state of the job
157+
if not json.loads(result.content).get("extensions").get("active"):
158+
break
159+
160+
time.sleep(3)
161+
162+
return result
163+
164+
def start_discovery(self):
165+
if self.wait_for_previous:
166+
result = self._wait_for_completion("previous")
167+
if result.failed:
168+
return result
169+
170+
result = self.discovery_api.post()
171+
if result.failed:
172+
return result
173+
174+
if self.wait_for_completion:
175+
result = self._wait_for_completion("current")
176+
177+
return result

0 commit comments

Comments
 (0)