Reporting, RRM features

This commit is contained in:
Dave 2023-06-09 07:03:37 +02:00
parent 7c2ac84e22
commit f9829258f0
21 changed files with 481 additions and 7 deletions

View File

@ -9,6 +9,9 @@ frappe.ui.form.on('IT Landscape', {
};
if (frm.doc.monitoring_link) {
frm.add_custom_button('Open Monitoring', () => frm.trigger('open_monitoring'), 'Actions');
};
if (frm.doc.rmm_instance) {
frm.add_custom_button('Get Agents From RMM', () => frm.trigger('rmm_get_agents'), 'RMM');
}
},
open_ticket_system: function(frm) {
@ -17,6 +20,21 @@ frappe.ui.form.on('IT Landscape', {
open_monitoring: function(frm) {
window.open(frm.doc.monitoring_link, '_blank').focus();
},
rmm_get_agents: function(frm) {
frappe.call({
"method": "msp.tactical-rmm.get_agents",
args: {
"it_landscape": frm.doc.name,
"rmm_instance": frm.doc.rmm_instance,
"tactical_rmm_tenant_caption": frm.doc.tactical_rmm_tenant_caption
},
callback: (response) => {
frappe.msgprint(__(response.message));
}
})
},
copy_ssh_keys: function(frm) {
frappe.call({

View File

@ -21,7 +21,8 @@
"landscape_image",
"monitoring_link",
"ticket_system_link",
"tactical_rmm_tenant_caption"
"tactical_rmm_tenant_caption",
"rmm_instance"
],
"fields": [
{
@ -112,11 +113,17 @@
"fieldtype": "Link",
"label": "IT Contract",
"options": "IT Contract"
},
{
"fieldname": "rmm_instance",
"fieldtype": "Link",
"label": "RMM Instance",
"options": "RMM Instance"
}
],
"image_field": "landscape_image",
"links": [],
"modified": "2023-02-22 20:02:46.515700",
"modified": "2023-06-08 23:20:35.777651",
"modified_by": "Administrator",
"module": "MSP",
"name": "IT Landscape",

View File

@ -28,10 +28,15 @@
"linked_objects",
"network_config_section",
"ip_adresses",
"rmm_data_section",
"rmm_specs",
"rmm_software",
"external_links_section",
"admin_interface_link",
"monitoring_link",
"oitc_host_uuid"
"oitc_host_uuid",
"rmm_agent_id",
"rmm_instance"
],
"fields": [
{
@ -183,11 +188,38 @@
"fieldname": "serial_number",
"fieldtype": "Data",
"label": "Serial Number"
},
{
"fieldname": "rmm_agent_id",
"fieldtype": "Data",
"label": "RMM Agent ID"
},
{
"fieldname": "rmm_instance",
"fieldtype": "Link",
"label": "RMM Instance",
"options": "RMM Instance"
},
{
"collapsible": 1,
"fieldname": "rmm_data_section",
"fieldtype": "Section Break",
"label": "RMM Data"
},
{
"fieldname": "rmm_specs",
"fieldtype": "Markdown Editor",
"label": "RMM Specs"
},
{
"fieldname": "rmm_software",
"fieldtype": "Markdown Editor",
"label": "RMM Software"
}
],
"image_field": "image",
"links": [],
"modified": "2023-03-02 10:10:07.173113",
"modified": "2023-06-08 23:00:31.338542",
"modified_by": "Administrator",
"module": "MSP",
"name": "IT Object",

View File

@ -0,0 +1,8 @@
// Copyright (c) 2023, itsdave GmbH and contributors
// For license information, please see license.txt
frappe.ui.form.on('IT Software Matching', {
// refresh: function(frm) {
// }
});

View File

@ -0,0 +1,70 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "ITSWMATCH-.#####",
"creation": "2023-06-08 22:10:40.703139",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"search_regex",
"software_name",
"category",
"active"
],
"fields": [
{
"fieldname": "search_regex",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Search Regex"
},
{
"fieldname": "software_name",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Software Name"
},
{
"fieldname": "category",
"fieldtype": "Select",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Category",
"options": "\nSoftware\nMS Office"
},
{
"default": "0",
"fieldname": "active",
"fieldtype": "Check",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Active"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-06-08 22:10:59.456228",
"modified_by": "Administrator",
"module": "MSP",
"name": "IT Software Matching",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,8 @@
# Copyright (c) 2023, itsdave GmbH and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class ITSoftwareMatching(Document):
pass

View File

@ -0,0 +1,8 @@
# Copyright (c) 2023, itsdave GmbH and Contributors
# See license.txt
# import frappe
import unittest
class TestITSoftwareMatching(unittest.TestCase):
pass

View File

@ -14,6 +14,16 @@ frappe.ui.form.on('MSP Documentation', {
}
});
}, 'Workflow');
frm.add_custom_button('2. office suche', function(){
frappe.call({
method: 'msp.tactical-rmm.search_office',
args: { documentation: frm.doc.name },
callback:function(r){
console.log(r.message)
frm.reload_doc()
}
});
}, 'Workflow');
}
});

View File

@ -12,6 +12,8 @@
"tactical_rmm_tenant_caption",
"generation_date",
"introduction",
"server_list",
"workstation_list",
"system_list",
"backup",
"aditional_data"
@ -59,11 +61,21 @@
"fieldname": "generation_date",
"fieldtype": "Date",
"label": "Generation Date"
},
{
"fieldname": "server_list",
"fieldtype": "Markdown Editor",
"label": "Server List"
},
{
"fieldname": "workstation_list",
"fieldtype": "Markdown Editor",
"label": "Workstation List"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-02-02 01:08:47.664035",
"modified": "2023-06-08 21:12:01.615350",
"modified_by": "Administrator",
"module": "MSP",
"name": "MSP Documentation",

View File

@ -0,0 +1,8 @@
// Copyright (c) 2023, itsdave GmbH and contributors
// For license information, please see license.txt
frappe.ui.form.on('MSP Functions', {
// refresh: function(frm) {
// }
});

View File

@ -0,0 +1,41 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2023-06-08 21:34:09.516160",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"get_office_versions"
],
"fields": [
{
"fieldname": "get_office_versions",
"fieldtype": "Button",
"label": "Get Office Versions",
"options": "msp.tactical-rmm.search_office"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-06-08 21:34:09.516160",
"modified_by": "Administrator",
"module": "MSP",
"name": "MSP Functions",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,8 @@
# Copyright (c) 2023, itsdave GmbH and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class MSPFunctions(Document):
pass

View File

@ -0,0 +1,8 @@
# Copyright (c) 2023, itsdave GmbH and Contributors
# See license.txt
# import frappe
import unittest
class TestMSPFunctions(unittest.TestCase):
pass

View File

View File

@ -0,0 +1,8 @@
// Copyright (c) 2023, itsdave GmbH and contributors
// For license information, please see license.txt
frappe.ui.form.on('RMM Instance', {
// refresh: function(frm) {
// }
});

View File

@ -0,0 +1,76 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "format:RMMINST-{caption}",
"creation": "2023-06-08 22:46:28.727092",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"caption",
"type",
"api_url",
"user",
"key"
],
"fields": [
{
"fieldname": "type",
"fieldtype": "Select",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Type",
"options": "Tactical RMM",
"reqd": 1
},
{
"fieldname": "api_url",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "API URL",
"reqd": 1
},
{
"fieldname": "caption",
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Caption",
"reqd": 1
},
{
"fieldname": "user",
"fieldtype": "Data",
"label": "User"
},
{
"fieldname": "key",
"fieldtype": "Password",
"label": "Key"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-06-08 22:48:17.914520",
"modified_by": "Administrator",
"module": "MSP",
"name": "RMM Instance",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC"
}

View File

@ -0,0 +1,8 @@
# Copyright (c) 2023, itsdave GmbH and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class RMMInstance(Document):
pass

View File

@ -0,0 +1,8 @@
# Copyright (c) 2023, itsdave GmbH and Contributors
# See license.txt
# import frappe
import unittest
class TestRMMInstance(unittest.TestCase):
pass

View File

@ -4,6 +4,84 @@ from frappe.utils.password import get_decrypted_password
import requests
import json
from pprint import pprint
import re
@frappe.whitelist()
def get_agents(it_landscape, rmm_instance = None, tactical_rmm_tenant_caption = None):
pass
@frappe.whitelist()
def get_relevant_software_for_agent(agent_id):
found_software = []
software_for_agent = get_software_for_agent(agent_id)
if "software" in software_for_agent:
for s in software_for_agent["software"]:
result = _match_software(s)
if result:
found_software.append(result)
return(found_software)
def _match_software(rmm_software_elememt):
sw_match_list = frappe.get_all("IT Software Matching", fields=["search_regex", "software_name", "category"], filters={"active": 1})
for el in sw_match_list:
result = re.match(el["search_regex"])
if result:
return {el["software_name"], el["category"]}
return None
@frappe.whitelist()
def search_office(agents = None):
points_for_found_strings = {}
agents_with_office = []
if not agents:
agents = get_all_agents()
todo = len(agents)
count = 0
for agent in agents:
found_office = False
count = count + 1
print("verarbeite agent " + str(count) + " von " + str(todo))
software_for_agent = get_software_for_agent(agent["agent_id"])
if "software" in software_for_agent:
for s in software_for_agent["software"]:
if (s["name"].lower().startswith("Microsoft Office".lower())):
found_string = s["name"]
found_office = True
if found_string in points_for_found_strings.keys():
points_for_found_strings[found_string] = points_for_found_strings[found_string] + 1
else:
points_for_found_strings[found_string] = 1
if found_office:
agents_with_office.append(agent)
else:
pass
print(points_for_found_strings)
#print(len(agents_with_office))
search_for_office_patches(agents_with_office)
print(points_for_found_strings)
def search_for_office_patches(agents_with_office):
count = 0
for agent in agents_with_office:
found_patches_for_office = False
patches = get_patches_for_agent(agent["agent_id"])
for patch in patches:
if "office".lower() in patch["title"].lower():
found_patches_for_office = True
if found_patches_for_office == False:
print("kein patch für agent mit office gefunden: " + agent["hostname"] + " | " + agent["client_name"])
count = count + 1
print("Anzahl Clients: " + str(count))
@frappe.whitelist()
def get_agents_pretty(documentation):
@ -15,15 +93,30 @@ def get_agents_pretty(documentation):
client_name = documentation_doc.tactical_rmm_tenant_caption
agents = get_all_agents()
print(agents)
agent_list = []
workstation_list = []
server_list = []
#if not agent_list:
# frappe.throw("API Abfrage hat keine Agents geliefert.")
for agent in agents:
if agent["client_name"] == client_name:
agent_list.append(agent)
if agent["monitoring_type"] == "workstation":
workstation_list.append(agent)
if agent["monitoring_type"] == "server":
server_list.append(agent)
pprint(agent)
output = make_agent_md_output(agent_list)
output_workstation = make_agent_md_output(workstation_list)
output_server = make_agent_md_output(server_list)
documentation_doc.system_list = output
documentation_doc.workstation_list = output_workstation
documentation_doc.server_list = output_server
documentation_doc.save()
return agent_list
@ -42,9 +135,48 @@ def get_all_agents():
}
agents = requests.get(f"{API}/agents/?detail=true", headers=HEADERS)
return agents.json()
def get_software_for_agent(agent_id=None):
settings = frappe.get_single("MSP Settings")
if not settings.api_key:
frappe.throw("API Key is missing")
if not settings.api_url:
frappe.throw("API URL is missing")
API = settings.api_url
HEADERS = {
"Content-Type": "application/json",
"X-API-KEY": get_decrypted_password("MSP Settings", "MSP Settings", "api_key", raise_exception=True),
}
if not agent_id:
frappe.throw("Agent ID fehlt")
software_for_agent = requests.get(f"{API}/software/{agent_id}/", headers=HEADERS)
return software_for_agent.json()
def get_patches_for_agent(agent_id=None):
settings = frappe.get_single("MSP Settings")
if not settings.api_key:
frappe.throw("API Key is missing")
if not settings.api_url:
frappe.throw("API URL is missing")
API = settings.api_url
HEADERS = {
"Content-Type": "application/json",
"X-API-KEY": get_decrypted_password("MSP Settings", "MSP Settings", "api_key", raise_exception=True),
}
if not agent_id:
frappe.throw("Agent ID fehlt")
patches_for_agent = requests.get(f"{API}/winupdate/{agent_id}/", headers=HEADERS)
return patches_for_agent.json()
def make_agent_md_output(agents):
md_output = ""
@ -56,8 +188,12 @@ def make_agent_md_output(agents):
- GPU: {agent["graphics"]}
- Disks: {agent["physical_disks"]}
- Model: {render_model(agent["make_model"])}
- Serial Number: {agent["serial_number"]}
- Type: {agent["monitoring_type"]}
- Site: {agent["site_name"]}
- Local IPs: {agent["local_ips"]}
- Public IP: {agent["public_ip"]}
- Last Seen: {agent["last_seen"]}
- Last User: {agent["logged_username"]}
'''
if agent["description"]: