Initial Commit v2.2.0

This commit is contained in:
Ralf Mellis 2023-03-11 14:29:54 +01:00
parent bc5a12babd
commit b0d808ae60
14 changed files with 1038 additions and 0 deletions

View File

@ -0,0 +1,79 @@
#!/usr/bin/env python3
from pprint import pprint
from .agent_based_api.v1 import register, render, Service, Result, State, Metric
def getStateUpper(levels, value):
warn, crit = levels
if value >= crit:
return State.CRIT
if value >= warn:
return State.WARN
return State.OK
def getStateLower(levels, value):
warn, crit = levels
if value < crit:
return State.CRIT
if value < warn:
return State.WARN
return State.OK
def discover_nextcloud_database(section):
yield(Service())
def check_nextcloud_database(params, section):
for key in section:
if key == "database":
opcache_hit_rate = section[key]["opcache_hit_rate"]
size = section[key]["size"]
type = section[key]["type"]
version = section[key]["version"]
levels = params["levels_database_opcache_hit_rate"]
# create graph for opcache hit rate
yield Metric("nc_database_opcache_hit_rate", opcache_hit_rate, levels=levels)
# create graph for database size
yield Metric("nc_database_size", size)
state = getStateLower(levels, opcache_hit_rate)
summary = f"Cache hit rate: {render.percent(opcache_hit_rate)}"
details = f"\nDatabase type: {type}\nDatabase version: {version}\nDatabase size: {render.bytes(size)}"
yield(Result(state=state, summary=summary, details=details))
def parse_nextcloud_database_section(string_table):
parsed_data = {
"database" : {}
}
params_list = [
"NC_Database_Type",
"NC_Database_Version",
"NC_Database_Size",
"NC_OPCache_Hit_Rate"
]
for line in string_table:
if line[0] in params_list:
param = line[0]
value = line[1]
if param == "NC_Database_Type":
parsed_data["database"]["type"] = value
elif param == "NC_Database_Version":
parsed_data["database"]["version"] = value
elif param == "NC_Database_Size":
parsed_data["database"]["size"] = int(value)
elif param == "NC_OPCache_Hit_Rate":
parsed_data["database"]["opcache_hit_rate"] = float(value)
return parsed_data
register.agent_section(
name="nextcloud_database",
parse_function=parse_nextcloud_database_section,
)
register.check_plugin(
name="nextcloud_database",
service_name="Nextcloud Database",
discovery_function=discover_nextcloud_database,
check_function=check_nextcloud_database,
check_default_parameters={
"levels_database_opcache_hit_rate": (99.7, 99.1),
},
check_ruleset_name="nextcloud_database",
)

View File

@ -0,0 +1,147 @@
#!/usr/bin/env python3
from pprint import pprint
from .agent_based_api.v1 import register, render, Service, Result, State, Metric
def getStateUpper(levels, value):
warn, crit = levels
if value >= crit:
return State.CRIT
if value >= warn:
return State.WARN
return State.OK
def getStateLower(levels, value):
warn, crit = levels
if value < crit:
return State.CRIT
if value < warn:
return State.WARN
return State.OK
def discover_nextcloud_info(section):
yield(Service())
def check_nextcloud_info(params, section):
for key in section:
if key == "nextcloud":
status = section[key]["status"]
version = section[key]["version"]
num_files = section[key]["number_files"]
num_shares = section[key]["number_shares"]
# create graph for number of files and shares
yield(Metric("nc_num_files", num_files))
yield(Metric("nc_num_shares", num_shares))
summary = f"Status is {status}"
details = f"Version is {version}\nNumber of files: {num_files}\nNumber of shares: {num_shares}\n"
if status == "ok":
state = State.OK
else:
state = State.CRIT
yield Result(state=state, summary=summary, details=details)
elif key == "users":
num_users = section[key]["number"]
num_active_last1hour = section[key]["active_last1hour"]
num_active_last1day = section[key]["active_last1day"]
num_active_last5min = section[key]["active_last5min"]
# create graphs for number of users
yield Metric("nc_num_users", num_users)
yield Metric("nc_active_users_last_1hour", num_active_last1hour)
yield Metric("nc_active_users_last_1day", num_active_last1day)
yield Metric("nc_active_users_last_5min", num_active_last5min)
notice = f"Number of users: {num_users}\n\nActive users last 5 min: {num_active_last5min}\nActive user since last hour: {num_active_last1hour}\nActive users since last day: {num_active_last1day}"
yield(Result(state=State.OK, notice=notice))
elif key == "storages":
num_storages = section[key]["number"]
num_storages_home = section[key]["number_home"]
num_storages_local = section[key]["number_local"]
num_storages_other = section[key]["number_other"]
# create graphs for number of storages
yield Metric("nc_num_storages", num_storages)
yield Metric("nc_num_storages_home", num_storages_home)
yield Metric("nc_num_storages_local", num_storages_local)
yield Metric("nc_num_storages_other", 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))
elif key == "apps":
num_apps_installed = section[key]["installed"]
num_apps_with_updates_available = section[key]["with_updates_available"]
# create graphs for number of apps
levels = params["levels_apps_with_updates_available"]
yield Metric("nc_num_apps_installed", num_apps_installed)
yield Metric("nc_apps_with_updates_available", num_apps_with_updates_available, levels=levels)
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}"
yield(Result(state=state, notice=notice))
def parse_nextcloud_info_section(string_table):
parsed_data = {
"nextcloud" : {},
"storages" : {},
"apps" : {},
"users" : {},
}
params_list = [
"NC_Version",
"NC_Status",
"NC_Num_Users",
"NC_Num_Files",
"NC_Num_Shares",
"NC_Num_Storages",
"NC_Num_Storages_Home",
"NC_Num_Storages_Local",
"NC_Num_Storages_Other",
"NC_Num_Apps_Installed",
"NC_Num_Apps_Updates_Available",
"NC_Active_Users_Last_5Min",
"NC_Active_Users_Last_1Hour",
"NC_Active_Users_Last_1Day"
]
for line in string_table:
if line[0] in params_list:
param = line[0]
value = line[1]
if param == "NC_Version":
parsed_data["nextcloud"]["version"] = value
elif param == "NC_Status":
parsed_data["nextcloud"]["status"] = value
elif param == "NC_Num_Files":
parsed_data["nextcloud"]["number_files"] = int(value)
elif param == "NC_Num_Shares":
parsed_data["nextcloud"]["number_shares"] = int(value)
elif param == "NC_Num_Storages":
parsed_data["storages"]["number"] = int(value)
elif param == "NC_Num_Storages_Home":
parsed_data["storages"]["number_home"] = int(value)
elif param == "NC_Num_Storages_Local":
parsed_data["storages"]["number_local"] = int(value)
elif param == "NC_Num_Storages_Other":
parsed_data["storages"]["number_other"] = int(value)
elif param == "NC_Num_Apps_Installed":
parsed_data["apps"]["installed"] = int(value)
elif param == "NC_Num_Apps_Updates_Available":
parsed_data["apps"]["with_updates_available"] = int(value)
elif param == "NC_Num_Users":
parsed_data["users"]["number"] = int(value)
elif param == "NC_Active_Users_Last_5Min":
parsed_data["users"]["active_last5min"] = int(value)
elif param == "NC_Active_Users_Last_1Hour":
parsed_data["users"]["active_last1hour"] = int(value)
elif param == "NC_Active_Users_Last_1Day":
parsed_data["users"]["active_last1day"] = int(value)
return parsed_data
register.agent_section(
name="nextcloud_info",
parse_function=parse_nextcloud_info_section,
)
register.check_plugin(
name="nextcloud_info",
service_name="Nextcloud Info",
discovery_function=discover_nextcloud_info,
check_function=check_nextcloud_info,
check_default_parameters={
"levels_apps_with_updates_available": (1, 2),
},
check_ruleset_name="nextcloud_info",
)

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python3
from pprint import pprint
from time import time
from .agent_based_api.v1 import register, render, Service, Result, State, Metric
def getStateUpper(levels, value):
warn, crit = levels
if value >= crit:
return State.CRIT
if value >= warn:
return State.WARN
return State.OK
def getStateLower(levels, value):
warn, crit = levels
if value < crit:
return State.CRIT
if value < warn:
return State.WARN
return State.OK
def discover_nextcloud_users(section):
for key in section:
yield(Service(item = key))
def check_nextcloud_users(item, params, section):
userid = item
quota_used_percent = section[item][0]
quota_used_bytes = section[item][1]
quota_total_bytes = section[item][2]
display_name = section[item][3]
last_login_human = section[item][4]
last_login_since = section[item][5]
free_space = quota_total_bytes - quota_used_bytes
print(free_space)
levels_quota_used = params["levels_users_quota_used"]
levels_free_space = params["levels_users_free_space"]
if last_login_human == "never":
quota_used_percent = 0
details = f"User ID is '{userid}', Last login: {last_login_human}"
summary = f"Used quota of '{display_name}' can't be calculated yet (never logged in)"
else:
# Levels are given in MBytes, we have to adjust this here
warn, crit = levels_free_space
warn = warn*1024*1024
crit = crit*1024*1024
state = getStateLower((warn, crit), free_space)
details = f"User ID is '{userid}'\nLast login: {last_login_human} ({last_login_since} ago)\nFree space: {render.bytes(free_space)}"
summary = f"Used quota of '{display_name}' is {render.percent(quota_used_percent)}, {render.bytes(quota_used_bytes)}/{render.bytes(quota_total_bytes)} used"
notice = f"Remaining free space: {render.bytes(free_space)}"
yield Metric("nc_users_free_space", free_space, levels=(warn, crit))
if state != State.OK:
yield(Result(state=state, notice=notice))
yield Metric("nc_users_quota_used", quota_used_percent, levels=levels_quota_used)
state = getStateUpper(levels_quota_used, quota_used_percent)
yield(Result(state=state, summary=summary, details=details))
def parse_nextcloud_users_section(string_table):
# Raw output from check:
# userid;displayname;lastLogin;quota_free;quota_quota;quota_relative;quota_total;quota_used
# str;str;int(milli seconds since epoch);int(bytes);int(bytes);float(percent);int(bytes);int(bytes)
parsed_data = {}
for line in string_table:
userid = line[0]
display_name = line[1]
last_login = int(line[2])/1000
if last_login == 0:
# user never logged in
last_login_human = "never"
last_login_since = "never"
else:
# user logged in at least once
curr_time = int(time())
login_diff = curr_time - last_login
last_login_human = render.datetime(last_login)
last_login_since = render.timespan(login_diff)
quota_relative = float(line[5])
quota_total = float(line[6])
quota_used = float(line[7])
parsed_data[f"{userid}"] = [quota_relative, quota_used, quota_total, display_name, last_login_human, last_login_since]
return parsed_data
register.agent_section(
name = "nextcloud_users",
parse_function = parse_nextcloud_users_section,
)
register.check_plugin(
name = "nextcloud_users",
service_name = "Nextcloud User %s",
discovery_function = discover_nextcloud_users,
check_function = check_nextcloud_users,
check_default_parameters = {
"levels_users_quota_used": (65.0, 85.00),
"levels_users_free_space": (256.0, 128.0)
},
check_ruleset_name="nextcloud_users",
)

View File

@ -0,0 +1,273 @@
#!/usr/bin/env python3
import getopt
import sys
import requests
import urllib3
import json
import os
from pprint import pprint
from requests.structures import CaseInsensitiveDict
from requests.auth import HTTPBasicAuth
def showUsage():
sys.stderr.write("""CheckMK Nextcloud Special Agent
USAGE: agent_nextcloud_info -u [username] -p [password]
OR
agent_nextcloud_info -u [username] -t [token]
agent_nextcloud_info -h
OPTIONS:
-H, --hostname Hostname (FQDN or IP) of Nextcloud server
-u, --username Username
-p, --password Password
-P, --port Port
-f, --folder Subfolder if not installed in web root
-t, --token Token (recommended)
--no-https Disable HTTPS, use HTTP (not recommended!)
--no-cert-check Disable TLS certificate check (not recommended!)
-h, --help Show this help message and exit
""")
DEBUG = False
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_user = "ocs/v1.php/cloud/users"
opt_hostname = ""
opt_username = ""
opt_password = ""
opt_port = ""
opt_folder = ""
opt_token = "0"
opt_no_https = False
opt_no_cert_check = False
short_options = 'hH:u:p:P:f:t:'
long_options = [
'hostname=', 'username=', 'password=', 'port=', 'token=', 'folder=', 'no-https', 'no-cert-check', 'help'
]
def getOptions():
global opt_hostname
global opt_username
global opt_password
global opt_port
global opt_folder
global opt_token
global opt_no_https
global opt_no_cert_check
opts, args = getopt.getopt(sys.argv[1:], short_options, long_options)
for opt, arg in opts:
if opt in ['-H', '--hostname']:
opt_hostname = arg
if opt in ['-u', '--username']:
opt_username = arg
elif opt in ['-p', '--password']:
opt_password = arg
elif opt in ['-P', '--port']:
opt_port = arg
elif opt in ['-f', '--folder']:
opt_folder = arg
elif opt in ['-t', '--token']:
opt_token = arg
elif opt in ['--no-https']:
opt_no_https = True
elif opt in ['--no-cert-check']:
opt_no_cert_check = True
elif opt in ['-h', '--help']:
showUsage()
sys.exit(0)
def showOptions():
print(f"Hostname: {opt_hostname}")
print(f"Username: {opt_username}")
#print(f"Password: {opt_password}")
print(f"Port: {opt_port}")
print(f"Folder: {opt_folder}")
#print(f"Token: {opt_token}")
print(f"No HTTPS: {opt_no_https}")
print(f"No TLS Check: {opt_no_cert_check}")
if DEBUG:
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"Hostname: {opt_hostname}, Port: {opt_port}, No HTTPS: {opt_no_https} \n")
def createUrl(endpoint, hostname, protocol, port, folder):
if folder == "":
url = f"{protocol}://{hostname}:{port}/{endpoint}"
else:
url = f"{protocol}://{hostname}:{port}/{folder}/{endpoint}"
if DEBUG:
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"Data URL: {url}\n")
return url
def createUrlUser(user, endpoint, hostname, protocol, port, folder):
if folder == "":
url = f"{protocol}://{hostname}:{port}/{endpoint}/{user}?format=json"
else:
url = f"{protocol}://{hostname}:{port}/{folder}/{endpoint}/{user}?format=json"
if DEBUG:
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
def getData(url, verify):
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
if (opt_token == '0'):
# authenticate with username and password
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
if (status == 200):
jsdata = response.text
data = json.loads(jsdata) # returns a dictionary
return data
elif (status == 503):
# this code is reported when maintenance mode is on
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}, maybe maintenance mode is on?\n")
sys.exit(1)
else:
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
def getDataAllUsers(url, verify):
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["OCS-APIRequest"] = "true"
if (opt_token == '0'):
# authenticate with username and password
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
if (status == 200):
jsdata = response.text
data = json.loads(jsdata) # returns a dictionary
return data
else:
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
def getDataUser(url, verify):
#print(url)
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["OCS-APIRequest"] = "true"
if (opt_token == '0'):
# authenticate with username and password
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
if (status == 200):
jsdata = response.text
data = json.loads(jsdata) # returns a dictionary
return data
else:
sys.stderr.write(f"Request response code is {response.status_code} with URL {url}\n")
sys.exit(1)
def doCmkOutput(data):
print("<<<nextcloud_info:sep(59)>>>")
print(f"NC_Version;{data['ocs']['data']['nextcloud']['system']['version']}")
print(f"NC_Status;{data['ocs']['meta']['status']}")
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_Shares;{data['ocs']['data']['nextcloud']['shares']['num_shares']}")
print(f"NC_Num_Storages;{data['ocs']['data']['nextcloud']['storage']['num_storages']}")
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_Other;{data['ocs']['data']['nextcloud']['storage']['num_storages_other']}")
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_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_1Day;{data['ocs']['data']['activeUsers']['last24hours']}")
print("<<<nextcloud_database:sep(59)>>>")
print(f"NC_Database_Type;{data['ocs']['data']['server']['database']['type']}")
print(f"NC_Database_Version;{data['ocs']['data']['server']['database']['version']}")
print(f"NC_Database_Size;{data['ocs']['data']['server']['database']['size']}")
print(f"NC_OPCache_Hit_Rate;{data['ocs']['data']['server']['php']['opcache']['opcache_statistics']['opcache_hit_rate']}")
def doCmkOutputAllUsers(data, verify, hostname, protocol, port, folder):
print("<<<nextcloud_users:sep(59)>>>")
for user in data['ocs']['data']['users']:
nc_url = createUrlUser(user, nc_api_endpoint_user, hostname, protocol, port, folder)
user_data = getDataUser(nc_url, verify)
userid = user_data['ocs']['data']['id']
displayname = user_data['ocs']['data']['displayname']
lastlogin = int(user_data['ocs']['data']['lastLogin'])
if lastlogin == 0:
# user has never logged in
quota_free = -1
quota_quota = -1
quota_relative = -1
quota_total = -1
quota_used = -1
else:
quota_free = user_data['ocs']['data']['quota']['free']
# quota_quota == -3 --> unlimited
quota_quota = user_data['ocs']['data']['quota']['quota']
# quota_relative = used * 100 / (free + used)
quota_relative = user_data['ocs']['data']['quota']['relative']
quota_total = user_data['ocs']['data']['quota']['total']
quota_used = user_data['ocs']['data']['quota']['used']
print(f"{userid};{displayname};{lastlogin};{quota_free};{quota_quota};{quota_relative};{quota_total};{quota_used}")
def main():
getOptions()
if DEBUG:
showOptions()
if (opt_hostname == ""):
sys.stderr.write(f"No hostname given.\n")
showUsage()
sys.exit(1)
if (opt_no_cert_check):
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
verify = False
else:
verify = True
if (opt_port == ""):
if (opt_no_https):
protocol = "http"
port = "80"
else:
protocol = "https"
port = "443"
else:
if (opt_no_https):
protocol = "http"
else:
protocol = "https"
port = opt_port
nc_url = createUrl(nc_api_endpoint, opt_hostname, protocol, port, opt_folder)
nc_data = getData(nc_url, verify)
doCmkOutput(nc_data)
nc_url = createUrl(nc_api_endpoint_all_users, opt_hostname, protocol, port, opt_folder)
nc_data = getDataAllUsers(nc_url, verify)
doCmkOutputAllUsers(nc_data, verify, opt_hostname, protocol, port, opt_folder)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,16 @@
title: Nextcloud: Database information
agents: linux
catalog: unsorted
license: GPL
distribution: check_mk
description:
Works with Nextcloud version 25.0.3 (use at your own risk with lower versions).
Tested only with mysql/mariab as underlying database.
You may use a username/password or username/token combination to get access to the Nextcloud API.
You can create this token within the personal settings of an administrative user in Nextcloud.
Got to security settings and create a new app password, use this for the token.
The user must not be secured with 2FA.
Shows several information about a Nextcloud database (type/version/size).
The check will raise WARN/CRIT if Database OP cache hit rate is below the configurable levels.
inventory:
one service is created (with several details)

View File

@ -0,0 +1,18 @@
title: Nextcloud: Various information
agents: linux
catalog: unsorted
license: GPL
distribution: check_mk
description:
Works with Nextcloud version 25.0.3 (use at your own risk with lower versions).
Tested only with mysql/mariab as underlying database.
You may use a username/password or username/token combination to get access to the Nextcloud API.
You can create this token within the personal settings of an administrative user in Nextcloud.
Got to security settings and create a new app password, use this for the token.
The user must not be secured with 2FA.
Shows several information about a Nextcloud instance (e.g. number of files/storages/users.
The check will raise CRIT if the Nextcloud instance is not in "ok" state.
The check will raise WARN/CRIT if Database OP cache hit rate is below the configurable levels.
The check will raise WARN/CRIT if the number of installed apps with available updates is above the configurable levels.
inventory:
one service is created (with several details)

View File

@ -0,0 +1,19 @@
title: Nextcloud: Quota and Storage Usage of Users
agents: linux
catalog: unsorted
license: GPL
distribution: check_mk
description:
Works with Nextcloud version 25.0.3 (use at your own risk with lower versions).
You may use a username/password or username/token combination to get access to the Nextcloud API.
You can create this token within the personal settings of an administrative user in Nextcloud.
Got to security settings and create a new app password, use this for the token.
The user must not be secured with 2FA.
Shows the usage of storage quota used by each user in percent of the maximum allowed quota.
Shows the remaining free space for each user based on his/her max quota and used space.
The check will raise WARN/CRIT if quota usage is above the configurable levels.
The check will raise WARN/CRIT if free space is below the configurable levels.
item:
userid
inventory:
one service is created for each user

View File

@ -0,0 +1,14 @@
def agent_nextcloud_arguments(params, hostname, ipaddress):
return [
"--hostname", params["hostname"],
"--username", params["username"],
"--password", params["password"],
"--token", params["token"],
"--port", params["port"],
"--folder", params["folder"],
"--no-https", params["no_https"],
"--no-cert-check", params["no_cert_check"],
ipaddress,
]
special_agent_info['nextcloud'] = agent_nextcloud_arguments

View File

@ -0,0 +1,129 @@
#!/usr/bin/env python3
from cmk.gui.i18n import _
from cmk.gui.plugins.metrics import (
metric_info,
graph_info,
)
metric_info["nc_num_users"] = {
"title": _("Number of Users"),
"unit": "count",
"color": "44/a",
}
metric_info["nc_num_shares"] = {
"title": _("Number of Shares"),
"unit": "count",
"color": "44/b",
}
metric_info["nc_num_storages"] = {
"title": _("Number of Storages"),
"unit": "count",
"color": "42/a",
}
metric_info["nc_num_storages_home"] = {
"title": _("Number of Home Storages"),
"unit": "count",
"color": "44/a",
}
metric_info["nc_num_storages_local"] = {
"title": _("Number of Local Storages"),
"unit": "count",
"color": "44/b",
}
metric_info["nc_num_storages_other"] = {
"title": _("Number of Other Storages"),
"unit": "count",
"color": "42/a",
}
metric_info["nc_num_files"] = {
"title": _("Number of Files"),
"unit": "count",
"color": "42/a",
}
metric_info["nc_num_apps_installed"] = {
"title": _("Number of installed Apps"),
"unit": "count",
"color": "43/a",
}
metric_info["nc_apps_with_updates_available"] = {
"title": _("Number of installed Apps with Updates Available"),
"unit": "count",
"color": "24/a",
}
metric_info["nc_active_users_last_5min"] = {
"title": _("Number of Active Users in the last 5 minutes"),
"unit": "count",
"color": "24/a",
}
metric_info["nc_active_users_last_1hour"] = {
"title": _("Number of Active Users in the last 1 hour"),
"unit": "count",
"color": "41/a",
}
metric_info["nc_active_users_last_1day"] = {
"title": _("Number of Active Users in the last 1 day"),
"unit": "count",
"color": "42/a",
}
metric_info["nc_users_free_space"] = {
"title": _("Free Space"),
"unit": "bytes",
"color": "22/a",
}
metric_info["nc_database_size"] = {
"title": _("Database Size"),
"unit": "bytes",
"color": "24/a",
}
metric_info["nc_database_opcache_hit_rate"] = {
"title": _("Database OP Cache Hit Rate"),
"unit": "%",
"color": "24/a",
}
metric_info["nc_users_quota_used"] = {
"title": _("Quota used"),
"unit": "%",
"color": "16/a",
}
graph_info["number_of_users_shares_storages_combined"] = {
"title": _("Number of Users, Shares and Storages"),
"metrics": [
("nc_num_users", "area"),
("nc_num_shares", "stack"),
("nc_num_storages", "stack"),
],
}
graph_info["number_of_storage_types_combined"] = {
"title": _("Number of Storage Types"),
"metrics": [
("nc_num_storages_home", "area"),
("nc_num_storages_local", "stack"),
("nc_num_storages_other", "stack"),
],
}
graph_info["number_of_active_users_combined"] = {
"title": _("Number of Active Users"),
"metrics": [
("nc_active_users_last_5min", "area"),
("nc_active_users_last_1hour", "stack"),
("nc_active_users_last_1day", "stack"),
],
}

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python3
from cmk.gui.plugins.metrics import perfometer_info
perfometer_info.append({
"type": "stacked",
"perfometers": [
{
"type": "linear",
"segments": ["nc_database_opcache_hit_rate"],
"total": 100.0,
},
],
})
perfometer_info.append({
"type": "stacked",
"perfometers": [
{
"type": "linear",
"segments": ["nc_database_size"],
},
],
})
perfometer_info.append({
"type": "stacked",
"perfometers": [
{
"type": "linear",
"segments": ["nc_users_quota_used"],
"total": 100.0,
},
],
})

View File

@ -0,0 +1,43 @@
from cmk.gui.i18n import _
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithoutItem,
rulespec_registry,
RulespecGroupCheckParametersApplications
)
from cmk.gui.valuespec import (
Dictionary,
ListChoice,
Tuple,
Percentage,
Integer,
Float,
)
def _parameter_spec_nextcloud_database():
return Dictionary(
elements=[
("levels_database_opcache_hit_rate", Tuple(
title=_("Nextcloud levels for database opcache hit rate"),
elements=[
Percentage(
title=_("Warning below"),
default_value=99.7,
),
Percentage(
title=_("Critical below"),
default_value=99.1,
)
],
)),
],
)
rulespec_registry.register(
CheckParameterRulespecWithoutItem(
check_group_name="nextcloud_database",
group=RulespecGroupCheckParametersApplications,
match_type="dict",
parameter_valuespec=_parameter_spec_nextcloud_database,
title=lambda: _("Nextcloud Database"),
)
)

View File

@ -0,0 +1,43 @@
from cmk.gui.i18n import _
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithoutItem,
rulespec_registry,
RulespecGroupCheckParametersApplications
)
from cmk.gui.valuespec import (
Dictionary,
ListChoice,
Tuple,
Percentage,
Integer,
Float,
)
def _parameter_spec_nextcloud_info():
return Dictionary(
elements=[
("levels_apps_with_updates_available", Tuple(
title=_("Nextcloud number of installed apps with updates available"),
elements=[
Integer(
title=_("Warning at"),
default_value=1,
),
Integer(
title=_("Critical at"),
default_value=2,
)
],
)),
],
)
rulespec_registry.register(
CheckParameterRulespecWithoutItem(
check_group_name="nextcloud_info",
group=RulespecGroupCheckParametersApplications,
match_type="dict",
parameter_valuespec=_parameter_spec_nextcloud_info,
title=lambda: _("Nextcloud Info"),
)
)

View File

@ -0,0 +1,59 @@
from cmk.gui.i18n import _
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithItem,
rulespec_registry,
RulespecGroupCheckParametersOperatingSystem,
)
from cmk.gui.valuespec import (
Dictionary,
ListChoice,
Checkbox,
TextAscii,
Password,
)
from cmk.gui.plugins.wato import (
HostRulespec,
)
from cmk.gui.plugins.wato.datasource_programs import RulespecGroupDatasourceProgramsCustom
import cmk.gui.watolib as watolib
def _valuespec_special_agent_nextcloud():
return Dictionary(
title=_("Nextcloud Server Information"),
help = _("Checking Nextcloud servers via API"),
elements=[
("hostname", TextAscii(title=_("Hostname"),
allow_empty=False,
help=_("Hostname of Nextcloud server (bare FQDN or IP, IP not tested), mandatory"))),
("username", TextAscii(title=_("Username"),
allow_empty=False,
help=_("Username with administrative rights, mandatory"))),
("password", Password(title=_("Password"),
allow_empty=True,
help=_("Specify password OR token, not both, token recommended"))),
("token", Password(title=_("Token"),
allow_empty=True,
help=_("Specify password OR token, not both, token recommended"))),
("port", TextAscii(title=_("Port"),
allow_empty=True,
help=_("Specify port if not listening to HTTPS, optional"))),
("folder", TextAscii(title=_("Folder"),
allow_empty=True,
help=_("Specify subfolder if your Nextcloud instance is not installed in the web root, no trailing/leading slashes, optional"))),
("no_https", Checkbox(title=_("Disable HTTPS"),
help=_("Activate to disable encryption (not recommended), optional"))),
("no_cert_check", Checkbox(title=_("Disable certificate validation"),
help=_("Activate to disable certificate validation (not recommended), optional"))),
],
optional_keys=[],
)
rulespec_registry.register(
HostRulespec(
factory_default=watolib.Rulespec.FACTORY_DEFAULT_UNUSED,
group=RulespecGroupDatasourceProgramsCustom,
name="special_agents:nextcloud",
valuespec=_valuespec_special_agent_nextcloud,
)
)

View File

@ -0,0 +1,66 @@
from cmk.gui.i18n import _
from cmk.gui.plugins.wato import (
CheckParameterRulespecWithItem,
rulespec_registry,
RulespecGroupCheckParametersApplications
)
from cmk.gui.valuespec import (
Dictionary,
ListChoice,
Tuple,
Percentage,
Integer,
Float,
)
def _item_spec_nextcloud_users():
return TextAscii(
title=_("User ID")
)
def _parameter_spec_nextcloud_users():
return Dictionary(
elements=[
("levels_users_quota_used", Tuple(
title=_("Nextcloud levels for quota usage of users"),
elements=[
Percentage(
title=_("Warning at"),
default_value=65.0,
unit="%",
),
Percentage(
title=_("Critical at"),
default_value=85.0,
unit="%",
)
],
)),
("levels_users_free_space", Tuple(
title=_("Nextcloud levels for free disk space of users"),
elements=[
Float(
title=_("Warning below"),
default_value=256.0,
unit="MBytes",
),
Float(
title=_("Critical below"),
default_value=128.0,
unit="MBytes",
)
],
)),
],
)
rulespec_registry.register(
CheckParameterRulespecWithItem(
check_group_name="nextcloud_users",
group=RulespecGroupCheckParametersApplications,
match_type="dict",
item_spec=_item_spec_nextcloud_users,
parameter_valuespec=_parameter_spec_nextcloud_users,
title=lambda: _("Nextcloud Users"),
)
)