Skip to content

Commit

Permalink
Do not update the host/service livestate for a received check result …
Browse files Browse the repository at this point in the history
…older than the last known check result

Do not set realm as required for a logcheckresult ... realm is auto-set according to the concerned host realm
  • Loading branch information
mohierf committed Dec 1, 2017
1 parent 8564884 commit 8cba642
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 69 deletions.
143 changes: 77 additions & 66 deletions alignak_backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ def pre_logcheckresult_post(items):
else:
host = hosts_drv.find_one({'_id': item['host']})
item['host_name'] = host['name']
item_last_check = host['ls_last_check']

if not item.get('service') and not item.get('service_name'):
# This is valid for an host check result
Expand All @@ -488,10 +489,19 @@ def pre_logcheckresult_post(items):
if item.get('service') and not item.get('service_name'):
service = services_drv.find_one({'_id': item['service']})
item['service_name'] = service['name']
item_last_check = service['ls_last_check']

# Set _realm as host's _realm
item['_realm'] = host['_realm']

g.updateLivestate = True
# If the log check result is older than the item last check, do not update the livestate
if item_last_check and item['last_check'] < item_last_check:
if 'ALIGNAK_BACKEND_PRINT' in os.environ:
print("LCR - will not update the livestate: %s / %s" % (item['last_check'],
item_last_check))
g.updateLivestate = False

if 'ALIGNAK_BACKEND_PRINT' in os.environ:
print("LCR - inserting an LCR for %s/%s..." % (item['host_name'], item['service_name']))

Expand All @@ -508,73 +518,74 @@ def after_insert_logcheckresult(items):
if 'ALIGNAK_BACKEND_PRINT' in os.environ:
print("LCR - inserted an LCR for %s/%s..." % (item['host_name'], item['service_name']))
print(" -> %s..." % item)
# # Update the livestate...
if item['service']:
# ...for a service
lookup = {"_id": item['service']}
data = {
'ls_state': item['state'],
'ls_state_type': item['state_type'],
'ls_state_id': item['state_id'],
'ls_acknowledged': item['acknowledged'],
'ls_acknowledgement_type': item['acknowledgement_type'],
'ls_downtimed': item['downtimed'],
'ls_last_check': item['last_check'],
'ls_last_state': item['last_state'],
'ls_last_state_type': item['last_state_type'],
'ls_output': item['output'],
'ls_long_output': item['long_output'],
'ls_perf_data': item['perf_data'],
'ls_current_attempt': item['current_attempt'],
'ls_max_attempts': item['max_attempts'],
'ls_latency': item['latency'],
'ls_execution_time': item['execution_time'],
'ls_passive_check': item['passive_check'],
'ls_state_changed': item['state_changed'],
'ls_last_state_changed': item['last_state_changed'],
'ls_last_hard_state_changed': item['last_hard_state_changed'],
'ls_last_time_ok': item['last_time_0'],
'ls_last_time_warning': item['last_time_1'],
'ls_last_time_critical': item['last_time_2'],
'ls_last_time_unknown': item['last_time_3'],
'ls_last_time_unreachable': item['last_time_4']
}
(pi_a, pi_b, pi_c, pi_d) = patch_internal('service', data, False, False, **lookup)
if 'ALIGNAK_BACKEND_PRINT' in os.environ:
print("LCR - internal patch result: %s, %s, %s, %s" % (pi_a, pi_b, pi_c, pi_d))
else:
# ...for an host
lookup = {"_id": item['host']}
data = {
'ls_state': item['state'],
'ls_state_type': item['state_type'],
'ls_state_id': item['state_id'],
'ls_acknowledged': item['acknowledged'],
'ls_acknowledgement_type': item['acknowledgement_type'],
'ls_downtimed': item['downtimed'],
'ls_last_check': item['last_check'],
'ls_last_state': item['last_state'],
'ls_last_state_type': item['last_state_type'],
'ls_output': item['output'],
'ls_long_output': item['long_output'],
'ls_perf_data': item['perf_data'],
'ls_current_attempt': item['current_attempt'],
'ls_max_attempts': item['max_attempts'],
'ls_latency': item['latency'],
'ls_execution_time': item['execution_time'],
'ls_passive_check': item['passive_check'],
'ls_state_changed': item['state_changed'],
'ls_last_state_changed': item['last_state_changed'],
'ls_last_hard_state_changed': item['last_hard_state_changed'],
'ls_last_time_up': item['last_time_0'],
'ls_last_time_down': item['last_time_1'],
# 'ls_last_time_2': item['last_time_2'],
# 'ls_last_time_3': item['last_time_3'],
'ls_last_time_unreachable': item['last_time_4']
}
(pi_a, pi_b, pi_c, pi_d) = patch_internal('host', data, False, False, **lookup)

if g.updateLivestate:
# # Update the livestate...
if item['service']:
# ...for a service
lookup = {"_id": item['service']}
data = {
'ls_state': item['state'],
'ls_state_type': item['state_type'],
'ls_state_id': item['state_id'],
'ls_acknowledged': item['acknowledged'],
'ls_acknowledgement_type': item['acknowledgement_type'],
'ls_downtimed': item['downtimed'],
'ls_last_check': item['last_check'],
'ls_last_state': item['last_state'],
'ls_last_state_type': item['last_state_type'],
'ls_output': item['output'],
'ls_long_output': item['long_output'],
'ls_perf_data': item['perf_data'],
'ls_current_attempt': item['current_attempt'],
'ls_max_attempts': item['max_attempts'],
'ls_latency': item['latency'],
'ls_execution_time': item['execution_time'],
'ls_passive_check': item['passive_check'],
'ls_state_changed': item['state_changed'],
'ls_last_state_changed': item['last_state_changed'],
'ls_last_hard_state_changed': item['last_hard_state_changed'],
'ls_last_time_ok': item['last_time_0'],
'ls_last_time_warning': item['last_time_1'],
'ls_last_time_critical': item['last_time_2'],
'ls_last_time_unknown': item['last_time_3'],
'ls_last_time_unreachable': item['last_time_4']
}
(pi_a, pi_b, pi_c, pi_d) = patch_internal('service', data, False, False, **lookup)
else:
# ...for an host
lookup = {"_id": item['host']}
data = {
'ls_state': item['state'],
'ls_state_type': item['state_type'],
'ls_state_id': item['state_id'],
'ls_acknowledged': item['acknowledged'],
'ls_acknowledgement_type': item['acknowledgement_type'],
'ls_downtimed': item['downtimed'],
'ls_last_check': item['last_check'],
'ls_last_state': item['last_state'],
'ls_last_state_type': item['last_state_type'],
'ls_output': item['output'],
'ls_long_output': item['long_output'],
'ls_perf_data': item['perf_data'],
'ls_current_attempt': item['current_attempt'],
'ls_max_attempts': item['max_attempts'],
'ls_latency': item['latency'],
'ls_execution_time': item['execution_time'],
'ls_passive_check': item['passive_check'],
'ls_state_changed': item['state_changed'],
'ls_last_state_changed': item['last_state_changed'],
'ls_last_hard_state_changed': item['last_hard_state_changed'],
'ls_last_time_up': item['last_time_0'],
'ls_last_time_down': item['last_time_1'],
# 'ls_last_time_2': item['last_time_2'],
# 'ls_last_time_3': item['last_time_3'],
'ls_last_time_unreachable': item['last_time_4']
}
(pi_a, pi_b, pi_c, pi_d) = patch_internal('host', data, False, False, **lookup)

if 'ALIGNAK_BACKEND_PRINT' in os.environ:
print("LCR - internal patch result: %s, %s, %s, %s" % (pi_a, pi_b, pi_c, pi_d))
print("LCR - updated the livestate: %s, %s, %s, %s" % (pi_a, pi_b, pi_c, pi_d))

# Create an history event for the new logcheckresult
message = "%s[%s] (%s/%s): %s" % (item['state'], item['state_type'],
Expand Down
1 change: 0 additions & 1 deletion alignak_backend/models/logcheckresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ def get_schema():
'resource': 'realm',
'embeddable': True
},
'required': True,
},
'_sub_realm': {
'schema_version': 1,
Expand Down
172 changes: 172 additions & 0 deletions test/test_logcheckresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,175 @@ def test_logcheckresult(self):
self.assertEqual(re[3]['type'], "check.result")
self.assertEqual(re[3]['message'], "OK[HARD] (False/False): Check output service 2")
self.assertEqual(re[3]['logcheckresult'], check_id)

def test_logcheckresult_past(self):
# pylint: disable=too-many-locals
"""
Test log checks results - do not update the livestate when the check result is too old
:return: None
"""
headers = {'Content-Type': 'application/json'}
sort_id = {'sort': '_id'}

# No existing logcheckresult
response = requests.get(
self.endpoint + '/logcheckresult', params=sort_id, auth=self.auth
)
resp = response.json()
re = resp['_items']
self.assertEqual(len(re), 0)

# Get hosts in the backend
response = requests.get(self.endpoint + '/host', params={'sort': 'name'}, auth=self.auth)
resp = response.json()
rh = resp['_items']
self.assertEqual(len(rh), 2)
self.assertEqual(rh[0]['name'], "_dummy")
self.assertEqual(rh[1]['name'], "srv001")

# Get service in the backend
response = requests.get(self.endpoint + '/service', params={'sort': 'name'}, auth=self.auth)
resp = response.json()
rs = resp['_items']
self.assertEqual(rs[0]['name'], "ping")

# -------------------------------------------
# Add a check result for an host
data = {
"last_check": timegm(datetime.utcnow().timetuple()),
"host": rh[0]['_id'],
"service": None,
'acknowledged': False,
'state_id': 0,
'state': 'UP',
'state_type': 'HARD',
'last_state_id': 0,
'last_state': 'UP',
'last_state_type': 'HARD',
'state_changed': False,
'latency': 0,
'execution_time': 0.12,
'output': 'Check output',
'long_output': 'Check long_output',
'perf_data': 'perf_data',
"_realm": self.realm_all
}
response = requests.post(
self.endpoint + '/logcheckresult', json=data, headers=headers, auth=self.auth
)
resp = response.json()
self.assertEqual(resp['_status'], 'OK')

# Get check results
response = requests.get(
self.endpoint + '/logcheckresult', params=sort_id, auth=self.auth
)
resp = response.json()
rl = resp['_items']
self.assertEqual(len(rl), 1)
rl = resp['_items']
check_id = rl[0]['_id']

# Host / service ids and names are correct
self.assertEqual(rl[0]['host'], rh[0]['_id'])
self.assertEqual(rl[0]['host_name'], rh[0]['name'])
self.assertEqual(rl[0]['service'], None)
self.assertEqual(rl[0]['service_name'], '')
self.assertEqual(rl[0]['output'], 'Check output')

# Get host in the backend to check that the main live state fields got updated
response = requests.get(self.endpoint + '/host/' + rh[0]['_id'],
params={'sort': 'name'}, auth=self.auth)
resp = response.json()
host = resp
self.assertEqual(host['name'], "_dummy")
# Check that all properties posted in the LCR data are found in
# the host live state corresponding property
for prop in host:
if not prop.startswith('ls_') or not prop[3:] in data:
continue
self.assertEqual(host[prop], data[prop[3:]])

# Get history
response = requests.get(self.endpoint + '/history', params=sort_id, auth=self.auth)
resp = response.json()
re = resp['_items']
self.assertEqual(len(re), 1)

# Host / service ids and names are correct
self.assertEqual(re[0]['host'], rh[0]['_id'])
self.assertEqual(re[0]['host_name'], rh[0]['name'])
self.assertEqual(re[0]['service'], None)
self.assertEqual(re[0]['service_name'], '')
self.assertEqual(re[0]['type'], "check.result")
self.assertEqual(re[0]['message'], "UP[HARD] (False/False): Check output")
self.assertEqual(re[0]['logcheckresult'], check_id)

# 2 -------------------------------------------
# Add a check result for an host with a last check older than the former one
data = {
"last_check": timegm(datetime.utcnow().timetuple()) - 10,
"host": rh[0]['_id'],
'acknowledged': False,
'state_id': 0,
'state': 'UP',
'state_type': 'HARD',
'last_state_id': 0,
'last_state': 'UP',
'last_state_type': 'HARD',
'state_changed': False,
'latency': 0,
'execution_time': 0.12,
'output': 'Check output 2',
'long_output': 'Check long_output',
'perf_data': 'perf_data',
"_realm": self.realm_all
}
response = requests.post(
self.endpoint + '/logcheckresult', json=data, headers=headers, auth=self.auth
)
resp = response.json()
self.assertEqual(resp['_status'], 'OK')

# Get check results
response = requests.get(
self.endpoint + '/logcheckresult', params=sort_id, auth=self.auth
)
resp = response.json()
rl = resp['_items']
self.assertEqual(len(rl), 2)
rl = resp['_items']
check_id = rl[1]['_id']

# Host / service ids and names are correct
self.assertEqual(rl[1]['host'], rh[0]['_id'])
self.assertEqual(rl[1]['host_name'], rh[0]['name'])
self.assertEqual(rl[1]['service'], None)
self.assertEqual(rl[1]['service_name'], '')
self.assertEqual(rl[1]['output'], 'Check output 2')

# Get host in the backend to check that the main live state fields got updated
response = requests.get(self.endpoint + '/host/' + rh[0]['_id'],
params={'sort': 'name'}, auth=self.auth)
resp = response.json()
host = resp
self.assertEqual(host['name'], "_dummy")
# Check that the host live state did not get updated!
self.assertNotEqual(host['ls_last_check'], data['last_check'])
self.assertNotEqual(host['ls_output'], data['output'])

# Get history
response = requests.get(self.endpoint + '/history', params=sort_id, auth=self.auth)
resp = response.json()
re = resp['_items']
self.assertEqual(len(re), 2)

# Host / service ids and names are correct
self.assertEqual(re[1]['host'], rh[0]['_id'])
self.assertEqual(re[1]['host_name'], rh[0]['name'])
self.assertEqual(re[1]['service'], None)
self.assertEqual(re[1]['service_name'], '')
self.assertEqual(re[1]['type'], "check.result")
self.assertEqual(re[1]['message'], "UP[HARD] (False/False): Check output 2")
self.assertEqual(re[1]['logcheckresult'], check_id)
6 changes: 4 additions & 2 deletions test/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ def test_schema_version(self):
"""
allmodels = register_models()
for model_name in allmodels:
print(model_name)
print("Model: %s" % model_name)
for field in allmodels[model_name]['schema']:
print("- field: %s" % field)
if field == 'schema_version':
assert 'schema_version' not in allmodels[model_name]['schema'][field]
else:
Expand All @@ -38,9 +39,10 @@ def test_schema_version_uptodate(self):
"""
allmodels = register_models()
for model_name in allmodels:
print(model_name)
print("Model: %s" % model_name)
highest = 0
for field in allmodels[model_name]['schema']:
print("- field: %s" % field)
if field != 'schema_version':
if allmodels[model_name]['schema'][field]['schema_version'] > highest:
highest = allmodels[model_name]['schema'][field]['schema_version']
Expand Down

0 comments on commit 8cba642

Please sign in to comment.