Hey guys.
I created a script using the rest API documentation and with some ideas out of this community. It is planned to be used to add labels to existing hosts using the “update_attribute” option which indicates it just updates the value. That made me believe i can add more labels to an existing host with this while keeping the existing labels.
The actual results of my script (which has a following discovery and activating changes section) proved me wrong, because my labels get overwritten.
Is it either possible to make checkmk really add those labels to the existing ones or to get a list of the existing labels for that host and autofill them into the json payload?
Thank you for your trouble and have a nice day!
Following code includes argument parsing, getting etag for host, insert changes, service discovery and activate changes processes
#!/usr/bin/env python3
import pprint
import os
import sys
import getopt
import requests
import json
import argparse
import urllib.request
import time
#Initializing variables
HOST_NAME = "hostname"
SITE_NAME = "sitename"
API_URL = f"http://{HOST_NAME}/{SITE_NAME}/check_mk/api/1.0"
USERNAME = "username"
PASSWORD = "password"
#Parsing arguments (key and value separated because json payload does not accept them combined)
parser = argparse.ArgumentParser(allow_abbrev=False)
parser.add_argument('-n', '--name', required=True, help='helptext')
parser.add_argument('-k', '--key', required=True, help='helptext')
parser.add_argument('-v', '--value', required=True, help='helptext')
args = parser.parse_args()
session = requests.session()
session.headers['Authorization'] = f"Bearer {USERNAME} {PASSWORD}"
session.headers['Accept'] = 'application/json'
#Requesting #ETAG (checksum) to ensure noone modified in between
query_string = urllib.parse.urlencode({})
HOSTNAME=args.name
request = urllib.request.Request(
f"{API_URL}/objects/host_config/{HOSTNAME}?{query_string}",
method="GET",
headers={
"Authorization": f"Bearer {USERNAME} {PASSWORD}",
"Accept": "application/json",
},
)
resp = urllib.request.urlopen(request)
if resp.status == 200:
etag = str(resp.headers["ETag"])
#Print for Testing purposes
# print("ETag fetched from "+args.name+": "+etag)
elif resp.status == 204:
print("Done")
else:
raise RuntimeError(resp.read())
#Adding Label to specified Host
print("Adding Label "+args.key+":"+args.value+" to "+args.name+" ...")
resp = session.put(
f"{API_URL}/objects/host_config/"+args.name,
headers={
"If-Match": etag, # (required) The value of the, to be modified, object's ETag header.
"Content-Type": 'application/json', # (required) A header specifying which type of content is in the request/response body.
},
json={
'update_attributes': {
'labels':{
args.key:args.value
}
},
},
)
if resp.status_code == 200:
print("Done")
elif resp.status_code == 204:
print("Done")
else:
raise RuntimeError(pprint.pformat(resp.json()))
#A little time-window to make sure service discovery is not conflicting with last step
time.sleep(5)
#Discovering and accepting previously made changes in Check-MK
try:
resp = session.post(
f"{API_URL}/domain-types/discovery_run/actions/bulk-discovery-start/invoke",
headers={
"Content-Type": 'application/json', # (required) A header specifying which type of content is in the request/response body.
},
json={
'hostnames': [args.name],
'mode': 'new',
'do_full_scan': True,
'bulk_size': 1,
'ignore_errors': True
},
)
if resp.status_code == 200:
print("Service discovery ... started (might take a moment)")
print("Service Discovery ...", end = " ")
elif resp.status_code == 204:
print("Service discovery ... done")
else:
raise RuntimeError(pprint.pformat(resp.json()))
#A little time-window to make sure service discovery is finished before attempting to move on
time.sleep(10)
print("done")
#Activation process starting after Discovery
resp = session.post(
f"{API_URL}/domain-types/activation_run/actions/activate-changes/invoke",
headers={
"Content-Type": 'application/json',
},
json={
'redirect': False,
'sites': [],
'force_foreign_changes': False
},
allow_redirects=True,
)
if resp.status_code == 200:
print("Activating changes ... done")
elif resp.status_code == 204:
print("Activating changes ... done")
else:
raise RuntimeError(pprint.pformat(resp.json()))
except:
print(args.name + " could not finish service discovery and/or activate changes process")