Release 0.6.1
This commit is contained in:
@@ -166,7 +166,7 @@ class Agent(BaseAuditModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def checks(self):
|
def checks(self):
|
||||||
total, passing, failing = 0, 0, 0
|
total, passing, failing, warning, info = 0, 0, 0, 0, 0
|
||||||
|
|
||||||
if self.agentchecks.exists(): # type: ignore
|
if self.agentchecks.exists(): # type: ignore
|
||||||
for i in self.agentchecks.all(): # type: ignore
|
for i in self.agentchecks.all(): # type: ignore
|
||||||
@@ -174,13 +174,20 @@ class Agent(BaseAuditModel):
|
|||||||
if i.status == "passing":
|
if i.status == "passing":
|
||||||
passing += 1
|
passing += 1
|
||||||
elif i.status == "failing":
|
elif i.status == "failing":
|
||||||
failing += 1
|
if i.alert_severity == "error":
|
||||||
|
failing += 1
|
||||||
|
elif i.alert_severity == "warning":
|
||||||
|
warning += 1
|
||||||
|
elif i.alert_severity == "info":
|
||||||
|
info += 1
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
"total": total,
|
"total": total,
|
||||||
"passing": passing,
|
"passing": passing,
|
||||||
"failing": failing,
|
"failing": failing,
|
||||||
"has_failing_checks": failing > 0,
|
"warning": warning,
|
||||||
|
"info": info,
|
||||||
|
"has_failing_checks": failing > 0 or warning > 0,
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
import random
|
import random
|
||||||
import requests
|
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@@ -21,21 +20,9 @@ from tacticalrmm.utils import run_nats_api_cmd
|
|||||||
logger.configure(**settings.LOG_CONFIG)
|
logger.configure(**settings.LOG_CONFIG)
|
||||||
|
|
||||||
|
|
||||||
def _get_exegen_url() -> str:
|
|
||||||
urls: list[str] = settings.EXE_GEN_URLS
|
|
||||||
for url in urls:
|
|
||||||
try:
|
|
||||||
r = requests.get(url, timeout=10)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if r.status_code == 200:
|
|
||||||
return url
|
|
||||||
|
|
||||||
return random.choice(urls)
|
|
||||||
|
|
||||||
|
|
||||||
def agent_update(pk: int, codesigntoken: str = None) -> str:
|
def agent_update(pk: int, codesigntoken: str = None) -> str:
|
||||||
|
from agents.utils import get_exegen_url
|
||||||
|
|
||||||
agent = Agent.objects.get(pk=pk)
|
agent = Agent.objects.get(pk=pk)
|
||||||
|
|
||||||
if pyver.parse(agent.version) <= pyver.parse("1.3.0"):
|
if pyver.parse(agent.version) <= pyver.parse("1.3.0"):
|
||||||
@@ -52,7 +39,7 @@ def agent_update(pk: int, codesigntoken: str = None) -> str:
|
|||||||
inno = agent.win_inno_exe
|
inno = agent.win_inno_exe
|
||||||
|
|
||||||
if codesigntoken is not None and pyver.parse(version) >= pyver.parse("1.5.0"):
|
if codesigntoken is not None and pyver.parse(version) >= pyver.parse("1.5.0"):
|
||||||
base_url = _get_exegen_url() + "/api/v1/winagents/?"
|
base_url = get_exegen_url() + "/api/v1/winagents/?"
|
||||||
params = {"version": version, "arch": agent.arch, "token": codesigntoken}
|
params = {"version": version, "arch": agent.arch, "token": codesigntoken}
|
||||||
url = base_url + urllib.parse.urlencode(params)
|
url = base_url + urllib.parse.urlencode(params)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -914,7 +914,7 @@ class TestAgentTasks(TacticalTestCase):
|
|||||||
self.authenticate()
|
self.authenticate()
|
||||||
self.setup_coresettings()
|
self.setup_coresettings()
|
||||||
|
|
||||||
@patch("agents.tasks._get_exegen_url")
|
@patch("agents.utils.get_exegen_url")
|
||||||
@patch("agents.models.Agent.nats_cmd")
|
@patch("agents.models.Agent.nats_cmd")
|
||||||
def test_agent_update(self, nats_cmd, get_exe):
|
def test_agent_update(self, nats_cmd, get_exe):
|
||||||
from agents.tasks import agent_update
|
from agents.tasks import agent_update
|
||||||
|
|||||||
37
api/tacticalrmm/agents/utils.py
Normal file
37
api/tacticalrmm/agents/utils.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import random
|
||||||
|
import requests
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def get_exegen_url() -> str:
|
||||||
|
urls: list[str] = settings.EXE_GEN_URLS
|
||||||
|
for url in urls:
|
||||||
|
try:
|
||||||
|
r = requests.get(url, timeout=10)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if r.status_code == 200:
|
||||||
|
return url
|
||||||
|
|
||||||
|
return random.choice(urls)
|
||||||
|
|
||||||
|
|
||||||
|
def get_winagent_url(arch: str) -> str:
|
||||||
|
from core.models import CodeSignToken
|
||||||
|
|
||||||
|
try:
|
||||||
|
codetoken = CodeSignToken.objects.first().token
|
||||||
|
base_url = get_exegen_url() + "/api/v1/winagents/?"
|
||||||
|
params = {
|
||||||
|
"version": settings.LATEST_AGENT_VER,
|
||||||
|
"arch": arch,
|
||||||
|
"token": codetoken,
|
||||||
|
}
|
||||||
|
dl_url = base_url + urllib.parse.urlencode(params)
|
||||||
|
except:
|
||||||
|
dl_url = settings.DL_64 if arch == "64" else settings.DL_32
|
||||||
|
|
||||||
|
return dl_url
|
||||||
@@ -353,6 +353,7 @@ class Reboot(APIView):
|
|||||||
|
|
||||||
@api_view(["POST"])
|
@api_view(["POST"])
|
||||||
def install_agent(request):
|
def install_agent(request):
|
||||||
|
from agents.utils import get_winagent_url
|
||||||
from knox.models import AuthToken
|
from knox.models import AuthToken
|
||||||
|
|
||||||
client_id = request.data["client"]
|
client_id = request.data["client"]
|
||||||
@@ -375,7 +376,7 @@ def install_agent(request):
|
|||||||
inno = (
|
inno = (
|
||||||
f"winagent-v{version}.exe" if arch == "64" else f"winagent-v{version}-x86.exe"
|
f"winagent-v{version}.exe" if arch == "64" else f"winagent-v{version}-x86.exe"
|
||||||
)
|
)
|
||||||
download_url = settings.DL_64 if arch == "64" else settings.DL_32
|
download_url = get_winagent_url(arch)
|
||||||
|
|
||||||
_, token = AuthToken.objects.create(
|
_, token = AuthToken.objects.create(
|
||||||
user=request.user, expiry=dt.timedelta(hours=request.data["expires"])
|
user=request.user, expiry=dt.timedelta(hours=request.data["expires"])
|
||||||
|
|||||||
@@ -86,7 +86,10 @@ class GetUpdateDeleteCheck(APIView):
|
|||||||
check = get_object_or_404(Check, pk=pk)
|
check = get_object_or_404(Check, pk=pk)
|
||||||
|
|
||||||
# remove fields that should not be changed when editing a check from the frontend
|
# remove fields that should not be changed when editing a check from the frontend
|
||||||
if "check_alert" not in request.data.keys():
|
if (
|
||||||
|
"check_alert" not in request.data.keys()
|
||||||
|
and "check_reset" not in request.data.keys()
|
||||||
|
):
|
||||||
[request.data.pop(i) for i in check.non_editable_fields]
|
[request.data.pop(i) for i in check.non_editable_fields]
|
||||||
|
|
||||||
# set event id to 0 if wildcard because it needs to be an integer field for db
|
# set event id to 0 if wildcard because it needs to be an integer field for db
|
||||||
@@ -108,6 +111,11 @@ class GetUpdateDeleteCheck(APIView):
|
|||||||
if check.policy:
|
if check.policy:
|
||||||
update_policy_check_fields_task(checkpk=pk)
|
update_policy_check_fields_task(checkpk=pk)
|
||||||
|
|
||||||
|
# resolve any alerts that are open
|
||||||
|
if "check_reset" in request.data.keys():
|
||||||
|
if obj.alert.filter(resolved=False).exists():
|
||||||
|
obj.alert.get(resolved=False).resolve()
|
||||||
|
|
||||||
return Response(f"{obj.readable_desc} was edited!")
|
return Response(f"{obj.readable_desc} was edited!")
|
||||||
|
|
||||||
def delete(self, request, pk):
|
def delete(self, request, pk):
|
||||||
|
|||||||
@@ -86,16 +86,24 @@ class Client(BaseAuditModel):
|
|||||||
.prefetch_related("agentchecks")
|
.prefetch_related("agentchecks")
|
||||||
)
|
)
|
||||||
|
|
||||||
failing = 0
|
data = {"error": False, "warning": False}
|
||||||
|
|
||||||
for agent in agents:
|
for agent in agents:
|
||||||
if agent.checks["has_failing_checks"]:
|
if agent.checks["has_failing_checks"]:
|
||||||
failing += 1
|
|
||||||
|
if agent.checks["warning"]:
|
||||||
|
data["warning"] = True
|
||||||
|
|
||||||
|
if agent.checks["failing"]:
|
||||||
|
data["error"] = True
|
||||||
|
break
|
||||||
|
|
||||||
if agent.overdue_email_alert or agent.overdue_text_alert:
|
if agent.overdue_email_alert or agent.overdue_text_alert:
|
||||||
if agent.status == "overdue":
|
if agent.status == "overdue":
|
||||||
failing += 1
|
data["error"] = True
|
||||||
|
break
|
||||||
|
|
||||||
return failing > 0
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize(client):
|
def serialize(client):
|
||||||
@@ -184,16 +192,24 @@ class Site(BaseAuditModel):
|
|||||||
.prefetch_related("agentchecks")
|
.prefetch_related("agentchecks")
|
||||||
)
|
)
|
||||||
|
|
||||||
failing = 0
|
data = {"error": False, "warning": False}
|
||||||
|
|
||||||
for agent in agents:
|
for agent in agents:
|
||||||
|
|
||||||
if agent.checks["has_failing_checks"]:
|
if agent.checks["has_failing_checks"]:
|
||||||
failing += 1
|
if agent.checks["warning"]:
|
||||||
|
data["warning"] = True
|
||||||
|
|
||||||
|
if agent.checks["failing"]:
|
||||||
|
data["error"] = True
|
||||||
|
break
|
||||||
|
|
||||||
if agent.overdue_email_alert or agent.overdue_text_alert:
|
if agent.overdue_email_alert or agent.overdue_text_alert:
|
||||||
if agent.status == "overdue":
|
if agent.status == "overdue":
|
||||||
failing += 1
|
data["error"] = True
|
||||||
|
break
|
||||||
|
|
||||||
return failing > 0
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize(site):
|
def serialize(site):
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ class SiteTreeSerializer(ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Site
|
model = Site
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
ordering = ("failing_checks",)
|
|
||||||
|
|
||||||
|
|
||||||
class ClientTreeSerializer(ModelSerializer):
|
class ClientTreeSerializer(ModelSerializer):
|
||||||
@@ -106,7 +105,6 @@ class ClientTreeSerializer(ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Client
|
model = Client
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
ordering = ("failing_checks",)
|
|
||||||
|
|
||||||
|
|
||||||
class DeploymentSerializer(ModelSerializer):
|
class DeploymentSerializer(ModelSerializer):
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
"name": "Disk - Cleanup C: drive",
|
"name": "Disk - Cleanup C: drive",
|
||||||
"description": "Cleans the C: drive's Window Temperary files, Windows SoftwareDistribution folder, the local users Temperary folder, IIS logs (if applicable) and empties the recycling bin. All deleted files will go into a log transcript in $env:TEMP. By default this script leaves files that are newer than 7 days old however this variable can be edited.",
|
"description": "Cleans the C: drive's Window Temperary files, Windows SoftwareDistribution folder, the local users Temperary folder, IIS logs (if applicable) and empties the recycling bin. All deleted files will go into a log transcript in $env:TEMP. By default this script leaves files that are newer than 7 days old however this variable can be edited.",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Other"
|
"category": "TRMM (Win):Maintenance"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"guid": "2f28e8c1-ae0f-4b46-a826-f513974526a3",
|
"guid": "2f28e8c1-ae0f-4b46-a826-f513974526a3",
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
"guid": "3c46290b-85db-4cd2-93a2-943c8c93b3b1",
|
"guid": "3c46290b-85db-4cd2-93a2-943c8c93b3b1",
|
||||||
"filename": "Speedtest.py",
|
"filename": "Speedtest.py",
|
||||||
"submittedBy": "https://github.com/wh1te909",
|
"submittedBy": "https://github.com/wh1te909",
|
||||||
"name": "Network - Speed Test",
|
"name": "Speed Test - Python",
|
||||||
"description": "Runs a Speed Test using Python",
|
"description": "Runs a Speed Test using Python",
|
||||||
"shell": "python",
|
"shell": "python",
|
||||||
"category": "TRMM (Win):Network"
|
"category": "TRMM (Win):Network"
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"guid": "2ea35fa2-c227-4d17-a40e-4d39f252e27a",
|
"guid": "2ea35fa2-c227-4d17-a40e-4d39f252e27a",
|
||||||
"filename": "Win_Bitlocker_Create_Status_Report.ps1",
|
"filename": "Win_Bitlocker_Create_Status_Report.ps1",
|
||||||
"submittedBy": "https://github.com/ThatsNASt",
|
"submittedBy": "https://github.com/ThatsNASt",
|
||||||
"name": "Create Bitlocker Status Report",
|
"name": "Bitlocker - Create Status Report",
|
||||||
"description": "Creates a Bitlocker status report.",
|
"description": "Creates a Bitlocker status report.",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Storage"
|
"category": "TRMM (Win):Storage"
|
||||||
@@ -228,7 +228,7 @@
|
|||||||
"guid": "24f19ead-fdfe-46b4-9dcb-4cd0e12a3940",
|
"guid": "24f19ead-fdfe-46b4-9dcb-4cd0e12a3940",
|
||||||
"filename": "Win_Speedtest.ps1",
|
"filename": "Win_Speedtest.ps1",
|
||||||
"submittedBy": "https://github.com/dinger1986",
|
"submittedBy": "https://github.com/dinger1986",
|
||||||
"name": "Speed Test Powershell",
|
"name": "Speed Test - Powershell",
|
||||||
"description": "Speed Test with Powershell(win 10 or server2016+)",
|
"description": "Speed Test with Powershell(win 10 or server2016+)",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Network"
|
"category": "TRMM (Win):Network"
|
||||||
@@ -327,7 +327,7 @@
|
|||||||
"guid": "5615aa90-0272-427b-8acf-0ca019612501",
|
"guid": "5615aa90-0272-427b-8acf-0ca019612501",
|
||||||
"filename": "Win_Chocolatey_Update_Installed.bat",
|
"filename": "Win_Chocolatey_Update_Installed.bat",
|
||||||
"submittedBy": "https://github.com/silversword411",
|
"submittedBy": "https://github.com/silversword411",
|
||||||
"name": "Chocolatey Update Installed Apps",
|
"name": "Update Installed Apps",
|
||||||
"description": "Update all apps that were installed using Chocolatey.",
|
"description": "Update all apps that were installed using Chocolatey.",
|
||||||
"shell": "cmd",
|
"shell": "cmd",
|
||||||
"category": "TRMM (Win):3rd Party Software>Chocolatey"
|
"category": "TRMM (Win):3rd Party Software>Chocolatey"
|
||||||
@@ -394,7 +394,7 @@
|
|||||||
"name": "Updates - Finish and restart",
|
"name": "Updates - Finish and restart",
|
||||||
"description": "Finish installing Windows updates and restart PC",
|
"description": "Finish installing Windows updates and restart PC",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Other"
|
"category": "TRMM (Win):Updates"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"guid": "63f89be0-a9c9-4c61-9b55-bce0b28b90b2",
|
"guid": "63f89be0-a9c9-4c61-9b55-bce0b28b90b2",
|
||||||
@@ -403,7 +403,7 @@
|
|||||||
"name": "Updates - Finish and Shutdown",
|
"name": "Updates - Finish and Shutdown",
|
||||||
"description": "Finish installing Windows updates and shutdown PC",
|
"description": "Finish installing Windows updates and shutdown PC",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Other"
|
"category": "TRMM (Win):Updates"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"guid": "e09895d5-ca13-44a2-a38c-6e77c740f0e8",
|
"guid": "e09895d5-ca13-44a2-a38c-6e77c740f0e8",
|
||||||
@@ -460,6 +460,16 @@
|
|||||||
"category": "TRMM (Win):Network",
|
"category": "TRMM (Win):Network",
|
||||||
"default_timeout": "90"
|
"default_timeout": "90"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"guid": "abe78170-7cf9-435b-9666-c5ef6c11a106",
|
||||||
|
"filename": "Win_Network_IPv6_Disable.ps1",
|
||||||
|
"submittedBy": "https://github.com/silversword411",
|
||||||
|
"name": "Network IPv6 - Disable",
|
||||||
|
"description": "Disable IPv6 on all adapters",
|
||||||
|
"shell": "powershell",
|
||||||
|
"category": "TRMM (Win):Network",
|
||||||
|
"default_timeout": "90"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"guid": "6ce5682a-49db-4c0b-9417-609cf905ac43",
|
"guid": "6ce5682a-49db-4c0b-9417-609cf905ac43",
|
||||||
"filename": "Win_Win10_Change_Key_and_Activate.ps1",
|
"filename": "Win_Win10_Change_Key_and_Activate.ps1",
|
||||||
@@ -563,9 +573,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"guid": "77da9c87-5a7a-4ba1-bdde-3eeb3b01d62d",
|
"guid": "77da9c87-5a7a-4ba1-bdde-3eeb3b01d62d",
|
||||||
"filename": "Win_Set_Network_To_Private.ps1",
|
"filename": "Win_Network_Set_To_Private.ps1",
|
||||||
"submittedBy": "https://github.com/tremor021",
|
"submittedBy": "https://github.com/tremor021",
|
||||||
"name": "Set Network To Private",
|
"name": "Network Category - Set Network To Private",
|
||||||
"description": "Sets current network type to Private",
|
"description": "Sets current network type to Private",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Network"
|
"category": "TRMM (Win):Network"
|
||||||
@@ -574,7 +584,7 @@
|
|||||||
"guid": "768f42d5-7b45-45ed-8233-254ae537aaa2",
|
"guid": "768f42d5-7b45-45ed-8233-254ae537aaa2",
|
||||||
"filename": "Win_TaskScheduler_Add_Task.ps1",
|
"filename": "Win_TaskScheduler_Add_Task.ps1",
|
||||||
"submittedBy": "https://github.com/tremor021",
|
"submittedBy": "https://github.com/tremor021",
|
||||||
"name": "Add task to TaskScheduler",
|
"name": "Task Scheduler - Add a task",
|
||||||
"description": "Add a task to Task Scheduler, needs editing",
|
"description": "Add a task to Task Scheduler, needs editing",
|
||||||
"shell": "powershell",
|
"shell": "powershell",
|
||||||
"category": "TRMM (Win):Other"
|
"category": "TRMM (Win):Other"
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ EXE_DIR = os.path.join(BASE_DIR, "tacticalrmm/private/exe")
|
|||||||
AUTH_USER_MODEL = "accounts.User"
|
AUTH_USER_MODEL = "accounts.User"
|
||||||
|
|
||||||
# latest release
|
# latest release
|
||||||
TRMM_VERSION = "0.6.0"
|
TRMM_VERSION = "0.6.1"
|
||||||
|
|
||||||
# bump this version everytime vue code is changed
|
# bump this version everytime vue code is changed
|
||||||
# to alert user they need to manually refresh their browser
|
# to alert user they need to manually refresh their browser
|
||||||
APP_VER = "0.0.129"
|
APP_VER = "0.0.130"
|
||||||
|
|
||||||
# https://github.com/wh1te909/rmmagent
|
# https://github.com/wh1te909/rmmagent
|
||||||
LATEST_AGENT_VER = "1.5.0"
|
LATEST_AGENT_VER = "1.5.1"
|
||||||
|
|
||||||
MESH_VER = "0.7.93"
|
MESH_VER = "0.7.93"
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ def generate_winagent_exe(
|
|||||||
file_name: str,
|
file_name: str,
|
||||||
) -> Union[Response, FileResponse]:
|
) -> Union[Response, FileResponse]:
|
||||||
|
|
||||||
from agents.tasks import _get_exegen_url
|
from agents.utils import get_exegen_url
|
||||||
|
|
||||||
inno = (
|
inno = (
|
||||||
f"winagent-v{settings.LATEST_AGENT_VER}.exe"
|
f"winagent-v{settings.LATEST_AGENT_VER}.exe"
|
||||||
@@ -62,7 +62,7 @@ def generate_winagent_exe(
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
codetoken = CodeSignToken.objects.first().token
|
codetoken = CodeSignToken.objects.first().token
|
||||||
base_url = _get_exegen_url() + "/api/v1/winagents/?"
|
base_url = get_exegen_url() + "/api/v1/winagents/?"
|
||||||
params = {
|
params = {
|
||||||
"version": settings.LATEST_AGENT_VER,
|
"version": settings.LATEST_AGENT_VER,
|
||||||
"arch": arch,
|
"arch": arch,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ A backup script is provided for quick and easy way to backup all settings into o
|
|||||||
|
|
||||||
Download the backup script:
|
Download the backup script:
|
||||||
```bash
|
```bash
|
||||||
wget https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/backup.sh
|
wget -N https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/backup.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
From the Web UI, click **Tools > Server Maintenance**
|
From the Web UI, click **Tools > Server Maintenance**
|
||||||
|
|||||||
8
scripts/Win_Network_IPv6_Disable.ps1
Normal file
8
scripts/Win_Network_IPv6_Disable.ps1
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#CVE-2020-16898 | Windows TCP/IP Remote Code Execution Vulnerability
|
||||||
|
#https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16898
|
||||||
|
|
||||||
|
#Disable IPv6 on All Adapers
|
||||||
|
Disable-NetAdapterBinding -Name "*" -ComponentID ms_tcpip6
|
||||||
|
|
||||||
|
#Confirm That all NIC's no longer have IPv6 Enabled
|
||||||
|
(Get-NetAdapterBinding -Name '*' -ComponentID ms_tcpip6).Enabled
|
||||||
@@ -303,17 +303,18 @@
|
|||||||
/>
|
/>
|
||||||
</q-td>
|
</q-td>
|
||||||
<q-td key="checks-status" :props="props">
|
<q-td key="checks-status" :props="props">
|
||||||
<q-icon v-if="props.row.maintenance_mode" name="fas fa-check-double" size="1.2em" color="warning">
|
<q-icon v-if="props.row.maintenance_mode" name="construction" size="1.2em" color="green">
|
||||||
<q-tooltip>Maintenance Mode Enabled</q-tooltip>
|
<q-tooltip>Maintenance Mode Enabled</q-tooltip>
|
||||||
</q-icon>
|
</q-icon>
|
||||||
<q-icon
|
<q-icon v-else-if="props.row.checks.failing > 0" name="fas fa-check-double" size="1.2em" color="negative">
|
||||||
v-else-if="props.row.checks.has_failing_checks"
|
|
||||||
name="fas fa-check-double"
|
|
||||||
size="1.2em"
|
|
||||||
color="negative"
|
|
||||||
>
|
|
||||||
<q-tooltip>Checks failing</q-tooltip>
|
<q-tooltip>Checks failing</q-tooltip>
|
||||||
</q-icon>
|
</q-icon>
|
||||||
|
<q-icon v-else-if="props.row.checks.warning > 0" name="fas fa-check-double" size="1.2em" color="warning">
|
||||||
|
<q-tooltip>Checks warning</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
|
<q-icon v-else-if="props.row.checks.info > 0" name="fas fa-check-double" size="1.2em" color="info">
|
||||||
|
<q-tooltip>Checks info</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
<q-icon v-else name="fas fa-check-double" size="1.2em" color="positive">
|
<q-icon v-else name="fas fa-check-double" size="1.2em" color="positive">
|
||||||
<q-tooltip>Checks passing</q-tooltip>
|
<q-tooltip>Checks passing</q-tooltip>
|
||||||
</q-icon>
|
</q-icon>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<q-table
|
<q-table
|
||||||
dense
|
dense
|
||||||
|
:table-class="{ 'table-bgcolor': !$q.dark.isActive, 'table-bgcolor-dark': $q.dark.isActive }"
|
||||||
class="tabs-tbl-sticky"
|
class="tabs-tbl-sticky"
|
||||||
:style="{ 'max-height': tabsTableHeight }"
|
:style="{ 'max-height': tabsTableHeight }"
|
||||||
:data="tasks"
|
:data="tasks"
|
||||||
|
|||||||
@@ -124,6 +124,13 @@
|
|||||||
<q-item-section>Delete</q-item-section>
|
<q-item-section>Delete</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
<q-separator></q-separator>
|
<q-separator></q-separator>
|
||||||
|
<q-item clickable v-close-popup @click="resetCheck(props.row.id)">
|
||||||
|
<q-item-section side>
|
||||||
|
<q-icon name="info" />
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>Reset Check Status</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-separator></q-separator>
|
||||||
<q-item clickable v-close-popup>
|
<q-item clickable v-close-popup>
|
||||||
<q-item-section>Close</q-item-section>
|
<q-item-section>Close</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
@@ -431,7 +438,25 @@ export default {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
resetCheck(check) {
|
||||||
|
const data = {
|
||||||
|
check_reset: true,
|
||||||
|
status: "passing",
|
||||||
|
};
|
||||||
|
|
||||||
|
axios
|
||||||
|
.patch(`/checks/${check}/check/`, data)
|
||||||
|
.then(r => {
|
||||||
|
this.$emit("refreshEdit");
|
||||||
|
this.$store.dispatch("loadChecks", this.selectedAgentPk);
|
||||||
|
this.notifySuccess("The check was reset");
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
this.notifyError("There was an issue resetting the check");
|
||||||
|
});
|
||||||
|
},
|
||||||
onRefresh(id) {
|
onRefresh(id) {
|
||||||
|
this.$emit("refreshEdit");
|
||||||
this.$store.dispatch("loadChecks", id);
|
this.$store.dispatch("loadChecks", id);
|
||||||
this.$store.dispatch("loadAutomatedTasks", id);
|
this.$store.dispatch("loadAutomatedTasks", id);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -283,10 +283,18 @@
|
|||||||
<q-tooltip> Batch </q-tooltip>
|
<q-tooltip> Batch </q-tooltip>
|
||||||
</q-icon>
|
</q-icon>
|
||||||
</q-td>
|
</q-td>
|
||||||
|
<!-- name -->
|
||||||
<q-td>{{ props.row.name }}</q-td>
|
<q-td>{{ props.row.name }}</q-td>
|
||||||
|
<!-- args -->
|
||||||
<q-td>
|
<q-td>
|
||||||
<span v-if="props.row.args.length > 0">{{ props.row.args }}</span>
|
<span v-if="props.row.args.length > 0">
|
||||||
|
{{ truncateText(props.row.args.toString()) }}
|
||||||
|
<q-tooltip v-if="props.row.args.toString().length >= 60" content-style="font-size: 12px">
|
||||||
|
{{ props.row.args }}
|
||||||
|
</q-tooltip>
|
||||||
|
</span>
|
||||||
</q-td>
|
</q-td>
|
||||||
|
|
||||||
<q-td>{{ props.row.category }}</q-td>
|
<q-td>{{ props.row.category }}</q-td>
|
||||||
<q-td>
|
<q-td>
|
||||||
{{ truncateText(props.row.description) }}
|
{{ truncateText(props.row.description) }}
|
||||||
@@ -363,6 +371,7 @@ export default {
|
|||||||
label: "Default Args",
|
label: "Default Args",
|
||||||
field: "args",
|
field: "args",
|
||||||
align: "left",
|
align: "left",
|
||||||
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "category",
|
name: "category",
|
||||||
@@ -516,11 +525,9 @@ export default {
|
|||||||
},
|
},
|
||||||
categories() {
|
categories() {
|
||||||
let list = [];
|
let list = [];
|
||||||
this.scripts.forEach(script => {
|
this.visibleScripts.forEach(script => {
|
||||||
if (!!script.category && !list.includes(script.category)) {
|
if (!!script.category && !list.includes(script.category)) {
|
||||||
if (script.category !== "Community") {
|
list.push(script.category);
|
||||||
list.push(script.category);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return list;
|
return list;
|
||||||
@@ -538,8 +545,7 @@ export default {
|
|||||||
let scriptsTemp = Object.assign([], this.visibleScripts);
|
let scriptsTemp = Object.assign([], this.visibleScripts);
|
||||||
let categoriesTemp = Object.assign([], this.categories);
|
let categoriesTemp = Object.assign([], this.categories);
|
||||||
|
|
||||||
// add Community and Unassigned values and categories array
|
// add Unassigned category
|
||||||
if (this.showCommunityScripts) categoriesTemp.push("Community");
|
|
||||||
categoriesTemp.push("Unassigned");
|
categoriesTemp.push("Unassigned");
|
||||||
|
|
||||||
const sorted = categoriesTemp.sort();
|
const sorted = categoriesTemp.sort();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<SummaryTab />
|
<SummaryTab />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="checks" class="q-pb-xs q-pt-none">
|
<q-tab-panel name="checks" class="q-pb-xs q-pt-none">
|
||||||
<ChecksTab />
|
<ChecksTab @refreshEdit="$emit('refreshEdit')" />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="tasks" class="q-pb-xs q-pt-none">
|
<q-tab-panel name="tasks" class="q-pb-xs q-pt-none">
|
||||||
<AutomatedTasksTab />
|
<AutomatedTasksTab />
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<q-btn class="q-mr-sm" dense flat push icon="refresh" @click="refreshSummary" />
|
<q-btn class="q-mr-sm" dense flat push icon="refresh" @click="refreshSummary" />
|
||||||
<span>
|
<span>
|
||||||
<b>{{ summary.hostname }}</b>
|
<b>{{ summary.hostname }}</b>
|
||||||
<span v-if="summary.maintenance_mode"> • <q-badge color="warning"> Maintenance Mode </q-badge> </span>
|
<span v-if="summary.maintenance_mode"> • <q-badge color="green"> Maintenance Mode </q-badge> </span>
|
||||||
• {{ summary.operating_system }} • Agent v{{ summary.version }}
|
• {{ summary.operating_system }} • Agent v{{ summary.version }}
|
||||||
</span>
|
</span>
|
||||||
<hr />
|
<hr />
|
||||||
@@ -72,6 +72,14 @@
|
|||||||
<q-avatar size="lg" square icon="cancel" color="red" text-color="white" />
|
<q-avatar size="lg" square icon="cancel" color="red" text-color="white" />
|
||||||
<small>{{ summary.checks.failing }} checks failing</small>
|
<small>{{ summary.checks.failing }} checks failing</small>
|
||||||
</q-chip>
|
</q-chip>
|
||||||
|
<q-chip v-if="summary.checks.warning" square size="lg">
|
||||||
|
<q-avatar size="lg" square icon="warning" color="warning" text-color="white" />
|
||||||
|
<small>{{ summary.checks.warning }} checks warning</small>
|
||||||
|
</q-chip>
|
||||||
|
<q-chip v-if="summary.checks.info" square size="lg">
|
||||||
|
<q-avatar size="lg" square icon="info" color="info" text-color="white" />
|
||||||
|
<small>{{ summary.checks.info }} checks info</small>
|
||||||
|
</q-chip>
|
||||||
<span v-if="awaitingSync(summary.checks.total, summary.checks.passing, summary.checks.failing)"
|
<span v-if="awaitingSync(summary.checks.total, summary.checks.passing, summary.checks.failing)"
|
||||||
>{{ summary.checks.total }} checks awaiting first synchronization</span
|
>{{ summary.checks.total }} checks awaiting first synchronization</span
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@
|
|||||||
<div class="col-3">Day of month to run:</div>
|
<div class="col-3">Day of month to run:</div>
|
||||||
<div class="col-4"></div>
|
<div class="col-4"></div>
|
||||||
<q-select
|
<q-select
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
v-show="winupdatepolicy.run_time_frequency !== 'inherit'"
|
||||||
dense
|
dense
|
||||||
class="col-5"
|
class="col-5"
|
||||||
outlined
|
outlined
|
||||||
@@ -103,11 +103,10 @@
|
|||||||
map-options
|
map-options
|
||||||
/>
|
/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="row">
|
<q-card-section class="row" v-show="winupdatepolicy.run_time_frequency !== 'inherit'">
|
||||||
<div class="col-3">Scheduled Time:</div>
|
<div class="col-3">Scheduled Time:</div>
|
||||||
<div class="col-4"></div>
|
<div class="col-4"></div>
|
||||||
<q-select
|
<q-select
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
dense
|
dense
|
||||||
class="col-5"
|
class="col-5"
|
||||||
outlined
|
outlined
|
||||||
@@ -118,51 +117,17 @@
|
|||||||
/>
|
/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section
|
<q-card-section
|
||||||
v-if="winupdatepolicy.run_time_frequency === 'daily' || winupdatepolicy.run_time_frequency === 'inherit'"
|
v-if="winupdatepolicy.run_time_frequency === 'daily'"
|
||||||
|
v-show="winupdatepolicy.run_time_frequency !== 'inherit'"
|
||||||
>
|
>
|
||||||
<div class="q-gutter-sm">
|
<div class="q-gutter-sm">
|
||||||
<q-checkbox
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="1" label="Monday" />
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="2" label="Tuesday" />
|
||||||
v-model="winupdatepolicy.run_time_days"
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="3" label="Wednesday" />
|
||||||
:val="1"
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="4" label="Thursday" />
|
||||||
label="Monday"
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="5" label="Friday" />
|
||||||
/>
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="6" label="Saturday" />
|
||||||
<q-checkbox
|
<q-checkbox v-model="winupdatepolicy.run_time_days" :val="0" label="Sunday" />
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
v-model="winupdatepolicy.run_time_days"
|
|
||||||
:val="2"
|
|
||||||
label="Tuesday"
|
|
||||||
/>
|
|
||||||
<q-checkbox
|
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
v-model="winupdatepolicy.run_time_days"
|
|
||||||
:val="3"
|
|
||||||
label="Wednesday"
|
|
||||||
/>
|
|
||||||
<q-checkbox
|
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
v-model="winupdatepolicy.run_time_days"
|
|
||||||
:val="4"
|
|
||||||
label="Thursday"
|
|
||||||
/>
|
|
||||||
<q-checkbox
|
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
v-model="winupdatepolicy.run_time_days"
|
|
||||||
:val="5"
|
|
||||||
label="Friday"
|
|
||||||
/>
|
|
||||||
<q-checkbox
|
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
v-model="winupdatepolicy.run_time_days"
|
|
||||||
:val="6"
|
|
||||||
label="Saturday"
|
|
||||||
/>
|
|
||||||
<q-checkbox
|
|
||||||
:disable="winupdatepolicy.run_time_frequency === 'inherit'"
|
|
||||||
v-model="winupdatepolicy.run_time_days"
|
|
||||||
:val="0"
|
|
||||||
label="Sunday"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<!-- Reboot After Installation -->
|
<!-- Reboot After Installation -->
|
||||||
@@ -189,20 +154,15 @@
|
|||||||
<q-checkbox v-model="winupdatepolicy.reprocess_failed_inherit" label="Inherit failed patch settings" />
|
<q-checkbox v-model="winupdatepolicy.reprocess_failed_inherit" label="Inherit failed patch settings" />
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section class="row">
|
<q-card-section class="row" v-show="!winupdatepolicy.reprocess_failed_inherit">
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
<q-checkbox
|
<q-checkbox v-model="winupdatepolicy.reprocess_failed" label="Reprocess failed patches" />
|
||||||
:disable="winupdatepolicy.reprocess_failed_inherit"
|
|
||||||
v-model="winupdatepolicy.reprocess_failed"
|
|
||||||
label="Reprocess failed patches"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<q-input
|
<q-input
|
||||||
dense
|
dense
|
||||||
v-model.number="winupdatepolicy.reprocess_failed_times"
|
v-model.number="winupdatepolicy.reprocess_failed_times"
|
||||||
:disable="winupdatepolicy.reprocess_failed_inherit"
|
|
||||||
type="number"
|
type="number"
|
||||||
filled
|
filled
|
||||||
label="Times"
|
label="Times"
|
||||||
@@ -210,11 +170,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3"></div>
|
<div class="col-3"></div>
|
||||||
<q-checkbox
|
<q-checkbox v-model="winupdatepolicy.email_if_fail" label="Send an email when patch installation fails" />
|
||||||
v-model="winupdatepolicy.email_if_fail"
|
|
||||||
:disable="winupdatepolicy.reprocess_failed_inherit"
|
|
||||||
label="Send an email when patch installation fails"
|
|
||||||
/>
|
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="left" v-if="policy">
|
<q-card-actions align="left" v-if="policy">
|
||||||
<q-btn label="Submit" color="primary" @click="submit" />
|
<q-btn label="Submit" color="primary" @click="submit" />
|
||||||
@@ -249,6 +205,7 @@ export default {
|
|||||||
run_time_hour: 3,
|
run_time_hour: 3,
|
||||||
run_time_frequency: "daily",
|
run_time_frequency: "daily",
|
||||||
run_time_days: [],
|
run_time_days: [],
|
||||||
|
run_time_day: 1,
|
||||||
reboot_after_install: "never",
|
reboot_after_install: "never",
|
||||||
reprocess_failed_inherit: false,
|
reprocess_failed_inherit: false,
|
||||||
reprocess_failed: false,
|
reprocess_failed: false,
|
||||||
|
|||||||
@@ -256,8 +256,9 @@ export default function () {
|
|||||||
alert_template: site.alert_template
|
alert_template: site.alert_template
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site.maintenance_mode) { siteNode["color"] = "warning" }
|
if (site.maintenance_mode) { siteNode["color"] = "green" }
|
||||||
else if (site.failing_checks) { siteNode["color"] = "negative" }
|
else if (site.failing_checks.error) { siteNode["color"] = "negative" }
|
||||||
|
else if (site.failing_checks.warning) { siteNode["color"] = "warning" }
|
||||||
|
|
||||||
childSites.push(siteNode);
|
childSites.push(siteNode);
|
||||||
}
|
}
|
||||||
@@ -274,8 +275,9 @@ export default function () {
|
|||||||
children: childSites
|
children: childSites
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client.maintenance_mode) clientNode["color"] = "warning"
|
if (client.maintenance_mode) clientNode["color"] = "green"
|
||||||
else if (client.failing_checks) clientNode["color"] = "negative"
|
else if (client.failing_checks.error) { clientNode["color"] = "negative" }
|
||||||
|
else if (client.failing_checks.warning) { clientNode["color"] = "warning" }
|
||||||
|
|
||||||
output.push(clientNode);
|
output.push(clientNode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,7 +343,7 @@
|
|||||||
<q-avatar color="primary" text-color="white" size="30px" icon="drag_indicator" />
|
<q-avatar color="primary" text-color="white" size="30px" icon="drag_indicator" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
<SubTableTabs />
|
<SubTableTabs @refreshEdit="refreshEntireSite" />
|
||||||
</template>
|
</template>
|
||||||
</q-splitter>
|
</q-splitter>
|
||||||
</template>
|
</template>
|
||||||
@@ -727,10 +727,10 @@ export default {
|
|||||||
let data = {
|
let data = {
|
||||||
id: node.id,
|
id: node.id,
|
||||||
type: node.raw.split("|")[0],
|
type: node.raw.split("|")[0],
|
||||||
action: node.color === "warning" ? false : true,
|
action: node.color === "green" ? false : true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const text = node.color === "warning" ? "Maintenance mode was disabled" : "Maintenance mode was enabled";
|
const text = node.color === "green" ? "Maintenance mode was disabled" : "Maintenance mode was enabled";
|
||||||
this.$store
|
this.$store
|
||||||
.dispatch("toggleMaintenanceMode", data)
|
.dispatch("toggleMaintenanceMode", data)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
@@ -742,7 +742,7 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
menuMaintenanceText(node) {
|
menuMaintenanceText(node) {
|
||||||
return node.color === "warning" ? "Disable Maintenance Mode" : "Enable Maintenance Mode";
|
return node.color === "green" ? "Disable Maintenance Mode" : "Enable Maintenance Mode";
|
||||||
},
|
},
|
||||||
clearFilter() {
|
clearFilter() {
|
||||||
this.filterTextLength = 0;
|
this.filterTextLength = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user