Skip to content

Commit

Permalink
Release 0.16.4
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1te909 committed Sep 2, 2023
2 parents 73c9956 + 9dc0b24 commit fd80ccd
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 53 deletions.
12 changes: 12 additions & 0 deletions api/tacticalrmm/agents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,13 @@ def install_agent(request):
from agents.utils import get_agent_url
from core.utils import token_is_valid

insecure = getattr(settings, "TRMM_INSECURE", False)

if insecure and request.data["installMethod"] in {"exe", "powershell"}:
return notify_error(
"Not available in insecure mode. Please use the 'Manual' method."
)

# TODO rework this ghetto validation hack
# https://github.com/amidaware/tacticalrmm/issues/1461
try:
Expand Down Expand Up @@ -672,6 +679,9 @@ def install_agent(request):
if int(request.data["power"]):
cmd.append("--power")

if insecure:
cmd.append("--insecure")

resp["cmd"] = " ".join(str(i) for i in cmd)
else:
install_flags.insert(0, f"sudo ./{inno}")
Expand All @@ -680,6 +690,8 @@ def install_agent(request):
resp["cmd"] = (
dl + f" && chmod +x {inno} && " + " ".join(str(i) for i in cmd)
)
if insecure:
resp["cmd"] += " --insecure"

resp["url"] = download_url

Expand Down
25 changes: 25 additions & 0 deletions api/tacticalrmm/checks/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,31 @@ def test_add_cpuload_check(self):

self.check_not_authenticated("post", url)

def test_reset_all_checks_status(self):
# setup data
agent = baker.make_recipe("agents.agent")
check = baker.make_recipe("checks.diskspace_check", agent=agent)
baker.make("checks.CheckResult", assigned_check=check, agent=agent)
baker.make(
"checks.CheckHistory",
check_id=check.id,
agent_id=agent.agent_id,
_quantity=30,
)
baker.make(
"checks.CheckHistory",
check_id=check.id,
agent_id=agent.agent_id,
_quantity=30,
)

url = f"{base_url}/{agent.agent_id}/resetall/"

resp = self.client.post(url)
self.assertEqual(resp.status_code, 200)

self.check_not_authenticated("post", url)

def test_add_memory_check(self):
url = f"{base_url}/"
agent = baker.make_recipe("agents.agent")
Expand Down
1 change: 1 addition & 0 deletions api/tacticalrmm/checks/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
path("", views.GetAddChecks.as_view()),
path("<int:pk>/", views.GetUpdateDeleteCheck.as_view()),
path("<int:pk>/reset/", views.ResetCheck.as_view()),
path("<agent:agent_id>/resetall/", views.ResetAllChecksStatus.as_view()),
path("<agent:agent_id>/run/", views.run_checks),
path("<int:pk>/history/", views.GetCheckHistory.as_view()),
path("<str:target>/<int:pk>/csbulkrun/", views.bulk_run_checks),
Expand Down
49 changes: 44 additions & 5 deletions api/tacticalrmm/checks/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import asyncio
from datetime import datetime as dt

from django.db.models import Q
from django.db.models import Prefetch, Q
from django.shortcuts import get_object_or_404
from django.utils import timezone as djangotime
from rest_framework.decorators import api_view, permission_classes
Expand All @@ -13,7 +13,7 @@
from agents.models import Agent
from alerts.models import Alert
from automation.models import Policy
from tacticalrmm.constants import CheckStatus, CheckType
from tacticalrmm.constants import AGENT_DEFER, CheckStatus, CheckType
from tacticalrmm.exceptions import NatsDown
from tacticalrmm.helpers import notify_error
from tacticalrmm.nats_utils import abulk_nats_command
Expand Down Expand Up @@ -122,15 +122,54 @@ def post(self, request, pk):
result.save()

# resolve any alerts that are open
alert = Alert.create_or_return_check_alert(
if alert := Alert.create_or_return_check_alert(
result.assigned_check, agent=result.agent, skip_create=True
)
if alert:
):
alert.resolve()

return Response("The check status was reset")


class ResetAllChecksStatus(APIView):
permission_classes = [IsAuthenticated, ChecksPerms]

def post(self, request, agent_id):
agent = get_object_or_404(
Agent.objects.defer(*AGENT_DEFER)
.select_related(
"policy",
"policy__alert_template",
"alert_template",
)
.prefetch_related(
Prefetch(
"checkresults",
queryset=CheckResult.objects.select_related("assigned_check"),
),
"agentchecks",
),
agent_id=agent_id,
)

if not _has_perm_on_agent(request.user, agent.agent_id):
raise PermissionDenied()

for check in agent.get_checks_with_policies():
try:
result = check.check_result
result.status = CheckStatus.PASSING
result.save()
if alert := Alert.create_or_return_check_alert(
result.assigned_check, agent=agent, skip_create=True
):
alert.resolve()
except:
# check hasn't run yet, no check result entry
continue

return Response("All checks status were reset")


class GetCheckHistory(APIView):
permission_classes = [IsAuthenticated, ChecksPerms]

Expand Down
7 changes: 7 additions & 0 deletions api/tacticalrmm/clients/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import uuid
from contextlib import suppress

from django.conf import settings
from django.db.models import Count, Exists, OuterRef, Prefetch, prefetch_related_objects
from django.shortcuts import get_object_or_404
from django.utils import timezone as djangotime
Expand Down Expand Up @@ -288,6 +289,9 @@ def get(self, request):
return Response(DeploymentSerializer(deps, many=True).data)

def post(self, request):
if getattr(settings, "TRMM_INSECURE", False):
return notify_error("Not available in insecure mode")

from accounts.models import User

site = get_object_or_404(Site, pk=request.data["site"])
Expand Down Expand Up @@ -343,6 +347,9 @@ class GenerateAgent(APIView):
permission_classes = (AllowAny,)

def get(self, request, uid):
if getattr(settings, "TRMM_INSECURE", False):
return notify_error("Not available in insecure mode")

from tacticalrmm.utils import generate_winagent_exe

try:
Expand Down
43 changes: 35 additions & 8 deletions api/tacticalrmm/core/agent_linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ if [ "${HAS_SYSTEMD}" != 'systemd' ]; then
exit 1
fi

if [[ $DISPLAY ]]; then
echo "ERROR: Display detected. Installer only supports running headless, i.e from ssh."
echo "If you cannot ssh in then please run 'sudo systemctl isolate multi-user.target' to switch to a non-graphical user session and run the installer again."
exit 1
fi

DEBUG=0
INSECURE=0
NOMESH=0

agentDL='agentDLChange'
meshDL='meshDLChange'

Expand Down Expand Up @@ -124,6 +134,19 @@ if [ $# -ne 0 ] && [ $1 == 'uninstall' ]; then
exit 0
fi

while [[ "$#" -gt 0 ]]; do
case $1 in
--debug) DEBUG=1 ;;
--insecure) INSECURE=1 ;;
--nomesh) NOMESH=1 ;;
*)
echo "ERROR: Unknown parameter: $1"
exit 1
;;
esac
shift
done

RemoveOldAgent

echo "Downloading tactical agent..."
Expand All @@ -136,7 +159,7 @@ chmod +x ${agentBin}

MESH_NODE_ID=""

if [ $# -ne 0 ] && [ $1 == '--nomesh' ]; then
if [[ $NOMESH -eq 1 ]]; then
echo "Skipping mesh install"
else
if [ -f "${meshSystemBin}" ]; then
Expand All @@ -154,18 +177,22 @@ if [ ! -d "${agentBinPath}" ]; then
mkdir -p ${agentBinPath}
fi

if [ $# -ne 0 ] && [ $1 == '--debug' ]; then
INSTALL_CMD="${agentBin} -m install -api ${apiURL} -client-id ${clientID} -site-id ${siteID} -agent-type ${agentType} -auth ${token} -log debug"
else
INSTALL_CMD="${agentBin} -m install -api ${apiURL} -client-id ${clientID} -site-id ${siteID} -agent-type ${agentType} -auth ${token}"
fi
INSTALL_CMD="${agentBin} -m install -api ${apiURL} -client-id ${clientID} -site-id ${siteID} -agent-type ${agentType} -auth ${token}"

if [ "${MESH_NODE_ID}" != '' ]; then
INSTALL_CMD+=" -meshnodeid ${MESH_NODE_ID}"
INSTALL_CMD+=" --meshnodeid ${MESH_NODE_ID}"
fi

if [[ $DEBUG -eq 1 ]]; then
INSTALL_CMD+=" --log debug"
fi

if [[ $INSECURE -eq 1 ]]; then
INSTALL_CMD+=" --insecure"
fi

if [ "${proxy}" != '' ]; then
INSTALL_CMD+=" -proxy ${proxy}"
INSTALL_CMD+=" --proxy ${proxy}"
fi

eval ${INSTALL_CMD}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.conf import settings
from django.core.management.base import BaseCommand

from tacticalrmm.helpers import get_nats_ports
from tacticalrmm.helpers import get_nats_internal_protocol, get_nats_ports


class Command(BaseCommand):
Expand All @@ -21,9 +21,10 @@ def handle(self, *args, **kwargs):
ssl = "disable"

nats_std_port, _ = get_nats_ports()
proto = get_nats_internal_protocol()
config = {
"key": settings.SECRET_KEY,
"natsurl": f"tls://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}",
"natsurl": f"{proto}://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}",
"user": db["USER"],
"pass": db["PASSWORD"],
"host": db["HOST"],
Expand Down
24 changes: 24 additions & 0 deletions api/tacticalrmm/core/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,27 @@ def test_get_meshagent_url_docker(self):
r,
"http://tactical-meshcentral:4443/meshagents?id=4&meshid=abc123&installflags=0",
)

@override_settings(TRMM_INSECURE=True)
def test_get_meshagent_url_insecure(self):
r = get_meshagent_url(
ident=MeshAgentIdent.DARWIN_UNIVERSAL,
plat="darwin",
mesh_site="https://mesh.example.com",
mesh_device_id="abc123",
)
self.assertEqual(
r,
"http://mesh.example.com:4430/meshagents?id=abc123&installflags=2&meshinstall=10005",
)

r = get_meshagent_url(
ident=MeshAgentIdent.WIN64,
plat="windows",
mesh_site="https://mesh.example.com",
mesh_device_id="abc123",
)
self.assertEqual(
r,
"http://mesh.example.com:4430/meshagents?id=4&meshid=abc123&installflags=0",
)
10 changes: 8 additions & 2 deletions api/tacticalrmm/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,12 @@ def get_mesh_ws_url() -> str:
if settings.DOCKER_BUILD:
uri = f"{settings.MESH_WS_URL}/control.ashx?auth={token}"
else:
site = core.mesh_site.replace("https", "wss")
uri = f"{site}/control.ashx?auth={token}"
if getattr(settings, "TRMM_INSECURE", False):
site = core.mesh_site.replace("https", "ws")
uri = f"{site}:4430/control.ashx?auth={token}"
else:
site = core.mesh_site.replace("https", "wss")
uri = f"{site}/control.ashx?auth={token}"

return uri

Expand Down Expand Up @@ -181,6 +185,8 @@ def get_meshagent_url(
) -> str:
if settings.DOCKER_BUILD:
base = settings.MESH_WS_URL.replace("ws://", "http://")
elif getattr(settings, "TRMM_INSECURE", False):
base = mesh_site.replace("https", "http") + ":4430"
else:
base = mesh_site

Expand Down
10 changes: 9 additions & 1 deletion api/tacticalrmm/tacticalrmm/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ def get_nats_ports() -> tuple[int, int]:
return nats_standard_port, nats_websocket_port


def get_nats_internal_protocol() -> str:
if getattr(settings, "TRMM_INSECURE", False):
return "nats"

return "tls"


def date_is_in_past(*, datetime_obj: "datetime", agent_tz: str) -> bool:
"""
datetime_obj must be a naive datetime
Expand All @@ -66,8 +73,9 @@ def rand_range(min: int, max: int) -> float:

def setup_nats_options() -> dict[str, Any]:
nats_std_port, _ = get_nats_ports()
proto = get_nats_internal_protocol()
opts = {
"servers": f"tls://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}",
"servers": f"{proto}://{settings.ALLOWED_HOSTS[0]}:{nats_std_port}",
"user": "tacticalrmm",
"name": "trmm-django",
"password": settings.SECRET_KEY,
Expand Down
8 changes: 4 additions & 4 deletions api/tacticalrmm/tacticalrmm/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@
AUTH_USER_MODEL = "accounts.User"

# latest release
TRMM_VERSION = "0.16.3"
TRMM_VERSION = "0.16.4"

# https://github.com/amidaware/tacticalrmm-web
WEB_VERSION = "0.101.28"
WEB_VERSION = "0.101.29"

# bump this version everytime vue code is changed
# to alert user they need to manually refresh their browser
APP_VER = "0.0.183"
APP_VER = "0.0.184"

# https://github.com/amidaware/rmmagent
LATEST_AGENT_VER = "2.4.11"
LATEST_AGENT_VER = "2.5.0"

MESH_VER = "1.1.9"

Expand Down
Loading

0 comments on commit fd80ccd

Please sign in to comment.