Initial commit
This commit is contained in:
280
local/share/check_mk/agents/special/agent_hal9001
Normal file
280
local/share/check_mk/agents/special/agent_hal9001
Normal file
@@ -0,0 +1,280 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import getopt
|
||||
import sys
|
||||
import random
|
||||
import os
|
||||
|
||||
"""
|
||||
Sample output
|
||||
|
||||
<<<hal9001_status:sep(59)>>>
|
||||
ok;SK-1st-Edition 1965-12-17;arthur;127.0.0.1
|
||||
|
||||
1. Status, possible values: ok, update available, storage down (String)
|
||||
2. Version (String)
|
||||
3. Username used for login (String)
|
||||
4. IP used for access (String)
|
||||
|
||||
<<<hal9001_users:sep(59)>>>
|
||||
user1;David Bowman;65536.0;262144.0
|
||||
user2;Frank Poole;16384.0;131072.0
|
||||
user3;Elena;32768.0;65536.0
|
||||
|
||||
1. User ID (string)
|
||||
2. User Real Name (string)
|
||||
3. Quota Used (float in bytes, absolut)
|
||||
4. Quota Max (float in bytes, absolut)
|
||||
|
||||
<<<hal9001_storages:sep(59)>>>
|
||||
storage1;DATA_Dullea;8192.0;262144.0
|
||||
storage2;DATA_Poole;2048.0;131072.0
|
||||
|
||||
1. Storage ID (string)
|
||||
2. Storage Custom Name (string)
|
||||
3. Upload (float in bytes, counter)
|
||||
4. Download (float in bytes, counter)
|
||||
"""
|
||||
|
||||
def showUsage():
|
||||
sys.stderr.write("""HAL9001 Special Agent
|
||||
USAGE: agent_hal9001 -H [hostname] -u [username] -p [password]
|
||||
agent_hal9001 -h
|
||||
OPTIONS:
|
||||
-H, --hostname Hostname (FQDN or IP) of HAL System
|
||||
-u, --username Username
|
||||
-p, --password Password
|
||||
-h, --help Show this help message and exit
|
||||
""")
|
||||
|
||||
# Parameters coming from CheckMK
|
||||
opt_hostname = ""
|
||||
opt_username = ""
|
||||
opt_password = ""
|
||||
|
||||
# Base values for randomly calculating the use of the storage system per user
|
||||
base_usage = float(65536 * 8) # 0.5 MByte
|
||||
max_quota = 1073741824.0 # 1 GByte
|
||||
|
||||
# these dicts are used as starting points, fell free to extend and/or adjust them
|
||||
# each user/storage results in an additional service
|
||||
users_dict = {
|
||||
"user1": {
|
||||
"realname": "David Bowman",
|
||||
"usage": base_usage*2,
|
||||
"quota_max": max_quota
|
||||
},
|
||||
"user2": {
|
||||
"realname": "Frank Poole",
|
||||
"usage": base_usage*3,
|
||||
"quota_max": max_quota/2
|
||||
},
|
||||
"user3": {
|
||||
"realname": "Elena",
|
||||
"usage": base_usage*4,
|
||||
"quota_max": max_quota*2
|
||||
}
|
||||
}
|
||||
|
||||
storages_dict = {
|
||||
"storage1": {
|
||||
"realname": "DATA_Dullea",
|
||||
"download": float(1024**3),
|
||||
"upload": float((1024**2) * 6)
|
||||
},
|
||||
"storage2": {
|
||||
"realname": "DATA_Poole",
|
||||
"download": float(1024**3),
|
||||
"upload": float((1024**2) * 4)
|
||||
}
|
||||
}
|
||||
|
||||
hal_status_list = ["ok", "update available", "storage down"]
|
||||
hal_version = "SK-1st-Edition 1965-12-17"
|
||||
|
||||
short_options = 'hH:u:p:'
|
||||
long_options = [
|
||||
'hostname=', 'username=', 'password=', 'help'
|
||||
]
|
||||
|
||||
def getOptions():
|
||||
global opt_hostname
|
||||
global opt_username
|
||||
global opt_password
|
||||
|
||||
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 ['-h', '--help']:
|
||||
showUsage()
|
||||
sys.exit(0)
|
||||
|
||||
def showOptions():
|
||||
print(f"Hostname: {opt_hostname}")
|
||||
print(f"Username: {opt_username}")
|
||||
print(f"Password: {opt_password}")
|
||||
|
||||
def calculateNewUserStorage(current_storage):
|
||||
# let the chance that no change occured be at 90%
|
||||
no_change = random.randint(1, 100)
|
||||
if no_change > 10:
|
||||
return float(current_storage)
|
||||
else:
|
||||
# create some variance, value of "amount" is interpreted in bytes
|
||||
factor = random.randint(1,4)
|
||||
amount = random.randint(1024000, 4096000)
|
||||
amount *= factor
|
||||
# increase or decrease, give increase a better chance (60:40), that's more real :-)
|
||||
plus_or_minus = random.randint(1,100)
|
||||
if plus_or_minus > 40:
|
||||
new_storage = current_storage + amount
|
||||
else:
|
||||
new_storage = current_storage - amount
|
||||
# avoid negative values
|
||||
if new_storage < 0:
|
||||
new_storage = 1024000
|
||||
return float(new_storage)
|
||||
|
||||
def calculateNewStorageCounters(ul_bytes, dl_bytes):
|
||||
# let the chance that no change occured be at 2%
|
||||
no_change = random.randint(1, 100)
|
||||
if no_change > 98:
|
||||
return float(ul_bytes), float(dl_bytes)
|
||||
else:
|
||||
# create some variance, values of "amount_<ul|dl>" is interpreted in bytes
|
||||
factor_ul = random.randint(1,7)
|
||||
amount_ul = random.randint(20240000, 50960000)
|
||||
amount_ul *= factor_ul
|
||||
factor_dl = random.randint(1,14)
|
||||
amount_dl = random.randint(30240000, 60960000)
|
||||
amount_dl *= factor_dl
|
||||
# we are simulating counters, so only increasing makes sense
|
||||
new_ul_bytes = ul_bytes + amount_ul
|
||||
new_dl_bytes = dl_bytes + amount_dl
|
||||
return float(new_ul_bytes), float(new_dl_bytes)
|
||||
|
||||
def doCmkHalStatusOutput(status, version, username, ipaddress):
|
||||
print("<<<hal9001_status:sep(59)>>>")
|
||||
print(f"{status};{version};{username};{ipaddress}")
|
||||
|
||||
def doCmkHalUsersOutput(users, hostname):
|
||||
print("<<<hal9001_users:sep(59)>>>")
|
||||
home_path = os.getenv("HOME")
|
||||
tmp_path = f"{home_path}/tmp"
|
||||
for user in users:
|
||||
# we need a way to store the current value for storage usage between runs of the agent
|
||||
help_file = f"{tmp_path}/hal9001_{hostname}_{user}_current_storage.txt"
|
||||
if os.path.exists(help_file):
|
||||
# help file exists, so get the content
|
||||
with open(help_file, "r") as file:
|
||||
current_storage = float(file.read())
|
||||
else:
|
||||
# help file does not exist, create it and store the start value in it
|
||||
with open(help_file, "w") as file:
|
||||
file.write(str(users[user]["usage"]))
|
||||
current_storage = users[user]["usage"]
|
||||
realname = users[user]["realname"]
|
||||
quota_max = users[user]["quota_max"]
|
||||
# simulate changes in storage usage
|
||||
new_storage = calculateNewUserStorage(current_storage)
|
||||
# save the new value in help file
|
||||
with open(help_file, "w") as file:
|
||||
file.write(str(new_storage))
|
||||
# create output
|
||||
print(f"{user};{realname};{new_storage};{quota_max}")
|
||||
|
||||
def doCmkHalStoragesOutput(storages, hostname):
|
||||
print("<<<hal9001_storages:sep(59)>>>")
|
||||
home_path = os.getenv("HOME")
|
||||
tmp_path = f"{home_path}/tmp"
|
||||
for storage in storages:
|
||||
# we need a way to store the current values for storage usage between runs of the agent
|
||||
# so we can simulate counters for uploaded/downloaded bytes
|
||||
help_file_ul = f"{tmp_path}/hal9001_{hostname}_{storage}_ul_bytes.txt"
|
||||
help_file_dl = f"{tmp_path}/hal9001_{hostname}_{storage}_dl_bytes.txt"
|
||||
if os.path.exists(help_file_ul):
|
||||
# help file exists, so get the content
|
||||
with open(help_file_ul, "r") as file:
|
||||
current_ul_bytes = float(file.read())
|
||||
else:
|
||||
# help file does not exist, create it and store the start value in it
|
||||
with open(help_file_ul, "w") as file:
|
||||
file.write(str(storages[storage]["upload"]))
|
||||
current_ul_bytes = storages[storage]["upload"]
|
||||
if os.path.exists(help_file_dl):
|
||||
# help file exists, so get the content
|
||||
with open(help_file_dl, "r") as file:
|
||||
current_dl_bytes = float(file.read())
|
||||
else:
|
||||
# help file does not exist, create it and store the start value in it
|
||||
with open(help_file_dl, "w") as file:
|
||||
file.write(str(storages[storage]["download"]))
|
||||
current_dl_bytes = storages[storage]["download"]
|
||||
realname = storages[storage]["realname"]
|
||||
# simulate changes in storage usage
|
||||
new_ul_bytes, new_dl_bytes = calculateNewStorageCounters(current_ul_bytes, current_dl_bytes)
|
||||
# save the new values in help files
|
||||
with open(help_file_ul, "w") as file:
|
||||
file.write(str(new_ul_bytes))
|
||||
with open(help_file_dl, "w") as file:
|
||||
file.write(str(new_dl_bytes))
|
||||
# create output
|
||||
print(f"{storage};{realname};{new_ul_bytes};{new_dl_bytes}")
|
||||
|
||||
def getStatus():
|
||||
# randomly set one of the three available states
|
||||
status_index = random.randint(1,100)
|
||||
if status_index <= 5:
|
||||
# should result in critical state
|
||||
hal_status = hal_status_list[2]
|
||||
elif status_index <= 15:
|
||||
# should result in warning state
|
||||
hal_status = hal_status_list[1]
|
||||
else:
|
||||
# should result in ok state
|
||||
hal_status = hal_status_list[0]
|
||||
return hal_status, hal_version
|
||||
|
||||
def doLogin(hostname, username, password):
|
||||
# simulate the login to our HAL system
|
||||
# give it a chance of 2% to fail to demonstrate an error from time to time
|
||||
success = random.randint(1, 100)
|
||||
if success > 2:
|
||||
return True, 200
|
||||
else:
|
||||
return False, 404
|
||||
|
||||
def main():
|
||||
getOptions()
|
||||
#showOptions()
|
||||
# some checks
|
||||
# keep in mind: the 1st line printed out to std.err will be shown as check result in CheckMK
|
||||
if (opt_hostname == ""):
|
||||
sys.stderr.write(f"No hostname given.\n")
|
||||
showUsage()
|
||||
sys.exit(1)
|
||||
if (opt_username == ""):
|
||||
sys.stderr.write(f"No username given.\n")
|
||||
showUsage()
|
||||
sys.exit(1)
|
||||
if (opt_password == ""):
|
||||
sys.stderr.write(f"No password given.\n")
|
||||
showUsage()
|
||||
sys.exit(1)
|
||||
success, code = doLogin(opt_hostname, opt_username, opt_password)
|
||||
if success:
|
||||
status, version = getStatus()
|
||||
doCmkHalStatusOutput(status, version, opt_username, opt_hostname)
|
||||
doCmkHalUsersOutput(users_dict, opt_hostname)
|
||||
doCmkHalStoragesOutput(storages_dict, opt_hostname)
|
||||
else:
|
||||
sys.stderr.write(f"Login to {opt_hostname} with user {opt_username} failed with error code {code}\n")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user