Initial Commit v2.2.0
This commit is contained in:
parent
bc5a12babd
commit
b0d808ae60
@ -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",
|
||||
)
|
147
local/lib/python3/cmk/base/plugins/agent_based/nextcloud_info.py
Normal file
147
local/lib/python3/cmk/base/plugins/agent_based/nextcloud_info.py
Normal 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",
|
||||
)
|
@ -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",
|
||||
)
|
273
local/share/check_mk/agents/special/agent_nextcloud
Executable file
273
local/share/check_mk/agents/special/agent_nextcloud
Executable 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()
|
16
local/share/check_mk/checkman/nextcloud_database
Normal file
16
local/share/check_mk/checkman/nextcloud_database
Normal 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)
|
18
local/share/check_mk/checkman/nextcloud_info
Normal file
18
local/share/check_mk/checkman/nextcloud_info
Normal 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)
|
19
local/share/check_mk/checkman/nextcloud_users
Normal file
19
local/share/check_mk/checkman/nextcloud_users
Normal 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
|
14
local/share/check_mk/checks/agent_nextcloud
Normal file
14
local/share/check_mk/checks/agent_nextcloud
Normal 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
|
129
local/share/check_mk/web/plugins/metrics/nextcloud_metrics.py
Normal file
129
local/share/check_mk/web/plugins/metrics/nextcloud_metrics.py
Normal 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"),
|
||||
],
|
||||
}
|
@ -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,
|
||||
},
|
||||
],
|
||||
})
|
@ -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"),
|
||||
)
|
||||
)
|
@ -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"),
|
||||
)
|
||||
)
|
59
local/share/check_mk/web/plugins/wato/nextcloud_params.py
Normal file
59
local/share/check_mk/web/plugins/wato/nextcloud_params.py
Normal 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,
|
||||
)
|
||||
)
|
@ -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"),
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue
Block a user