aboutsummaryrefslogtreecommitdiff
path: root/plugins/check_nextcloud
blob: 7e638c091f81b9fc2a531a26f32379d82be717ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python3

import requests
import argparse

status = {'OK': 0, 'WARNING': 1, 'CRITICAL': 2, 'UNKNOWN': 3}

class Check:
    def __init__(self, status: str, description: str, data: tuple[str,str,str] | None):
        self.status = status
        self.description = description
        self.data = data

    def format(self) -> str:
        if self.data != None:
            return f"{self.status} - {self.description} | {';'.join(self.data)}"
        else:
            return f"{self.status} - {self.description}"
    def exit(self):
        print(self.format())
        exit(status[self.status])

parser = argparse.ArgumentParser(description='Check nextcloud status via api')
parser.add_argument('-u', dest='max_conns', action='store', type=int, default=None, nargs=2)
parser.add_argument('-c', dest='opcache', action='store', type=float, default=None, nargs=2)
parser.add_argument('-a', dest='updates', action='store_true', help='check for app updates')
args=parser.parse_args()

def check_interned_strings_cache(data_json, warning: float, critical: float) -> Check:
    data_opcache = data_json['ocs']['data']['server']['php']['opcache']
    cache_max = data_opcache['interned_strings_usage']['buffer_size']
    cache_used = data_opcache['interned_strings_usage']['used_memory'] / cache_max
    data = map('{:.2f}'.format, (cache_used, warning, critical))
    if cache_used >= critical:
        return Check('CRITICAL',"The OPcache interned strings buffer is full.", data)
    if cache_used >= warning:
        return Check('WARNING', f"OPcache interned strings buffer is to {cache_used:.0%} filled. " +
            f"This should not be more than {warning:.0%}!", data)
    return Check('OK', f"OPcache interned strings buffer is to {cache_used:.0%} filled.", data)

def check_activer_users(data_json, warning: int, critical: int) -> Check:
    active_users = data_json['ocs']['data']['activeUsers']['last5minutes']
    if active_users >= critical:
        status = 'CRITICAL'
    elif active_users >= warning:
        status = 'WARNING'
    else:
        status = 'OK'
    return Check( status, f'{active_users} {"users were" if active_users != 1 else "user was"} active in the last 5 minutes.'
                , map(str, (active_users,warning,critical)))

def check_app_updates(data_json) -> Check:
    updates = data_json['ocs']['data']['nextcloud']['system']['apps']['app_updates']
    if updates != []:
        return Check('WARNING', f'The following apps can be updates: {" ".join(updates)}.', None)
    else:
        return Check('OK', 'No app updates were found.', None)

try:
    data_json = requests.get('https://nextcloud.my.cum.re/ocs/v2.php/apps/serverinfo/api/v1/info?format=json'
                             , headers={'NC-Token': ''}).json() #TODO Savely store secret
    if data_json['ocs']['meta']['status'] == 'failure':
        raise Exception('API call failed!')
    if args.updates:
        check_app_updates(data_json).exit()
    if args.max_conns != None:
        warning, critical = args.max_conns
        check_activer_users(data_json, warning, critical).exit()
    if args.opcache != None:
        warning, critical = args.opcache
        check_interned_strings_cache(data_json, warning, critical).exit()
except Exception as ex:
    #TODO Define own execption, we dont want to leak data!
    Check('UNKNOWN', f'A python runtime execption occured: {ex}', None).exit()