MKP 2.4.0, added password store for app password, some changes for compatibility with NC 28
This commit is contained in:
parent
1fbeae93a1
commit
714990bffb
2
.gitignore
vendored
2
.gitignore
vendored
@ -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*
|
||||||
|
@ -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|
|
||||||
|
@ -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,15 +114,20 @@ 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":
|
||||||
num_apps_installed = section[key]["installed"]
|
# Workaround for Nextcloud 28, "apps" info is not always available
|
||||||
num_apps_with_updates_available = section[key]["with_updates_available"]
|
try:
|
||||||
# create graphs for number of apps
|
num_apps_installed = section[key]["installed"]
|
||||||
levels = params["levels_apps_with_updates_available"]
|
num_apps_with_updates_available = section[key]["with_updates_available"]
|
||||||
yield Metric("nc_num_apps_installed", num_apps_installed)
|
# create graphs for number of apps
|
||||||
yield Metric("nc_apps_with_updates_available", num_apps_with_updates_available, levels=levels)
|
levels = params["levels_apps_with_updates_available"]
|
||||||
state = getStateUpper(levels, num_apps_with_updates_available)
|
yield Metric("nc_num_apps_installed", num_apps_installed)
|
||||||
notice = f"Number of installed apps: {num_apps_installed}\nNumber of apps with updates available: {num_apps_with_updates_available}"
|
yield Metric("nc_apps_with_updates_available", num_apps_with_updates_available, levels=levels)
|
||||||
yield(Result(state=state, notice=notice))
|
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))
|
||||||
|
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",
|
||||||
|
@ -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']}")
|
||||||
print(f"NC_Num_Apps_Installed;{data['ocs']['data']['nextcloud']['system']['apps']['num_installed']}")
|
# Workaround for Nextcloud 28.0.1 (KeyError "apps")
|
||||||
print(f"NC_Num_Apps_Updates_Available;{data['ocs']['data']['nextcloud']['system']['apps']['num_updates_available']}")
|
try:
|
||||||
|
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']}")
|
||||||
|
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()
|
@ -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"],
|
||||||
|
@ -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
BIN
mkp/Nextcloud-2.4.0.mkp
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user