Merge pull request #16 from itsdave-de/feature/add-host-status-information-to-it-object

Feature/add host status information to it object
This commit is contained in:
itsdaveit 2022-07-20 10:36:52 +02:00 committed by GitHub
commit b5388517c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 258 additions and 8 deletions

View File

@ -2,7 +2,144 @@
// For license information, please see license.txt
frappe.ui.form.on('IT Object', {
refresh: function(frm) {
refresh: function (frm) {
const loader = `
<div class="line-wobble"></div>
<style>
.line-wobble {
--uib-size: 80px;
--uib-speed: 1.75s;
--uib-color: black;
--uib-line-weight: 5px;
position: relative;
margin: 0 auto;
top: 45%;
display: flex;
align-items: center;
justify-content: center;
height: var(--uib-line-weight);
width: var(--uib-size);
border-radius: calc(var(--uib-line-weight) / 2);
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.line-wobble::before {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: var(--uib-color);
opacity: 0.1;
}
.line-wobble::after {
content: '';
height: 100%;
width: 100%;
border-radius: calc(var(--uib-line-weight) / 2);
animation: wobble var(--uib-speed) ease-in-out infinite;
transform: translateX(-95%);
background-color: var(--uib-color);
}
@keyframes wobble {
0%,
100% {
transform: translateX(-95%);
}
50% {
transform: translateX(95%);
}
}
</style>
`;
const container = document.getElementById('oitc-output');
// Set width and height to <div> parent element and to <form> grandparent element so relative width and height with % works greate
container.parentElement.parentElement.style.width = '100%';
container.parentElement.parentElement.style.height = '100%';
container.parentElement.style.width = '100%';
container.parentElement.style.height = '90%';
// Set this styles to showcase where the information will appear
container.style.width = '100%';
container.style.height = '100%';
container.style.background = 'rgba(212, 204, 203, 0.4)';
container.innerHTML = loader;
frm.call('get_oitc_host_status_data', {})
.then((response) => {
const container = document.getElementById('oitc-output');
if (response.message.status !== 200) {
container.innerHTML = response.message.response || 'An error occurred while fetching OITC data';
return;
}
let background = response.message?.statusColors?.upStateColor;
if (response.message?.host?.hostStatus?.currentState?.toUpperCase() === "DOWN") {
background = response.message?.statusColors?.downStateColor;
} else if (response.message?.host?.hostStatus?.currentState?.toUpperCase() === "UNREACHABLE") {
background = response.message?.statusColors?.unreachableStateColor;
}
container.innerHTML = `
<div class="js-oitc-output">
<div>
<h1 class="font-size-50" style="color: white;">
${response.message?.host?.hostStatus?.currentState?.toUpperCase()}
</h1>
</div>
<div>
<div>Current State since</div>
<h3 style="color: white; margin: 1rem 0;">
${response.message?.host?.hostStatus?.currentStateSince}
</h3>
</div>
<div>
<div>Last check</div>
<h3 style="color: white; margin: 1rem 0;">
${response.message?.host?.hostStatus?.lastCheck}
</h3>
</div>
<div>
<div>Next check</div>
<h3 style="color: white; margin: 1rem 0;">
${response.message?.host?.hostStatus?.nextCheck}
</h3>
</div>
<div>
<div>Services</div>
<h3 style="color: white; margin: 1rem 0;">
Total Services: ${response.message?.host?.servicesStatus?.totalServices}
</h3>
<div>Services Status:</div>
<h3 style="color: white; margin: 1rem 0;">
<ul style="text-align:left;">
<li>OK: ${response.message?.host?.servicesStatus?.state?.ok}</li>
<li>CRITICAL: ${response.message?.host?.servicesStatus?.state?.critical}</li>
<li>WARNING: ${response.message?.host?.servicesStatus?.state?.warning}</li>
<li>UNKNOWN: ${response.message?.host?.servicesStatus?.state?.unknown}</li>
</ul>
</h3>
</div>
</div>
`
let statusData = document.querySelector('.js-oitc-output')
statusData.style.textAlign = 'center';
statusData.style.color = '#FFF';
statusData.style.fontWeight = 'Bold';
statusData.style.background = background;
statusData.style.padding = '1rem';
})
if (frm.doc.admin_interface_link) {
frm.add_custom_button('Open Admin Interface', () => frm.trigger('open_admin_interface'), 'Actions');
};
@ -10,10 +147,10 @@ frappe.ui.form.on('IT Object', {
frm.add_custom_button('Open Monitoring', () => frm.trigger('open_monitoring'), 'Actions');
};
},
open_admin_interface: function(frm) {
open_admin_interface: function (frm) {
window.open(frm.doc.admin_interface_link, '_blank').focus();
},
open_monitoring: function(frm) {
open_monitoring: function (frm) {
window.open(frm.doc.monitoring_link, '_blank').focus();
},

View File

@ -17,6 +17,8 @@
"customer",
"it_landscape",
"location",
"monitoring_section",
"oitc_output",
"description_section",
"description",
"image",
@ -143,11 +145,22 @@
"fieldname": "oitc_host_uuid",
"fieldtype": "Data",
"label": "OITC Host UUID"
},
{
"fieldname": "monitoring_section",
"fieldtype": "Column Break",
"label": "Monitoring"
},
{
"fieldname": "oitc_output",
"fieldtype": "HTML",
"label": "OITC Output",
"options": "<div id=\"oitc-output\">OITC output expected</div>"
}
],
"image_field": "image",
"links": [],
"modified": "2022-07-18 10:24:39.463386",
"modified": "2022-07-18 15:05:40.504305",
"modified_by": "Administrator",
"module": "MSP",
"name": "IT Object",

View File

@ -3,8 +3,74 @@
# For license information, please see license.txt
from __future__ import unicode_literals
# import frappe
import frappe
import requests
from frappe.model.document import Document
class ITObject(Document):
pass
def get_host_status_from_hosts_data(self, hosts_data, msp_settings_doc):
host_data_response = {}
for host_data in hosts_data['all_hosts']:
if host_data['Host']['uuid'] != self.oitc_host_uuid:
continue
host_data_response = {
'status': 200,
'host': {
'id': host_data['Host']['id'],
'uuid': host_data['Host']['uuid'],
'hostStatus': {
'currentState': host_data['Hoststatus']['humanState'],
'lastCheck': host_data['Hoststatus']['lastCheckInWords'],
'nextCheck': host_data['Hoststatus']['nextCheckInWords'],
'currentStateSince': host_data['Hoststatus']['lastHardStateChangeInWords']
},
'servicesStatus': {
'totalServices': host_data['ServicestatusSummary']['total'],
'state': {
'ok': host_data['ServicestatusSummary']['state']['ok'],
'critical': host_data['ServicestatusSummary']['state']['critical'],
'unknown': host_data['ServicestatusSummary']['state']['unknown'],
'warning': host_data['ServicestatusSummary']['state']['warning']
}
}
},
'statusColors': {
'upStateColor': msp_settings_doc.oitc_status_up_color,
'downStateColor': msp_settings_doc.oitc_status_down_color,
'unreachableStateColor': msp_settings_doc.oitc_status_unreachable_color
}
}
return host_data_response
@frappe.whitelist()
def get_oitc_host_status_data(self):
msp_settings_doc = frappe.get_doc('MSP Settings')
if not self.oitc_host_uuid:
return {
'status': 422,
'response': "This host does not have any OITC Host UUID stored. Please store an OITC Host UUID in the 'External References' section to get its status data."
}
try:
endpoint = f'{msp_settings_doc.oitc_url}hosts/index.json?angular=true&scroll=true&page=1'
api_authorization = f'{msp_settings_doc.oitc_api_key_header_string}' + msp_settings_doc.get_password('oitc_api_key')
headers = {'Authorization': api_authorization}
hosts_data = requests.get(url=endpoint, headers=headers, verify=False)
return self.get_host_status_from_hosts_data(hosts_data.json(), msp_settings_doc)
except Exception as exception:
exception_message = f'Data could not be fetched from {msp_settings_doc.oitc_url}. Error -> {str(exception)}'
return {
'status': 500,
'response': exception_message
}

View File

@ -8,7 +8,12 @@
"field_order": [
"open_it_cockpit_integration_section",
"oitc_url",
"oitc_api_key_header_string",
"oitc_api_key",
"column_break_column",
"oitc_status_up_color",
"oitc_status_down_color",
"oitc_status_unreachable_color",
"qr_code_settings_section",
"qr_code_dark_color",
"qr_code_scale"
@ -27,7 +32,8 @@
{
"fieldname": "oitc_api_key",
"fieldtype": "Password",
"label": "OITC API Key"
"label": "OITC API Key",
"length": 200
},
{
"fieldname": "qr_code_settings_section",
@ -43,12 +49,40 @@
"fieldname": "qr_code_scale",
"fieldtype": "Int",
"label": "QR Code Scale"
},
{
"default": "X-OITC-API ",
"fieldname": "oitc_api_key_header_string",
"fieldtype": "Read Only",
"label": "OITC API Key Header string",
"length": 100,
"options": "X-OITC-API "
},
{
"fieldname": "column_break_column",
"fieldtype": "Column Break",
"label": "Column Break"
},
{
"fieldname": "oitc_status_up_color",
"fieldtype": "Color",
"label": "OITC Status Up Color"
},
{
"fieldname": "oitc_status_down_color",
"fieldtype": "Color",
"label": "OITC Status Down Color"
},
{
"fieldname": "oitc_status_unreachable_color",
"fieldtype": "Color",
"label": "OITC Status Unreachable Color"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-07-18 10:53:35.413597",
"modified": "2022-07-19 12:16:04.805493",
"modified_by": "Administrator",
"module": "MSP",
"name": "MSP Settings",