From 553ec9598260b9c09dbbd908fdf728fa16ecb46e Mon Sep 17 00:00:00 2001 From: "th.l" <thl-cmk@outlook.com> Date: Mon, 11 Apr 2022 07:33:55 +0200 Subject: [PATCH] update project --- agents/bakery/curl.py | 697 +++++++++++++++++---------------------- curl.mkp | Bin 25640 -> 26073 bytes packages/curl | 15 +- web/plugins/wato/curl.py | 257 ++++++++------- 4 files changed, 446 insertions(+), 523 deletions(-) diff --git a/agents/bakery/curl.py b/agents/bakery/curl.py index c28137e..28169f8 100755 --- a/agents/bakery/curl.py +++ b/agents/bakery/curl.py @@ -48,10 +48,15 @@ # added options --path-as-is, --ssl-allow-beast, --no-buffer, --no-keepalive, --no-sessionid # 2022-03-28: added option --crlf # added SMTP settings: --mail-auth, --mail-from, --mail-rcpt, --mail-rcpt-allowfails, --upload-file (SMTP) +# 2022-04-10: added deployment of cURL executables +# no separate WATO rules per OS necessary anymore +# reworked to make scalable for multiple OSs (THX to andreas.doehler[at]gmail[dot]com) +# removed data adjustments between default and per url settings after WATO rework # from pathlib import Path -from typing import List, Tuple, Dict +from typing import List, Dict, Any +from dataclasses import dataclass from cmk.utils import ( password_store, @@ -65,53 +70,69 @@ from cmk.base.cee.plugins.bakery.bakery_api.v1 import ( ) -bakery_version = '20220325.v0.0.6' - - -def get_curl_files(conf: Tuple[str, Dict[str, List[any]]]) -> FileGenerator: - if conf[0] == 'linux': - _os = OS.LINUX - _script = 'curl.sh' - _curl_output = '--output /dev/null' - _temp_path = '/var/tmp/' - _conf_path = '/etc/check_mk/' - elif conf[0] == 'windows': - _os = OS.WINDOWS - _script = 'curl.ps1' - _curl_output = '--output NUL' - _temp_path = 'c:/windows/temp/' - _conf_path = 'C:/ProgramData/checkmk/agent/config/' - else: - _os = None - _script = None - _curl_output = None - _temp_path = None - _conf_path = None - +@dataclass +class CurlConfig: + base_os: OS + curl_output: str + temp_path: str + conf_path: str + traget_path_bin: str + plugin_name: str + curl_executable_src: Dict[str, str] + curl_executable_dest: str + + +CURL_CONFIGS: List[CurlConfig] = [ + CurlConfig( + base_os=OS.LINUX, + curl_output="--output /dev/null", + temp_path="/var/tmp/", + conf_path="/etc/check_mk/", + traget_path_bin='../bin/curl', + plugin_name='curl.sh', + curl_executable_src={'64bit': 'curl-amd64', '32bit': 'curl-i386'}, + curl_executable_dest='../bin/curl', + ), + CurlConfig( + base_os=OS.WINDOWS, + curl_output="--output NUL", + temp_path="c:/windows/temp/", + conf_path="C:/ProgramData/checkmk/agent/config/", + traget_path_bin='..\\bin\\curl.exe', + plugin_name='curl.ps1', + curl_executable_src={'64bit': 'curl.exe.64', '32bit': 'curl.exe.32'}, + curl_executable_dest='..\\bin\\curl.exe', + ), +] + +bakery_version = '20220410.v0.0.7' + + +def get_curl_files(conf) -> FileGenerator: field_separator: str = '|' # needs matching separator in the shell scripts - options_separator: str = ' ' - options = conf[1].copy() - url_cfg_lines = [] + # catch pre 20220410 WATO format + options: Dict[str, Any] = conf[1].copy() if type(conf) == tuple else conf + + url_cfg_lines = [] url_list = options['url_list'] default_settings = options.get('default_settings', {}) - interval = None - timeout = None - - if options.get('interval'): - interval = options['interval'] * 60 # minutes to seconds - options.pop('interval') + interval = options['interval'] * 60 if options.get('interval') else None + timeout = options['timeout'] * 60 if options.get('timeout') else None - if options.get('timeout'): - timeout = options['timeout'] * 60 # minutes to seconds - options.pop('timeout') + if options.get('curl_executable'): + for curl_config in CURL_CONFIGS: + yield Plugin( + base_os=curl_config.base_os, + source=Path(curl_config.curl_executable_src[str(options['curl_executable'])]), + target=Path(curl_config.curl_executable_dest), + ) + yield Plugin(base_os=curl_config.base_os, source=Path('curl-ca-bundle.crt')) curl_item = 0 for entry in url_list: curl_item += 1 - options_array = [] - header_array = [] regex_option = 'no_regex' save_output = False # get service name and url, first try new format, then old format @@ -121,8 +142,6 @@ def get_curl_files(conf: Tuple[str, Dict[str, List[any]]]) -> FileGenerator: service_name = entry['service_name'] url = entry['url'] - options_array.append(f'--url "{url}"') - url_settings = default_settings.copy() entry = entry.get('url_settings', {}).copy() @@ -150,394 +169,284 @@ def get_curl_files(conf: Tuple[str, Dict[str, List[any]]]) -> FileGenerator: # merge per url settings with default settings url_settings.update(entry) - # adjust per url settings with default settings (dictionary) - for key in [ - 'expected_strings', - 'header_strings', - 'referer', - 'request_headers', - ]: - if type(url_settings.get(key)) == tuple: - url_settings.update({key: url_settings[key][1]}) - - for key in [ - 'limit_rate', - 'max_file_size', - 'max_time', - 'speed_limit', - 'speed_time', - 'connect_timeout', - 'api_key_header', - # 'user_auth', - ]: - if type(url_settings.get(key)) == tuple: - if url_settings[key][0] == key: - url_settings.update({key: url_settings[key][1]}) - # adjust per url settings with default settings (tuple) - for key in [ - 'http_proxy', - ]: - if type(url_settings.get(key)) == tuple: - if type(url_settings[key][1]) == dict: - url_settings.update({key: url_settings[key][1]}) - - # filter options - if url_settings.get('http_proxy'): - if url_settings['http_proxy'] == '--noproxy': - options_array.append("--noproxy '*'") - else: - proxy_protocol, proxy_server, proxy_port = url_settings['http_proxy']['proxy_server'] - options_array.append(f'{proxy_protocol} {proxy_server}:{proxy_port}') - if url_settings['http_proxy'].get('proxy_auth'): - proxy_user, proxy_password, proxy_auth = url_settings['http_proxy']['proxy_auth'] - if proxy_password[0] == 'store': - pw = password_store.extract(proxy_password[1]) - else: - pw = proxy_password[1] - options_array.append(f'--proxy-user {proxy_user}:{pw}') - options_array.append(proxy_auth) - url_settings.pop('http_proxy') - - if url_settings.get('user_auth'): - if url_settings['user_auth'][0] == 'user_auth': - user, user_password, user_auth = url_settings['user_auth'][1] - if user_password[0] == 'store': - pw = password_store.extract(user_password[1]) + for curl_config in CURL_CONFIGS: + _os = curl_config.base_os + _curl_output = curl_config.curl_output + _temp_path = curl_config.temp_path + _conf_path = curl_config.conf_path + + _options = [f'--url "{url}"'] + _headers = [] + + # filter options + _options.append(url_settings['get_header_only']) if url_settings.get('get_header_only') else None + _options.append(url_settings['compressed']) if url_settings.get('compressed') else None + _options.append(f'--max-time {url_settings["max_time"]}') if url_settings.get('max_time') else None + _options.append(f'--speed-time {url_settings["speed_time"]}') if url_settings.get('speed_time') else None + _options.append(f'--connect-timeout {url_settings["connect_timeout"]}') if url_settings.get('connect_timeout') else None + _options.append(f'--user-agent "{url_settings["user_agent"]}"') if url_settings.get('user_agent') else None + _options.append(f'--referer {url_settings["referer"]}') if url_settings.get('referer') else None + _options.append(f'{url_settings["tls_ssl_version"]}') if url_settings.get('tls_ssl_version') else None + _options.append(f'{url_settings["http_version"]}') if url_settings.get('http_version') else None + + if url_settings.get('max_file_size'): + max_size, unit = url_settings['max_file_size'] + _options.append(f'--max-filesize {max_size}{unit}') + + if url_settings.get('speed_limit'): + speed, unit = url_settings['speed_limit'] + _options.append(f'--speed-limit {speed * unit}') + + if url_settings.get('limit_rate'): + speed, unit = url_settings['limit_rate'] + _options.append(f'--limit-rate {speed}{unit}') + + if url_settings.get('http_proxy'): + if url_settings['http_proxy'] == '--noproxy': + _options.append("--noproxy '*'") else: - pw = user_password[1] - options_array.append(f'--user {user}:{pw}') - options_array.append(user_auth) - elif url_settings['user_auth'][0] == 'priv_key_auth': - user, pass_phrase, priv_key = url_settings['user_auth'][1] - options_array.append(f'--user {user}:') - options_array.append(f'--key {_conf_path}curl/curl_item_{curl_item}.priv_key') - if pass_phrase[0] == 'store': - pw = password_store.extract(pass_phrase[1]) + proxy_protocol, proxy_server, proxy_port = url_settings['http_proxy']['proxy_server'] + _options.append(f'{proxy_protocol} {proxy_server}:{proxy_port}') + if url_settings['http_proxy'].get('proxy_auth'): + proxy_user, proxy_password, proxy_auth = url_settings['http_proxy']['proxy_auth'] + if proxy_password[0] == 'store': + pw = password_store.extract(proxy_password[1]) + else: + pw = proxy_password[1] + _options.append(f'--proxy-user {proxy_user}:{pw}') + _options.append(proxy_auth) + + if url_settings.get('request_headers'): + for header in url_settings['request_headers']: + key, value = header + _headers.append(f'{key}:{value}') + + if url_settings.get('api_key_header'): + api_header, api_key = url_settings['api_key_header'] + api_header = api_header.rstrip(':') + if api_key[0] == 'store': + api_key = password_store.extract(api_key[1]) else: - pw = pass_phrase[1] - options_array.append(f'--pass {pw}') + api_key = api_key[1] + _headers.append(f'{api_header}:{api_key}') + + if url_settings.get('redirects'): + location, location_trusted, max_redirects = url_settings['redirects'] + _options.append(f'--location') if location else None + _options.append(f'--location-trusted') if location_trusted else None + _options.append(f'--max-redirs {max_redirects}') if max_redirects else None + + if url_settings.get('advanced_settings'): + allow_beast, cr2lf, no_apln, no_buffering, no_npn, no_sessionid, no_keepalive, \ + path_as_is, tcp_fastopen, tcp_nodelay = url_settings['advanced_settings'] + + _options.append(f'--ssl-allow-beast') if allow_beast else None + _options.append(f'--crlf') if cr2lf else None + _options.append(f'--no-alpn') if no_apln else None + _options.append(f'--no-buffer') if no_buffering else None + _options.append(f'--no-npn') if no_npn else None + _options.append(f'--no-sessionid') if no_sessionid else None + _options.append(f'--no-keepalive') if no_keepalive else None + _options.append(f'--path-as-is') if path_as_is else None + _options.append(f'--tcp-fastopen') if tcp_fastopen else None + _options.append(f'--tcp-nodelay') if tcp_nodelay else None + + if url_settings.get('ip_address_resolution'): + dns_options = url_settings['ip_address_resolution'] + _options.append(dns_options['dns_resolve_names']) if dns_options.get('dns_resolve_names') else None + _options.append(f'--dns-interface {dns_options["dns_source_interface"]}') if dns_options.get('dns_source_interface') else None + _options.append(f'--dns-ipv4-addr {dns_options["dns_source_ipv4"]}') if dns_options.get('dns_source_ipv4') else None + _options.append(f'--dns-ipv6-addr {dns_options["dns_source_ipv6"]}') if dns_options.get('dns_source_ipv6') else None + _options.append(f'--dns-servers {",".join(dns_options["dns_servers"])}') if dns_options.get('dns_servers') else None + + if url_settings.get('ftp_settings'): + ftp_options = url_settings['ftp_settings'] + _options.append(f'--compressed-ssh') if ftp_options.get('compressed_ssh') else None + _options.append(f'--list-only') if ftp_options.get('list_only') else None + _options.append(f'--use-ascii') if ftp_options.get('use_ascii') else None + _options.append(f'--ftp-create-dirs') if ftp_options.get('ftp_create_dirs') else None + _options.append(f'--ftp-account {ftp_options["ftp_account"]}') if ftp_options.get('ftp_account') else None + _options.append(f'--ftp-alternative-to-user {ftp_options["ftp_alternate_to_user"]}') if ftp_options.get('ftp_alternate_to_user') else None + _options.append(f'--ftp-method {ftp_options["ftp_change_cwd_method"]}') if ftp_options.get('ftp_change_cwd_method') else None + + if ftp_options.get('ftp_mode'): + ftp_mode = ftp_options['ftp_mode'] + if ftp_mode[0] == 'ftp_pass': + no_send_epsv, send_pret, skip_ip = ftp_mode[1] + _options.append(f'--ftp-pasv') + _options.append(f'--disable-epsv') if no_send_epsv else None + _options.append(f'--ftp-pret') if send_pret else None + _options.append(f'--ftp-skip-pasv-ip') if skip_ip else None + else: + no_send_eprt, active_address = ftp_options[1] + _options.append(f'--disable-eprt') if no_send_eprt else None + _options.append(f'--ftp-port {active_address}') if active_address else None + if ftp_options.get('ftp_ssl_control'): + _options.append(f'--ftp-ssl-control') + ftp_ssl_ccc, ftp_ssl_ccc_mode = ftp_options['ftp_ssl_control'] + if ftp_ssl_ccc: + _options.append(f'--ftp-ssl-ccc') + _options.append(f'--ftp-ssl-ccc-mode {ftp_ssl_ccc_mode}') + + if url_settings.get('user_auth'): + if url_settings['user_auth'][0] == 'user_auth': + user, user_password, user_auth = url_settings['user_auth'][1] + pw = password_store.extract(user_password[1]) if user_password[0] == 'store' else user_password[1] + _options.append(f'--user {user}:{pw}') + _options.append(user_auth) + elif url_settings['user_auth'][0] == 'priv_key_auth': + user, pass_phrase, priv_key = url_settings['user_auth'][1] + pw = password_store.extract(pass_phrase[1]) if pass_phrase[0] == 'store' else pass_phrase[1] + _options.append(f'--user {user}:') + _options.append(f'--key {_conf_path}curl/curl_item_{curl_item}.priv_key') + _options.append(f'--pass {pw}') + yield PluginConfig( + base_os=_os, + lines=[priv_key], + target=Path(f'curl/curl_item_{curl_item}.priv_key'), + include_header=False, + ) + + if url_settings.get('expected_strings'): + save_output = True yield PluginConfig( base_os=_os, - lines=[priv_key], - target=Path(f'curl/curl_item_{curl_item}.priv_key'), + lines=url_settings['expected_strings'], + target=Path(f'curl/curl_item_{curl_item}.search_response'), include_header=False, ) - url_settings.pop('user_auth') - - if url_settings.get('expected_strings'): - save_output = True - yield PluginConfig( - base_os=_os, - lines=url_settings['expected_strings'], - target=Path(f'curl/curl_item_{curl_item}.search_response'), - include_header=False, - ) - url_settings.pop('expected_strings') - if url_settings.get('header_strings'): - options_array.append(f'--dump-header {_temp_path}curl_header') - yield PluginConfig( - base_os=_os, - lines=url_settings['header_strings'], - target=Path(f'curl/curl_item_{curl_item}.search_header'), - include_header=False, - ) - url_settings.pop('header_strings') - - if url_settings.get('limit_rate'): - speed, unit = url_settings['limit_rate'] - options_array.append(f'--limit-rate {speed}{unit}') - url_settings.pop('limit_rate') - - if url_settings.get('max_file_size'): - max_size, unit = url_settings['max_file_size'] - options_array.append(f'--max-filesize {max_size}{unit}') - url_settings.pop('max_file_size') - - if url_settings.get('max_time'): - options_array.append(f'--max-time {url_settings["max_time"]}') - url_settings.pop('max_time') - - if url_settings.get('speed_limit'): - speed, unit = url_settings['speed_limit'] - options_array.append(f'--speed-limit {speed * unit}') - url_settings.pop('speed_limit') - - if url_settings.get('speed_time'): - options_array.append(f'--speed-time {url_settings["speed_time"]}') - url_settings.pop('speed_time') - - if url_settings.get('connect_timeout'): - options_array.append(f'--connect-timeout {url_settings["connect_timeout"]}') - url_settings.pop('connect_timeout') - - if url_settings.get('user_agent'): - user_agent = url_settings['user_agent'] - options_array.append(f'--user-agent "{user_agent}"') - url_settings.pop('user_agent') - - if url_settings.get('referer'): - referer = url_settings['referer'] - options_array.append(f'--referer {referer}') - url_settings.pop('referer') - - if url_settings.get('request_headers'): - for header in url_settings['request_headers']: - key, value = header - header_array.append(f'{key}:{value}') - # options_array.append(f'--header "{key}:{value}"') - url_settings.pop('request_headers') - - if url_settings.get('api_key_header'): - api_header, api_key = url_settings['api_key_header'] - api_header = api_header.rstrip(':') - if api_key[0] == 'store': - api_key = password_store.extract(api_key[1]) - else: - api_key = api_key[1] - header_array.append(f'{api_header}:{api_key}') - # options_array.append(f'--header "{api_header}:{api_key}"') - url_settings.pop('api_key_header') - - if url_settings.get('redirects'): - location, location_trusted, max_redirects = url_settings['redirects'] - if location: - options_array.append(f'--location') - if location_trusted: - options_array.append(f'--location-trusted') - if max_redirects: - options_array.append(f'--max-redirs {int(max_redirects)}') - url_settings.pop('redirects') - - if url_settings.get('cert_verify'): - pub_md5 = None - pub_sha256 = None - pub_key = None - try: # 2022-03-23: added ssh settings - insecure, ocsp, no_revoke, cert_chain = url_settings['cert_verify'] - except ValueError: # 2022-03-23: added ssh settings - insecure, ocsp, no_revoke, cert_chain, pub_md5, pub_sha256, pub_key = url_settings['cert_verify'] - if insecure: - options_array.append(f'--insecure') - if ocsp: - options_array.append(f'--cert-status') - if no_revoke: - options_array.append(f'--ssl-no-revoke') - if cert_chain: - cert_chain = cert_chain[cert_chain.find('-----BEGIN CERTIFICATE-----'):] - yield PluginConfig( - base_os=_os, - lines=[cert_chain], - target=Path(f'curl/curl_item_{curl_item}.ca_cert'), - include_header=False, - ) - options_array.append(f'--cacert {_conf_path}curl/curl_item_{curl_item}.ca_cert') - if pub_md5: - options_array.append(f'--hostpubmd5 {pub_md5}') - if pub_sha256: - options_array.append(f'--hostpubsha256 {pub_sha256}') - if pub_key: + if url_settings.get('header_strings'): + _options.append(f'--dump-header {_temp_path}curl_header') yield PluginConfig( base_os=_os, - lines=[pub_key], - target=Path(f'curl/curl_item_{curl_item}.pub_key'), + lines=url_settings['header_strings'], + target=Path(f'curl/curl_item_{curl_item}.search_header'), include_header=False, ) - options_array.append(f'--pubkey {_conf_path}curl/curl_item_{curl_item}.pub_key') - - url_settings.pop('cert_verify') - - if url_settings.get('advanced_settings'): - allow_beast, cr2lf, no_apln, no_buffering, no_npn, no_sessionid, no_keepalive, \ - path_as_is, tcp_fastopen, tcp_nodelay = url_settings['advanced_settings'] - if allow_beast: - options_array.append(f'--ssl-allow-beast') - if cr2lf: - options_array.append(f'--crlf') - if no_apln: - options_array.append(f'--no-alpn') - if no_buffering: - options_array.append(f'--no-buffer') - if no_npn: - options_array.append(f'--no-npn') - if no_sessionid: - options_array.append(f'--no-sessionid') - if no_keepalive: - options_array.append(f'--no-keepalive') - if path_as_is: - options_array.append(f'--path-as-is') - if tcp_fastopen: - options_array.append(f'--tcp-fastopen') - if tcp_nodelay: - options_array.append(f'--tcp-nodelay') - url_settings.pop('advanced_settings') - - if url_settings.get('post_binary'): - header_array.append(f'content-type: {url_settings["post_binary"][0]}') - yield PluginConfig( - base_os=_os, - lines=[url_settings["post_binary"][1]], - target=Path(f'curl/curl_item_{curl_item}.post_binary'), - include_header=False, - ) - options_array.append(f'--data-binary @{_conf_path}curl/curl_item_{curl_item}.post_binary') - url_settings.pop('post_binary') - if url_settings.get('regex_response'): - regex_str, no_case, multi_line = url_settings['regex_response'] - if regex_str: - save_output = True + if url_settings.get('cert_verify'): + pub_md5 = None + pub_sha256 = None + pub_key = None + try: # 2022-03-23: added ssh settings + insecure, ocsp, no_revoke, cert_chain = url_settings['cert_verify'] + except ValueError: # 2022-03-23: added ssh settings + insecure, ocsp, no_revoke, cert_chain, pub_md5, pub_sha256, pub_key = url_settings['cert_verify'] + + _options.append(f'--insecure') if insecure else None + _options.append(f'--cert-status') if ocsp else None + _options.append(f'--ssl-no-revoke') if no_revoke else None + _options.append(f'--hostpubmd5 {pub_md5}') if pub_md5 else None + _options.append(f'--hostpubsha256 {pub_sha256}') if pub_sha256 else None + + if cert_chain: + cert_chain = cert_chain[cert_chain.find('-----BEGIN CERTIFICATE-----'):] + yield PluginConfig( + base_os=_os, + lines=[cert_chain], + target=Path(f'curl/curl_item_{curl_item}.ca_cert'), + include_header=False, + ) + _options.append(f'--cacert {_conf_path}curl/curl_item_{curl_item}.ca_cert') + + if pub_key: + yield PluginConfig( + base_os=_os, + lines=[pub_key], + target=Path(f'curl/curl_item_{curl_item}.pub_key'), + include_header=False, + ) + _options.append(f'--pubkey {_conf_path}curl/curl_item_{curl_item}.pub_key') + + if url_settings.get('post_binary'): + _headers.append(f'content-type: {url_settings["post_binary"][0]}') yield PluginConfig( base_os=_os, - lines=[regex_str], - target=Path(f'curl/curl_item_{curl_item}.regex'), + lines=[url_settings["post_binary"][1]], + target=Path(f'curl/curl_item_{curl_item}.post_binary'), include_header=False, ) - if no_case: - regex_option = 'nocase' - else: - regex_option = 'case' - if multi_line: - regex_option += '_multiline' - else: - regex_option += '_nomultiline' - - url_settings.pop('regex_response') - - if url_settings.get('ip_address_resolution'): - dns_options = url_settings['ip_address_resolution'] - if dns_options.get('dns_resolve_names'): - options_array.append(dns_options['dns_resolve_names']) - if dns_options.get('ens_source_interface'): - options_array.append(f'--dns-interface {dns_options["ens_source_interface"]}') - if dns_options.get('dns_source_ipv4'): - options_array.append(f'--dns-ipv4-addr {dns_options["dns_source_ipv4"]}') - if dns_options.get('dns_source_ipv6'): - options_array.append(f'--dns-ipv6-addr {dns_options["dns_source_ipv6"]}') - if dns_options.get('dns_servers'): - options_array.append(f'--dns-servers {",".join(dns_options["dns_servers"])}') - url_settings.pop('ip_address_resolution') - - if url_settings.get('ftp_settings'): - ftp_options = url_settings['ftp_settings'] - if ftp_options.get('ftp_account'): - options_array.append(f'--ftp-account {ftp_options["ftp_account"]}') - if ftp_options.get('ftp_alternate_to_user'): - options_array.append(f'--ftp-alternative-to-user {ftp_options["ftp_alternate_to_user"]}') - if ftp_options.get('ftp_create_dirs'): - options_array.append(f'--ftp-create-dirs') - if ftp_options.get('ftp_change_cwd_method'): - options_array.append(f'--ftp-method {ftp_options["ftp_change_cwd_method"]}') - if ftp_options.get('ftp_mode'): - ftp_mode = ftp_options['ftp_mode'] - if ftp_mode[0] == 'ftp_pass': - options_array.append(f'--ftp-pasv') - no_send_epsv, send_pret, skip_ip = ftp_mode[1] - if no_send_epsv: - options_array.append(f'--disable-epsv') - if send_pret: - options_array.append(f'--ftp-pret') - if skip_ip: - options_array.append(f'--ftp-skip-pasv-ip') - else: - no_send_eprt, active_address = ftp_options[1] - if no_send_eprt: - options_array.append(f'--disable-eprt') - if active_address: - options_array.append(f'--ftp-port {active_address}') - if ftp_options.get('ftp_ssl_control'): - options_array.append(f'--ftp-ssl-control') - ftp_ssl_ccc, ftp_ssl_ccc_mode = ftp_options['ftp_ssl_control'] - if ftp_ssl_ccc: - options_array.append(f'--ftp-ssl-ccc') - options_array.append(f'--ftp-ssl-ccc-mode {ftp_ssl_ccc_mode}') - if ftp_options.get('compressed_ssh'): - options_array.append(f'--compressed-ssh') - if ftp_options.get('list_only'): - options_array.append(f'--list-only') - if ftp_options.get('use_ascii'): - options_array.append(f'--use-ascii') - url_settings.pop('ftp_settings') - - if url_settings.get('mail_settings'): - mail_options = url_settings['mail_settings'] - if mail_options.get('mail_from'): - options_array.append(f'--mail-from {mail_options["mail_from"]}') - if mail_options.get('mail_rcpt'): - for address in mail_options['mail_rcpt']: - options_array.append(f'--mail-rcpt {address}') - if mail_options.get('mail_auth'): - options_array.append(f'--mail-auth {mail_options["mail_auth"]}') - if mail_options.get('request'): - options_array.append(f'--request {mail_options["request"]}') - if mail_options.get('mail_rpct_allowfail'): - options_array.append(f'--mail-rcpt-allowfails') - message = [] - if mail_options.get('request_headers'): - for header, value in mail_options['request_headers']: - message.append(f'{header}: {value}') - if mail_options.get('message'): - message.append(mail_options['message']) - if message: - options_array.append(f'--upload-file {_conf_path}curl/curl_item_{curl_item}.message') + _options.append(f'--data-binary @{_conf_path}curl/curl_item_{curl_item}.post_binary') + + if url_settings.get('regex_response'): + regex_str, no_case, multi_line = url_settings['regex_response'] + if regex_str: + save_output = True + yield PluginConfig( + base_os=_os, + lines=[regex_str], + target=Path(f'curl/curl_item_{curl_item}.regex'), + include_header=False, + ) + regex_option = 'nocase' if no_case else 'case' + regex_option += '_multiline' if multi_line else '_nomultiline' + + if url_settings.get('mail_settings'): + mail_options = url_settings['mail_settings'] + + _options.append(f'--mail-from {mail_options["mail_from"]}') if mail_options.get('mail_from') else None + _options.append(f'--mail-auth {mail_options["mail_auth"]}') if mail_options.get('mail_auth') else None + _options.append(f'--request {mail_options["request"]}') if mail_options.get('request') else None + _options.append(f'--mail-rcpt-allowfails') if mail_options.get('mail_rpct_allowfail') else None + + if mail_options.get('mail_rcpt'): + for address in mail_options['mail_rcpt']: + _options.append(f'--mail-rcpt {address}') + + message = [] + message.append(mail_options['message']) if mail_options.get('message') else None + if mail_options.get('request_headers'): + for header, value in mail_options['request_headers']: + message.append(f'{header}: {value}') + if message: + _options.append(f'--upload-file {_conf_path}curl/curl_item_{curl_item}.message') + yield PluginConfig( + base_os=_os, + lines=message, + target=Path(f'curl/curl_item_{curl_item}.message'), + include_header=False, + ) + + _options.append(f'--output {_temp_path}curl_output') if save_output else _options.append(_curl_output) + + if _headers: yield PluginConfig( base_os=_os, - lines=message, - target=Path(f'curl/curl_item_{curl_item}.message'), + lines=_headers, + target=Path(f'curl/curl_item_{curl_item}.header'), include_header=False, ) - url_settings.pop('mail_settings') + _options.append(f'--header @{_conf_path}curl/curl_item_{curl_item}.header') - if save_output: - options_array.append(f'--output {_temp_path}curl_output') - else: - options_array.append(_curl_output) - - if header_array: yield PluginConfig( base_os=_os, - lines=header_array, - target=Path(f'curl/curl_item_{curl_item}.header'), - include_header=False, + lines=_options, + target=Path(f'curl/curl_item_{curl_item}.options'), + include_header=True, ) - options_array.append(f'--header @{_conf_path}curl/curl_item_{curl_item}.header') - - for value in url_settings.values(): - options_array.append(value) - curl_options = options_separator.join(options_array) - while ' ' in curl_options: - curl_options = curl_options.replace(' ', ' ') url_cfg_lines.append( f'{service_name}{field_separator}' - # f'"{url}"{field_separator}' - # f'{curl_options.strip()}{field_separator}' f'curl_item_{curl_item}{field_separator}' f'{regex_option}{field_separator}' ) + + for curl_config in CURL_CONFIGS: + yield Plugin( + base_os=curl_config.base_os, + source=Path(curl_config.plugin_name), + interval=interval, + timeout=timeout + ) yield PluginConfig( - base_os=_os, - lines=options_array, - target=Path(f'curl/curl_item_{curl_item}.options'), - include_header=True, + base_os=curl_config.base_os, + lines=url_cfg_lines, + target=Path('curl.cfg'), + include_header=False ) - yield Plugin( - base_os=_os, - source=Path(_script), - target=Path(_script), - interval=interval, - timeout=timeout, - ) - - yield PluginConfig( - base_os=_os, - lines=url_cfg_lines, - target=Path('curl.cfg'), - include_header=False, - ) - register.bakery_plugin( name='curl', diff --git a/curl.mkp b/curl.mkp index ecf9c70ffb7ca71c57ec484f831358704877964a..c6feb860a25fcd019e4f88f5cb52c76ce6417b68 100644 GIT binary patch literal 26073 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%0AoU=Hgtsg7g2(pA&C+UP;=; zy7_M#n|}Y82)D&m<a4-@u|wMO1@i+zJB|DEz7P60=&!>jUwe9SK&mip{WpKE55XM( z_inv}J1vx}yG!Btlz!|dnCrQFxRNPGVkRAfl+K@t9@@#(+YYQbHWW+uDC-o(UEtsa zij?+9+z2^W9L^FS5W&f4-*D1mEaF0t_1tGOH|fXQyMLx5bpSa#8)i;t_jid|<hbnI zx>z2$9f6(r4@=JF^XR%EJSRw@SO<*9cW5#*C5G{l=@4o$l%zZH&orVN#(_Hir()e& zJ6yaUu_Q!+dG^+C`E7JoN@6<!OM8-%vEtLxD_iqy%6inU9Hckir>@zb_$&RB*u7z^ z)Q^f)A2r%<4LHXQ?<CSU<s)8%LCgM3wgG1%H0#*kgEDQBr>shqev)%<gCzFRlB#Pt zx`E>LOE?8lK4GQ>kg6*3(upwkz}rAAqFDCft%>_vnVuf|zJc(hql4_OtQHe46qhwz zvsP0EEQ*X^Rm_a_lUhS__Es=LH471t)%PfhhT=o^wpByopX?FxEcEl_m{oI@0c0*o zd1cy-UBgpl!jX~d<5}G8)b|-G=CTv%1hK10Q;4iOIs+7y|8gp%UrFRwob$uxHyK?^ z1)_%;__ieqn4DCJI0x)latq2c3&R$)L`dD~vv`uwrWNvC?UipciX{EjP4Ox=APE)S z0`c|~7~NG!bQM0A4Ay}JEcWJj0czYlfl?Yk5jh0g5eUT$FgXkSddJmO>N}9cyS>M{ zr;1$zWj6m+=QJ-yL>XeXQ<b6)W5e4B5w(04&OVfnx{#e9PiXEhhs;ET$0hF&JRwkp zbEihJJI~~;wQCGJTp!mkyg0?{Tgd?Uy90MuQn6@XOYjS0oIO&m@0=g1F`MuIunc$2 zCgY~=Z8A5d@8d0PSY+6O7)ud0FH|!q|LB*s{VJgvf*+HKUs_aIJJ}EU4U9nId0fJ= zyvP>pTB)o$epPlZ$qXMD12jO-+g17Y0;EdKfDwD_xC=SISGZ%I@mGVo;x&^^&RHyy zgTNH@%wx7KJ)3vWV+V;w{v@zHHze2#Forry5>XJ25p;|fG@SKn;MX5Z(%(HeCFUd! zO+7w?-c>TZ36a^x_z)%7k~>e%GBoobC?_~4j&;5!uq{~Y5HVzobwuOBzVT$lHKheA zDhfz1uS{up=c+~4;;{{6`u|Azxz!A<dS!7H^H=5Wu|AMdx$uc=$#$F}LfHZ#7ST4= zuD%yWPZ472C0-vOIG}3Vku_Nm^_UuZym$CO(yAcL;V&t4o1*nj9)O^v_zJwf<r7W+ i7gkbJCR+P?v>5w;CW`(?&j?fSOXx;XbQeq;0_;Efb`jkG literal 25640 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 diff --git a/packages/curl b/packages/curl index 1a8e612..a769adf 100644 --- a/packages/curl +++ b/packages/curl @@ -2,18 +2,21 @@ 'description': 'cURL agent plugin\n' '\n' 'Monitor URLs from the perspective of your monitored hosts, ' - 'not the monitoring server ;-). Deployment and configuration ' - 'of the plugin is integrated in the CMK bakery.\n' + 'not the monitoring server ;-). \n' + '\n' + 'The plugin is based on a idea by Christian Wirtz ' + 'doc[at]snowheaven[dot]de and Ingo Hambrock.\n' '\n' - 'The plugin is based on a idea by based on the work by ' - 'Christian Wirtz doc[at]snowheaven[dot]de and Ingo Hambrock\n' 'This agent plugin for Linux and Windows is build around the ' 'curl command line tool from https://curl.se.\n' '\n' 'The executable is not included in this package. The plugin ' 'will use by default the system provided curl executable.\n' '\n' - 'Note: this plugin needs at leat curl version 7.70.0 from ' + 'Deployment and configuration of the plugin is integrated in ' + 'the CMK bakery.\n' + '\n' + 'Note: this plugin needs at least curl version 7.70.0 from ' 'April 29 2020 to work. You can use my CMK package ' '"curl_executable.mkp" to deploy a compatible version.\n', 'download_url': 'https://thl-cmk.hopto.org/gitlab/checkmk/vendor-independent/curl', @@ -23,7 +26,7 @@ 'name': 'curl', 'num_files': 6, 'title': 'cURL agent plugin', - 'version': '20220406.v0.1.6', + 'version': '20220410.v0.1.7', 'version.min_required': '2.0.0', 'version.packaged': '2021.09.20', 'version.usable_until': None} \ No newline at end of file diff --git a/web/plugins/wato/curl.py b/web/plugins/wato/curl.py index b051c4b..56adc42 100644 --- a/web/plugins/wato/curl.py +++ b/web/plugins/wato/curl.py @@ -65,6 +65,11 @@ # 2022-03-25: added options --compressed-ssh, --list-only, --use-ascii # added options --path-as-is, --ssl-allow-beast, --no-buffer, --no-keepalive, --no-sessionid # 2022-03-28: added options --mail-auth, --mail-from, --mail-rcpt, --mail-rcpt-allowfails, --crlf, --upload-file (SMTP) +# 2022-04-10: added options to deploy cURL executable, no separate rules for curl and curl executable anymore +# windows/linux summarized under on option, no separate WATO rules per OS necessary anymore +# replaced most CascadingDropdown with Alternative to avoid the need for adusting default and url settings +# in the bakery +# import ipaddress from cmk.gui.i18n import _ @@ -89,6 +94,7 @@ from cmk.gui.valuespec import ( Age, # Url, UploadOrPasteTextFile, + Alternative, ) from cmk.gui.plugins.wato import ( rulespec_registry, @@ -104,7 +110,7 @@ from cmk.gui.cee.plugins.wato.agent_bakery.rulespecs.utils import ( RulespecGroupMonitoringAgentsAgentPlugins, ) -bakery_plugin_version = '20220325.v0.0.6' +bakery_plugin_version = '20220410.v0.0.7' # unsafe characters https://www.tutorialspoint.com/html/html_url_encoding.htm forbidden_chars = '"<>#%{}|\^~[]` \'' @@ -147,7 +153,7 @@ _curl_check_elements = [ )), ('http_error_code_to_ignore', ListOfStrings( - title=_('HTTP:q error codes to ignore'), + title=_('HTTP error codes to ignore'), allow_empty=False, orientation='horizontal', valuespec=Integer(size=3, minvalue=0, maxvalue=999), @@ -552,21 +558,19 @@ _option_proxy_auth = ('proxy_auth', )) _options_proxy = ('http_proxy', - CascadingDropdown( + Alternative( title=_('Configure proxy server'), - sorted=False, - choices=[ - ('http_proxy', _('Use proxy'), - Dictionary( - title='Use proxy', - elements=[ - _option_proxy_server, - _option_proxy_auth, - ], - required_keys=['proxy_server'], - )), - ('--noproxy', _('Don\'t use any proxy')), - ('', _('Don\'t configure an proxy (use system settings)')), + elements=[ + Dictionary( + title='Use proxy', + elements=[ + _option_proxy_server, + _option_proxy_auth, + ], + required_keys=['proxy_server'], + ), + FixedValue('--noproxy', title=_('Don\'t use any proxy'), totext=_('')), + FixedValue(None, title=_('Don\'t configure an proxy (use system settings)'), totext=_('')), ], )) @@ -626,7 +630,7 @@ _option_address_resolution = ('ip_address_resolution', ('--ipv4', _('IPv4 only')), ('--ipv6', _('IPv6 only')), ])), - ('ens_source_interface', TextUnicode( + ('dns_source_interface', TextUnicode( title=_('Source interface'), regex='[0-9a-zA-Z]', size=15, @@ -750,12 +754,11 @@ _option_expected_strings = ('expected_strings', valuespec=TextInput(allow_empty=False, regex='[a-zA-Z0-9\.]'), )) _url_expected_strings = ('expected_strings', - CascadingDropdown( - title=_('Strings to expect in response'), - sorted=False, - choices=[ - ('expected_strings', _('Expected strings'), _option_expected_strings[1]), - ('', _('Don\'t expect any strings in the response')), + Alternative( + title=_('Override strings to expect in response'), + elements=[ + _option_expected_strings[1], + FixedValue(None, title=_('Don\'t expect any strings in the response'), totext=_('')), ], )) @@ -767,12 +770,11 @@ _option_header_strings = ('header_strings', valuespec=TextInput(allow_empty=False, regex='[a-zA-Z0-9\\.]'), )) _url_header_strings = ('header_strings', - CascadingDropdown( - title=_('Strings to expect in header'), - sorted=False, - choices=[ - ('header_strings', _('Header strings'), _option_expected_strings[1]), - ('', _('Don\'t expect any strings in the header')), + Alternative( + title=_('Override strings to expect in header'), + elements=[ + _option_expected_strings[1], + FixedValue(None, title=_('Don\'t expect any strings in the header'), totext=_('')), ], )) @@ -804,15 +806,13 @@ _option_request_headers = ('request_headers', add_label=_('Add header'), movable=True, )) - _url_request_headers = ('request_headers', - CascadingDropdown( - title=_('Set headers'), - sorted=False, - choices=[ - ('request_headers', _('Override default request headers'), _option_request_headers[1]), - ('', _('Don\'t configure request headers')), - ], + Alternative( + title=_('Override default headers'), + elements=[ + _option_request_headers[1], + FixedValue(None, title=_('Don\'t configure request headers'), totext=_('')) + ] )) _option_mail_settings = ('mail_settings', @@ -875,12 +875,11 @@ _option_api_key_header = ('api_key_header', ], )) _url_api_key_header = ('api_key_header', - CascadingDropdown( + Alternative( title=_('Set API key header'), - sorted=False, - choices=[ - ('api_key_header', _('API key header'), _option_api_key_header[1],), - ('', _('Don\'t configure an API key header')), + elements=[ + _option_api_key_header[1], + FixedValue(None, title=_('Don\'t configure an API key header'), totext=_('')), ], )) @@ -907,12 +906,11 @@ _option_limit_rate = ('limit_rate', orientation='horizontal', )) _url_limit_rate = ('limit_rate', - CascadingDropdown( + Alternative( title=_('Maximum UP-/Download rate'), - sorted=False, - choices=[ - ('limit_rate', _('Override default rate limit'), _option_limit_rate[1],), - ('', _('No rate limit')), + elements=[ + _option_limit_rate[1], + FixedValue(None, title=_('Don\'t configure a rate limit'), totext=_('')), ], )) @@ -939,12 +937,11 @@ _option_max_file_size = ('max_file_size', orientation='horizontal', )) _url_max_file_size = ('max_file_size', - CascadingDropdown( + Alternative( title=_('Maximum file size'), - sorted=False, - choices=[ - ('max_file_size', _('Override default maximum file size'), _option_max_file_size[1],), - ('', _('No file size limit')), + elements=[ + _option_max_file_size[1], + FixedValue(None, title=_('Don\'t configure a file size limit'), totext=_('')), ], )) @@ -956,13 +953,11 @@ _option_max_time = ('max_time', unit='s', )) _url_max_time = ('max_time', - CascadingDropdown( + Alternative( title=_('Maximum transfer time'), - sorted=False, - choices=[ - ('max_time', _('Override default maximum transfer time'), - _option_max_time[1],), - ('', _('No transfer time limit')), + elements=[ + _option_max_time[1], + FixedValue(None, title=_('Don\'t configure a transfer time limit'), totext=_('')), ], )) @@ -986,12 +981,11 @@ _option_speed_limit = ('speed_limit', ], orientation='horizontal', )) _url_speed_limit = ('speed_limit', - CascadingDropdown( + Alternative( title=_('Minimum speed'), - sorted=False, - choices=[ - ('speed_limit', _('Override default minimum speed'), _option_speed_limit[1],), - ('', _('No lower speed limit')), + elements=[ + _option_speed_limit[1], + FixedValue(None, title=_('Don\'t configure a lower speed limit'), totext=_('')), ], )) @@ -1002,13 +996,11 @@ _option_speed_time = ('speed_time', minvalue=1, unit='s', )) _url_speed_time = ('speed_time', - CascadingDropdown( + Alternative( title=_('Minimum speed time'), - sorted=False, - choices=[ - ('speed_time', _('Override default minimum speed time'), - _option_speed_time[1],), - ('', _('No minimum speed time limit')), + elements=[ + _option_speed_time[1], + FixedValue(None, title=_('Don\'t configure a minimum speed time limit'), totext=_('')), ], )) @@ -1019,13 +1011,11 @@ _option_connect_timeout = ('connect_timeout', minvalue=1, unit='s', )) _url_connect_timeout = ('connect_timeout', - CascadingDropdown( + Alternative( title=_('Maximum time to connect'), - sorted=False, - choices=[ - ('connect_timeout', _('Override default maximum time to connect'), - _option_connect_timeout[1],), - ('', _('Don\'t configure a maximum time to connect')), + elements=[ + _option_connect_timeout[1], + FixedValue(None, title=_('Don\'t configure a maximum time to connect'), totext=_('')), ], )) @@ -1044,6 +1034,21 @@ _option_limits = ('limits', ), title=_('Set connection limits') )) +_url_limits = ('limits', + Foldable( + Dictionary( + title=_('Limits'), + elements=[ + _url_limit_rate, + _url_max_file_size, + _url_connect_timeout, + _url_max_time, + _url_speed_limit, + _url_speed_time, + ] + ), + title=_('Override connection limits') + )) _option_user_agent = ('user_agent', TextUnicode( @@ -1073,14 +1078,12 @@ _option_referer = ('referer', forbidden_chars='|" ', )) _url_referer = ('referer', - CascadingDropdown( - title=_('Set referer'), - sorted=False, - choices=[ - ('referer', _('Override default referer'), - _option_referer[1],), - ('', _('Don\'t configure a referer')), - ], + Alternative( + title=_('Override default referer'), + elements=[ + _option_referer[1], + FixedValue(None, title=_('Don\'t configure a referer'), totext=_('')) + ] )) _options_compressed = ('compressed', @@ -1098,21 +1101,6 @@ _url_compressed = ('compressed', ], )) -_options_no_npn = ('no_npn', - FixedValue( - '--no-npn', - title=_('Next Protocol Negotiation (NPN)'), - totext=_('Next Protocol Negotiation disabled'), - )) -_url_no_npn = ('no_npn', - DropdownChoice( - title=_('Next Protocol Negotiation (NPN)'), - choices=[ - ('--no-npn', _('Disable Next Protocol Negotiation')), - ('', _('Don\'t disable Next Protocol Negotiation')), - ], - )) - _option_post = ('post_binary', Tuple( title=_('Send HTTP POST data'), @@ -1153,7 +1141,7 @@ _option_url_settings = ('url_settings', _url_user_agent, _url_header_strings, _url_expected_strings, - _option_limits, + _url_limits, _option_address_resolution, _option_ftp_settings, _option_mail_settings, @@ -1272,33 +1260,56 @@ _option_plugin_timeout = ('timeout', ), ),) -elements = [ - _option_url, - _option_plugin_interval, - _option_plugin_timeout, - _option_default_settings, -] +_option_curl_executable = ('curl_executable', + DropdownChoice( + title=_('cURL executable to use'), + help=_( + 'By default this plugin will use the system provided cURL executable. You can ' + 'decide to deploy a separate cURL executable. If you do so you need to install the ' + 'optional CMK package curl_executable<version>.mkp.' + ), + choices=[ + (None, _('Use system provided cURL executable')), + ('64bit', _('Deploy 64bit cURL version')), + ('32bit', _('Deploy 32bit cURL version')), + ] + )) + + +def _transform_forth_agent_config_curl(params): + # transform added 20220410 on removing os specific rules + if type(params) == tuple: + if params[0] in ['linux', 'windows', 'deploy']: + params = params[1] + else: + params = None + return params def _valuespec_agent_config_curl(): - return CascadingDropdown( - title=_('cURL'), - sorted=False, - choices=[ - ('linux', - _('Deploy Linux cURL agent plugin'), - Dictionary( - elements=elements, - required_keys=['url_list'], - )), - ('windows', - _('Deploy Windows cURL agent plugin'), - Dictionary( - elements=elements, - required_keys=['url_list'], - )), - (None, _('Do not deploy the cURL agent plugin')), - ], + return Transform( + Alternative( + title=_('cURL'), + elements=[ + Dictionary( + title=_('Deploy cURL agent plugin'), + elements=[ + _option_url, + _option_plugin_interval, + _option_plugin_timeout, + _option_curl_executable, + _option_default_settings, + ], + required_keys=['url_list'], + ), + FixedValue( + None, + title=_('Do not deploy the cURL agent plugin'), + totext=_('The cURL agent plugin will not be deployed') + ), + ], + ), + forth=_transform_forth_agent_config_curl, ) -- GitLab