MKP 2.4.0, added password store for app password, some changes for compatibility with NC 28

This commit is contained in:
mellis 2024-01-12 12:23:21 +01:00
parent 1fbeae93a1
commit 714990bffb
7 changed files with 137 additions and 89 deletions

2
.gitignore vendored
View File

@ -16,7 +16,7 @@ __pycache__/
*.vsix *.vsix
# Exclude all "private" files (Ralf Mellis) # Exclude all "private" files (Ralf Mellis)
RaMe* RM*
# Exclude all "private" files (Torsten Behne) # Exclude all "private" files (Torsten Behne)
TB* TB*

View File

@ -1,7 +1,7 @@
# Nextcloud CheckMK Special Agent # Nextcloud CheckMK Special Agent
Monitors various aspects of Nextcloud instances like state, quota and disk usage of all users, number of apps with available updates, database php opcache hit rate and so on. Monitors various aspects of Nextcloud instances like state, quota and disk usage of all users, number of apps with available updates, database php opcache hit rate and so on.
Gives additional information regarding versions of Nextcloud, database, number of storages and active users etc. Gives additional information regarding versions of Nextcloud, database, number of storages and active users etc.
Tested with Nextcloud 25/26/27. Tested with Nextcloud 25/26/27/28.
Tested only with MySQL/MariaDB as database backend. Tested only with MySQL/MariaDB as database backend.
Feel free to report other working environments. Feel free to report other working environments.
@ -9,6 +9,7 @@ Version History:
-- --
|Date|Version|Changes| |Date|Version|Changes|
|----|-------|-------| |----|-------|-------|
|2023/01/12|2.4.0|Integrated Password Store for App Password, some changes for compatibility with NC 28 added|
|2023/11/26|2.3.4|Fixed agent crash if opcache_get_status is disabled by server settings| |2023/11/26|2.3.4|Fixed agent crash if opcache_get_status is disabled by server settings|
|2023/08/16|2.3.3|Fixed some misleading info strings regarding database opcache| |2023/08/16|2.3.3|Fixed some misleading info strings regarding database opcache|
|2023/08/12|2.3.2|MKP now compatible with CheckMK 2.2| |2023/08/12|2.3.2|MKP now compatible with CheckMK 2.2|

View File

@ -1,7 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from pprint import pprint from pprint import pprint
from datetime import datetime
from .agent_based_api.v1 import register, render, Service, Result, State, Metric from .agent_based_api.v1 import register, render, Service, Result, State, Metric
def getStateUpper(levels, value): def getStateUpper(levels, value):
warn, crit = levels warn, crit = levels
if value >= crit: if value >= crit:
@ -10,6 +12,7 @@ def getStateUpper(levels, value):
return State.WARN return State.WARN
return State.OK return State.OK
def getStateLower(levels, value): def getStateLower(levels, value):
warn, crit = levels warn, crit = levels
if value < crit: if value < crit:
@ -18,14 +21,25 @@ def getStateLower(levels, value):
return State.WARN return State.WARN
return State.OK return State.OK
def discover_nextcloud_info(section): def discover_nextcloud_info(section):
yield(Service()) yield(Service())
def check_nextcloud_info(params, section): def check_nextcloud_info(params, section):
for key in section: for key in section:
if key == "nextcloud": if key == "nextcloud":
levels_free_space = params["levels_free_space"] levels_free_space = params["levels_free_space"]
levels_number_of_files = params["levels_number_of_files"] levels_number_of_files = params["levels_number_of_files"]
# update infos are available only from Nextcloud version 28 onwards
try:
last_update = section[key]["last_update"]
update_available = section[key]["update_available"]
last_update_human = datetime.fromtimestamp(last_update)
except KeyError:
last_update = "Update information not available, update to at least version 28"
update_available = "False"
last_update_human = "Update information not available"
status = section[key]["status"] status = section[key]["status"]
free_space = section[key]["freespace"] free_space = section[key]["freespace"]
version = section[key]["version"] version = section[key]["version"]
@ -40,13 +54,23 @@ def check_nextcloud_info(params, section):
# create overall result # create overall result
summary = f"Status is {status}" summary = f"Status is {status}"
details = f"Nextcloud version: {version}\nPHP version: {php_version}\nWebserver: {webserver}\n\nNumber of files: {num_files}\nNumber of shares: {num_shares}\n\nFree space on disk: {render.bytes(free_space)}\n" details = f"Nextcloud version: {version}\nLast update: {last_update_human}\nPHP version: {php_version}\nWebserver: {webserver}\n\nNumber of files: {num_files}\nNumber of shares: {num_shares}\n\nFree space on disk: {render.bytes(free_space)}\n"
if status == "ok": if status == "ok":
state = State.OK state = State.OK
else: else:
state = State.CRIT state = State.CRIT
yield Result(state=state, summary=summary, details=details) yield Result(state=state, summary=summary, details=details)
# Create result for available updates
if update_available != "False":
state = State.WARN
notice = f"Update is available"
else:
state = State.OK
notice = "No update available"
if state != State.OK:
yield(Result(state=state, notice=notice))
# Create result for free space on disk # Create result for free space on disk
# Levels for free space are given in GBytes, we have to adjust this here # Levels for free space are given in GBytes, we have to adjust this here
warn, crit = levels_free_space warn, crit = levels_free_space
@ -90,6 +114,8 @@ def check_nextcloud_info(params, section):
notice = f"Number of storages: {num_storages}\nNumber of home/local/other storages: {num_storages_home}/{num_storages_local}/{num_storages_other}" notice = f"Number of storages: {num_storages}\nNumber of home/local/other storages: {num_storages_home}/{num_storages_local}/{num_storages_other}"
yield(Result(state=State.OK, notice=notice)) yield(Result(state=State.OK, notice=notice))
elif key == "apps": elif key == "apps":
# Workaround for Nextcloud 28, "apps" info is not always available
try:
num_apps_installed = section[key]["installed"] num_apps_installed = section[key]["installed"]
num_apps_with_updates_available = section[key]["with_updates_available"] num_apps_with_updates_available = section[key]["with_updates_available"]
# create graphs for number of apps # create graphs for number of apps
@ -99,6 +125,9 @@ def check_nextcloud_info(params, section):
state = getStateUpper(levels, num_apps_with_updates_available) state = getStateUpper(levels, num_apps_with_updates_available)
notice = f"Number of installed apps: {num_apps_installed}\nNumber of apps with updates available: {num_apps_with_updates_available}" notice = f"Number of installed apps: {num_apps_installed}\nNumber of apps with updates available: {num_apps_with_updates_available}"
yield(Result(state=state, notice=notice)) yield(Result(state=state, notice=notice))
except KeyError:
pass
def parse_nextcloud_info_section(string_table): def parse_nextcloud_info_section(string_table):
parsed_data = { parsed_data = {
@ -111,6 +140,8 @@ def parse_nextcloud_info_section(string_table):
"NC_Version", "NC_Version",
"NC_Freespace", "NC_Freespace",
"NC_Status", "NC_Status",
"NC_Last_Update",
"NC_Update_Available",
"NC_Webserver", "NC_Webserver",
"NC_PHP_Version", "NC_PHP_Version",
"NC_Num_Users", "NC_Num_Users",
@ -136,6 +167,10 @@ def parse_nextcloud_info_section(string_table):
parsed_data["nextcloud"]["freespace"] = float(value) parsed_data["nextcloud"]["freespace"] = float(value)
elif param == "NC_Status": elif param == "NC_Status":
parsed_data["nextcloud"]["status"] = value parsed_data["nextcloud"]["status"] = value
elif param == "NC_Last_Update":
parsed_data["nextcloud"]["last_update"] = int(value)
elif param == "NC_Update_Available":
parsed_data["nextcloud"]["update_available"] = value
elif param == "NC_Webserver": elif param == "NC_Webserver":
parsed_data["nextcloud"]["webserver"] = value parsed_data["nextcloud"]["webserver"] = value
elif param == "NC_PHP_Version": elif param == "NC_PHP_Version":
@ -164,13 +199,16 @@ def parse_nextcloud_info_section(string_table):
parsed_data["users"]["active_last1hour"] = int(value) parsed_data["users"]["active_last1hour"] = int(value)
elif param == "NC_Active_Users_Last_1Day": elif param == "NC_Active_Users_Last_1Day":
parsed_data["users"]["active_last1day"] = int(value) parsed_data["users"]["active_last1day"] = int(value)
#pprint(parsed_data)
return parsed_data return parsed_data
register.agent_section( register.agent_section(
name="nextcloud_info", name="nextcloud_info",
parse_function=parse_nextcloud_info_section, parse_function=parse_nextcloud_info_section,
) )
register.check_plugin( register.check_plugin(
name="nextcloud_info", name="nextcloud_info",
service_name="Nextcloud Info", service_name="Nextcloud Info",

View File

@ -9,6 +9,7 @@ import os
from pprint import pprint from pprint import pprint
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
from requests.auth import HTTPBasicAuth from requests.auth import HTTPBasicAuth
import cmk.utils.password_store
def showUsage(): def showUsage():
sys.stderr.write("""CheckMK Nextcloud Special Agent sys.stderr.write("""CheckMK Nextcloud Special Agent
@ -34,7 +35,7 @@ OPTIONS:
# be aware: activating this logs very sensitive information to debug files in ~/tmp # be aware: activating this logs very sensitive information to debug files in ~/tmp
# !!DO NOT FORGET to delete these files after debugging is done!! # !!DO NOT FORGET to delete these files after debugging is done!!
DEBUG = False DEBUG = True
nc_api_endpoint = "ocs/v2.php/apps/serverinfo/api/v1/info?format=json" nc_api_endpoint = "ocs/v2.php/apps/serverinfo/api/v1/info?format=json"
nc_api_endpoint_all_users = "ocs/v1.php/cloud/users?format=json" nc_api_endpoint_all_users = "ocs/v1.php/cloud/users?format=json"
@ -54,6 +55,15 @@ long_options = [
'hostname=', 'username=', 'password=', 'port=', 'token=', 'folder=', 'no-https=', 'no-cert-check=', 'help' 'hostname=', 'username=', 'password=', 'port=', 'token=', 'folder=', 'no-https=', 'no-cert-check=', 'help'
] ]
def logDebug(line):
if DEBUG:
home_path = os.getenv("HOME")
tmp_path = f"{home_path}/tmp"
help_file = f"{tmp_path}/nextcloud_{opt_hostname}_{opt_port}_debug.txt"
with open(help_file, "a") as file:
file.write(line)
def getOptions(): def getOptions():
global opt_hostname global opt_hostname
global opt_username global opt_username
@ -91,12 +101,7 @@ def getOptions():
elif opt in ['-h', '--help']: elif opt in ['-h', '--help']:
showUsage() showUsage()
sys.exit(0) sys.exit(0)
if DEBUG: logDebug(f"getOptions - Number of Arguments: {len(sys.argv)}, Argument List: {str(sys.argv)}\n")
home_path = os.getenv("HOME")
tmp_path = f"{home_path}/tmp"
help_file = f"{tmp_path}/nextcloud_{opt_hostname}_debug.txt"
with open(help_file, "a") as file:
file.write(f"Number of Arguments: {len(sys.argv)}, Argument List: {str(sys.argv)}\n")
def showOptions(): def showOptions():
print(f"Hostname: {opt_hostname}") print(f"Hostname: {opt_hostname}")
@ -107,48 +112,41 @@ def showOptions():
print(f"Token: {opt_token}") print(f"Token: {opt_token}")
print(f"No HTTPS: {opt_no_https}") print(f"No HTTPS: {opt_no_https}")
print(f"No TLS Check: {opt_no_cert_check}") print(f"No TLS Check: {opt_no_cert_check}")
home_path = os.getenv("HOME") logDebug(f"showOptions - Hostname: {opt_hostname}, Port: {opt_port}, No HTTPS: {opt_no_https}, No Cert Check: {opt_no_cert_check}\n")
tmp_path = f"{home_path}/tmp"
help_file = f"{tmp_path}/nextcloud_{opt_hostname}_debug.txt"
with open(help_file, "a") as file:
file.write(f"Hostname: {opt_hostname}, Port: {opt_port}, No HTTPS: {opt_no_https}, No Cert Check: {opt_no_cert_check}\n")
def createUrl(endpoint, hostname, protocol, port, folder): def createUrl(endpoint, hostname, protocol, port, folder):
# these parameters are needed, otherwise no information about updates regarding apps and Nextcloud itself are not reported (since version 28)
params = "skipApps=false&skipUpdate=false"
if folder == "": if folder == "":
url = f"{protocol}://{hostname}:{port}/{endpoint}" url = f"{protocol}://{hostname}:{port}/{endpoint}"
else: else:
url = f"{protocol}://{hostname}:{port}/{folder}/{endpoint}" url = f"{protocol}://{hostname}:{port}/{folder}/{endpoint}"
if DEBUG: if endpoint == nc_api_endpoint:
home_path = os.getenv("HOME") url = f"{url}&{params}"
tmp_path = f"{home_path}/tmp" logDebug(f"createUrl - Data URL: {url}\n")
help_file = f"{tmp_path}/nextcloud_{hostname}_debug.txt"
with open(help_file, "a") as file:
file.write(f"Data URL: {url}\n")
return url return url
def createUrlUser(user, endpoint, hostname, protocol, port, folder): def createUrlUser(user, endpoint, hostname, protocol, port, folder):
params = "format=json"
if folder == "": if folder == "":
url = f"{protocol}://{hostname}:{port}/{endpoint}/{user}?format=json" url = f"{protocol}://{hostname}:{port}/{endpoint}/{user}?{params}"
else: else:
url = f"{protocol}://{hostname}:{port}/{folder}/{endpoint}/{user}?format=json" url = f"{protocol}://{hostname}:{port}/{folder}/{endpoint}/{user}?{params}"
if DEBUG: logDebug(f"createUrlUser - User URL: {url}\n")
home_path = os.getenv("HOME")
tmp_path = f"{home_path}/tmp"
help_file = f"{tmp_path}/nextcloud_{hostname}_debug.txt"
with open(help_file, "a") as file:
file.write(f"User URL: {url}\n")
return url return url
def getData(url, verify): def getSession(username, secret):
session = requests.session()
session.cookies.set("SameSite", "Strict")
session.auth = (username, secret)
session.headers['Accept'] = "application/json"
return session
def getData(session, url, verify):
headers = CaseInsensitiveDict() headers = CaseInsensitiveDict()
headers["Accept"] = "application/json" headers["Accept"] = "application/json"
if (opt_token == '0'): cookies = {"nc_sameSiteCookiestrict": "true"}
# authenticate with username and password response = session.get(url, headers=headers, cookies=cookies, verify=verify)
pwd = opt_password
else:
# authenticate with token
pwd = opt_token
response = requests.get(url, auth=HTTPBasicAuth(opt_username, pwd), headers=headers, verify=verify)
status = response.status_code status = response.status_code
if (status == 200): if (status == 200):
jsdata = response.text jsdata = response.text
@ -162,17 +160,12 @@ def getData(url, verify):
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n") sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1) sys.exit(1)
def getDataAllUsers(url, verify): def getDataAllUsers(session, url, verify):
headers = CaseInsensitiveDict() headers = CaseInsensitiveDict()
headers["Accept"] = "application/json" headers["Accept"] = "application/json"
headers["OCS-APIRequest"] = "true" headers["OCS-APIRequest"] = "true"
if (opt_token == '0'): cookies = {"nc_sameSiteCookiestrict": "true"}
# authenticate with username and password response = session.get(url, headers=headers, cookies=cookies, verify=verify)
pwd = opt_password
else:
# authenticate with token
pwd = opt_token
response = requests.get(url, auth=HTTPBasicAuth(opt_username, pwd), headers=headers, verify=verify)
status = response.status_code status = response.status_code
if (status == 200): if (status == 200):
jsdata = response.text jsdata = response.text
@ -182,18 +175,12 @@ def getDataAllUsers(url, verify):
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n") sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1) sys.exit(1)
def getDataUser(url, verify): def getDataUser(session, url, verify):
#print(url)
headers = CaseInsensitiveDict() headers = CaseInsensitiveDict()
headers["Accept"] = "application/json" headers["Accept"] = "application/json"
headers["OCS-APIRequest"] = "true" headers["OCS-APIRequest"] = "true"
if (opt_token == '0'): cookies = {"nc_sameSiteCookiestrict": "true"}
# authenticate with username and password response = session.get(url, headers=headers, cookies=cookies, verify=verify)
pwd = opt_password
else:
# authenticate with token
pwd = opt_token
response = requests.get(url, auth=HTTPBasicAuth(opt_username, pwd), headers=headers, verify=verify)
status = response.status_code status = response.status_code
if (status == 200): if (status == 200):
jsdata = response.text jsdata = response.text
@ -208,6 +195,12 @@ def doCmkOutput(data):
print(f"NC_Version;{data['ocs']['data']['nextcloud']['system']['version']}") print(f"NC_Version;{data['ocs']['data']['nextcloud']['system']['version']}")
print(f"NC_Freespace;{data['ocs']['data']['nextcloud']['system']['freespace']}") print(f"NC_Freespace;{data['ocs']['data']['nextcloud']['system']['freespace']}")
print(f"NC_Status;{data['ocs']['meta']['status']}") print(f"NC_Status;{data['ocs']['meta']['status']}")
# This update info is available only from version 28 onwards, so the key "update" does not exist in all versions before
try:
print(f"NC_Last_Update;{data['ocs']['data']['nextcloud']['system']['update']['lastupdatedat']}")
print(f"NC_Update_Available;{data['ocs']['data']['nextcloud']['system']['update']['available']}")
except KeyError:
pass
print(f"NC_Num_Users;{data['ocs']['data']['nextcloud']['storage']['num_users']}") print(f"NC_Num_Users;{data['ocs']['data']['nextcloud']['storage']['num_users']}")
print(f"NC_Num_Files;{data['ocs']['data']['nextcloud']['storage']['num_files']}") print(f"NC_Num_Files;{data['ocs']['data']['nextcloud']['storage']['num_files']}")
print(f"NC_Num_Shares;{data['ocs']['data']['nextcloud']['shares']['num_shares']}") print(f"NC_Num_Shares;{data['ocs']['data']['nextcloud']['shares']['num_shares']}")
@ -215,8 +208,12 @@ def doCmkOutput(data):
print(f"NC_Num_Storages_Home;{data['ocs']['data']['nextcloud']['storage']['num_storages_home']}") print(f"NC_Num_Storages_Home;{data['ocs']['data']['nextcloud']['storage']['num_storages_home']}")
print(f"NC_Num_Storages_Local;{data['ocs']['data']['nextcloud']['storage']['num_storages_local']}") print(f"NC_Num_Storages_Local;{data['ocs']['data']['nextcloud']['storage']['num_storages_local']}")
print(f"NC_Num_Storages_Other;{data['ocs']['data']['nextcloud']['storage']['num_storages_other']}") print(f"NC_Num_Storages_Other;{data['ocs']['data']['nextcloud']['storage']['num_storages_other']}")
# Workaround for Nextcloud 28.0.1 (KeyError "apps")
try:
print(f"NC_Num_Apps_Installed;{data['ocs']['data']['nextcloud']['system']['apps']['num_installed']}") print(f"NC_Num_Apps_Installed;{data['ocs']['data']['nextcloud']['system']['apps']['num_installed']}")
print(f"NC_Num_Apps_Updates_Available;{data['ocs']['data']['nextcloud']['system']['apps']['num_updates_available']}") print(f"NC_Num_Apps_Updates_Available;{data['ocs']['data']['nextcloud']['system']['apps']['num_updates_available']}")
except KeyError:
pass
print(f"NC_Active_Users_Last_5Min;{data['ocs']['data']['activeUsers']['last5minutes']}") print(f"NC_Active_Users_Last_5Min;{data['ocs']['data']['activeUsers']['last5minutes']}")
print(f"NC_Active_Users_Last_1Hour;{data['ocs']['data']['activeUsers']['last1hour']}") print(f"NC_Active_Users_Last_1Hour;{data['ocs']['data']['activeUsers']['last1hour']}")
print(f"NC_Active_Users_Last_1Day;{data['ocs']['data']['activeUsers']['last24hours']}") print(f"NC_Active_Users_Last_1Day;{data['ocs']['data']['activeUsers']['last24hours']}")
@ -234,11 +231,11 @@ def doCmkOutput(data):
else: else:
print(f"NC_OPCache_Hit_Rate;0") print(f"NC_OPCache_Hit_Rate;0")
def doCmkOutputAllUsers(data, verify, hostname, protocol, port, folder): def doCmkOutputAllUsers(session, data, verify, hostname, protocol, port, folder):
print("<<<nextcloud_users:sep(59)>>>") print("<<<nextcloud_users:sep(59)>>>")
for user in data['ocs']['data']['users']: for user in data['ocs']['data']['users']:
nc_url = createUrlUser(user, nc_api_endpoint_user, hostname, protocol, port, folder) nc_url = createUrlUser(user, nc_api_endpoint_user, hostname, protocol, port, folder)
user_data = getDataUser(nc_url, verify) user_data = getDataUser(session, nc_url, verify)
userid = user_data['ocs']['data']['id'] userid = user_data['ocs']['data']['id']
displayname = user_data['ocs']['data']['displayname'] displayname = user_data['ocs']['data']['displayname']
lastlogin = int(user_data['ocs']['data']['lastLogin']) lastlogin = int(user_data['ocs']['data']['lastLogin'])
@ -260,6 +257,8 @@ def doCmkOutputAllUsers(data, verify, hostname, protocol, port, folder):
print(f"{userid};{displayname};{lastlogin};{quota_free};{quota_quota};{quota_relative};{quota_total};{quota_used}") print(f"{userid};{displayname};{lastlogin};{quota_free};{quota_quota};{quota_relative};{quota_total};{quota_used}")
def main(): def main():
# replace password from pwd store
cmk.utils.password_store.replace_passwords()
getOptions() getOptions()
if (opt_hostname == ""): if (opt_hostname == ""):
sys.stderr.write(f"No hostname given.\n") sys.stderr.write(f"No hostname given.\n")
@ -291,12 +290,21 @@ def main():
if (protocol == "https" and port == "80"): if (protocol == "https" and port == "80"):
sys.stderr.write(f"Combining HTTPS with port 80 is not supported.\n") sys.stderr.write(f"Combining HTTPS with port 80 is not supported.\n")
sys.exit(1) sys.exit(1)
if (opt_token == '0'):
# authenticate with username and password
pwd = opt_password
else:
# authenticate with token
pwd = opt_token
# create session
session = getSession(opt_username, pwd)
nc_url = createUrl(nc_api_endpoint, opt_hostname, protocol, port, opt_folder) nc_url = createUrl(nc_api_endpoint, opt_hostname, protocol, port, opt_folder)
nc_data = getData(nc_url, verify) nc_data = getData(session, nc_url, verify)
doCmkOutput(nc_data) doCmkOutput(nc_data)
nc_url = createUrl(nc_api_endpoint_all_users, opt_hostname, protocol, port, opt_folder) nc_url = createUrl(nc_api_endpoint_all_users, opt_hostname, protocol, port, opt_folder)
nc_data = getDataAllUsers(nc_url, verify) nc_data = getDataAllUsers(session, nc_url, verify)
doCmkOutputAllUsers(nc_data, verify, opt_hostname, protocol, port, opt_folder) doCmkOutputAllUsers(session, nc_data, verify, opt_hostname, protocol, port, opt_folder)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -3,7 +3,7 @@ def agent_nextcloud_arguments(params, hostname, ipaddress):
"--hostname", params["hostname"], "--hostname", params["hostname"],
"--username", params["username"], "--username", params["username"],
"--password", params["password"], "--password", params["password"],
"--token", params["token"], "--token", passwordstore_get_cmdline("%s", params["token"]),
"--port", params["port"], "--port", params["port"],
"--folder", params["folder"], "--folder", params["folder"],
"--no-https", params["no_https"], "--no-https", params["no_https"],

View File

@ -1,10 +1,13 @@
from cmk.gui.i18n import _ #!/usr/bin/env python3
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithItem,
rulespec_registry,
RulespecGroupCheckParametersOperatingSystem,
)
from cmk.gui.i18n import _
from cmk.gui.plugins.wato.special_agents.common import RulespecGroupDatasourceProgramsApps
from cmk.gui.plugins.wato.utils import (
HostRulespec,
Rulespec,
IndividualOrStoredPassword,
rulespec_registry,
)
from cmk.gui.valuespec import ( from cmk.gui.valuespec import (
Dictionary, Dictionary,
ListChoice, ListChoice,
@ -13,11 +16,8 @@ from cmk.gui.valuespec import (
Password, Password,
) )
from cmk.gui.plugins.wato import ( def _factory_default_special_agent_nextcloud():
HostRulespec, return Rulespec.FACTORY_DEFAULT_UNUSED
)
from cmk.gui.plugins.wato.datasource_programs import RulespecGroupDatasourceProgramsCustom
def _valuespec_special_agent_nextcloud(): def _valuespec_special_agent_nextcloud():
return Dictionary( return Dictionary(
@ -33,7 +33,7 @@ def _valuespec_special_agent_nextcloud():
("password", Password(title=_("Password"), ("password", Password(title=_("Password"),
allow_empty=True, allow_empty=True,
help=_("Specify password OR token, not both, token recommended"))), help=_("Specify password OR token, not both, token recommended"))),
("token", Password(title=_("Token"), ("token", IndividualOrStoredPassword(title=_("App Password"),
allow_empty=True, allow_empty=True,
help=_("Specify password OR token, not both, token recommended"))), help=_("Specify password OR token, not both, token recommended"))),
("port", TextAscii(title=_("Port"), ("port", TextAscii(title=_("Port"),
@ -52,8 +52,9 @@ def _valuespec_special_agent_nextcloud():
rulespec_registry.register( rulespec_registry.register(
HostRulespec( HostRulespec(
group=RulespecGroupDatasourceProgramsCustom, factory_default = _factory_default_special_agent_nextcloud(),
name="special_agents:nextcloud", group = RulespecGroupDatasourceProgramsApps,
valuespec=_valuespec_special_agent_nextcloud, name = "special_agents:nextcloud",
valuespec = _valuespec_special_agent_nextcloud,
) )
) )

BIN
mkp/Nextcloud-2.4.0.mkp Normal file

Binary file not shown.