Skip to content

Commit

Permalink
Release 0.2.17
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1te909 committed Dec 16, 2020
2 parents a8e03c6 + 8fa368f commit fb43978
Show file tree
Hide file tree
Showing 34 changed files with 1,547 additions and 656 deletions.
12 changes: 12 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: wh1te909
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2020-12-10 17:00

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('accounts', '0008_user_dark_mode'),
]

operations = [
migrations.AddField(
model_name='user',
name='show_community_scripts',
field=models.BooleanField(default=True),
),
]
1 change: 1 addition & 0 deletions api/tacticalrmm/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class User(AbstractUser, BaseAuditModel):
is_active = models.BooleanField(default=True)
totp_key = models.CharField(max_length=50, null=True, blank=True)
dark_mode = models.BooleanField(default=True)
show_community_scripts = models.BooleanField(default=True)

agent = models.OneToOneField(
"agents.Agent",
Expand Down
44 changes: 39 additions & 5 deletions api/tacticalrmm/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,29 @@ def get(self, request, pk):
def put(self, request, pk):
user = get_object_or_404(User, pk=pk)

if (
hasattr(settings, "ROOT_USER")
and request.user != user
and user.username == settings.ROOT_USER
):
return notify_error("The root user cannot be modified from the UI")

serializer = UserSerializer(instance=user, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save()

return Response("ok")

def delete(self, request, pk):
get_object_or_404(User, pk=pk).delete()
user = get_object_or_404(User, pk=pk)
if (
hasattr(settings, "ROOT_USER")
and request.user != user
and user.username == settings.ROOT_USER
):
return notify_error("The root user cannot be deleted from the UI")

user.delete()

return Response("ok")

Expand All @@ -124,17 +139,29 @@ class UserActions(APIView):

# reset password
def post(self, request):

user = get_object_or_404(User, pk=request.data["id"])
if (
hasattr(settings, "ROOT_USER")
and request.user != user
and user.username == settings.ROOT_USER
):
return notify_error("The root user cannot be modified from the UI")

user.set_password(request.data["password"])
user.save()

return Response("ok")

# reset two factor token
def put(self, request):

user = get_object_or_404(User, pk=request.data["id"])
if (
hasattr(settings, "ROOT_USER")
and request.user != user
and user.username == settings.ROOT_USER
):
return notify_error("The root user cannot be modified from the UI")

user.totp_key = ""
user.save()

Expand All @@ -161,6 +188,13 @@ def post(self, request):
class UserUI(APIView):
def patch(self, request):
user = request.user
user.dark_mode = request.data["dark_mode"]
user.save(update_fields=["dark_mode"])

if "dark_mode" in request.data:
user.dark_mode = request.data["dark_mode"]
user.save(update_fields=["dark_mode"])

if "show_community_scripts" in request.data:
user.show_community_scripts = request.data["show_community_scripts"]
user.save(update_fields=["show_community_scripts"])

return Response("ok")
20 changes: 20 additions & 0 deletions api/tacticalrmm/agents/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from time import sleep
import random
import requests
from concurrent.futures import ThreadPoolExecutor
from packaging import version as pyver
from typing import List

Expand All @@ -16,6 +17,25 @@
logger.configure(**settings.LOG_CONFIG)


def _check_agent_service(pk: int) -> None:
agent = Agent.objects.get(pk=pk)
r = asyncio.run(agent.nats_cmd({"func": "ping"}, timeout=2))
if r == "pong":
logger.info(
f"Detected crashed tacticalagent service on {agent.hostname}, attempting recovery"
)
data = {"func": "recover", "payload": {"mode": "tacagent"}}
asyncio.run(agent.nats_cmd(data, wait=False))


@app.task
def monitor_agents_task() -> None:
q = Agent.objects.all()
agents: List[int] = [i.pk for i in q if i.has_nats and i.status != "online"]
with ThreadPoolExecutor(max_workers=15) as executor:
executor.map(_check_agent_service, agents)


def agent_update(pk: int) -> str:
agent = Agent.objects.get(pk=pk)
# skip if we can't determine the arch
Expand Down
6 changes: 6 additions & 0 deletions api/tacticalrmm/agents/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ def test_bulk_cmd_script(

payload = {
"mode": "command",
"monType": "all",
"target": "agents",
"client": None,
"site": None,
Expand All @@ -567,6 +568,7 @@ def test_bulk_cmd_script(

payload = {
"mode": "command",
"monType": "servers",
"target": "agents",
"client": None,
"site": None,
Expand All @@ -581,6 +583,7 @@ def test_bulk_cmd_script(

payload = {
"mode": "command",
"monType": "workstations",
"target": "client",
"client": self.agent.client.id,
"site": None,
Expand All @@ -598,6 +601,7 @@ def test_bulk_cmd_script(

payload = {
"mode": "command",
"monType": "all",
"target": "client",
"client": self.agent.client.id,
"site": self.agent.site.id,
Expand All @@ -615,6 +619,7 @@ def test_bulk_cmd_script(

payload = {
"mode": "scan",
"monType": "all",
"target": "agents",
"client": None,
"site": None,
Expand All @@ -628,6 +633,7 @@ def test_bulk_cmd_script(

payload = {
"mode": "install",
"monType": "all",
"target": "client",
"client": self.agent.client.id,
"site": None,
Expand Down
5 changes: 5 additions & 0 deletions api/tacticalrmm/agents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,11 @@ def bulk(request):
else:
return notify_error("Something went wrong")

if request.data["monType"] == "servers":
q = q.filter(monitoring_type="server")
elif request.data["monType"] == "workstations":
q = q.filter(monitoring_type="workstation")

minions = [agent.salt_id for agent in q]
agents = [agent.pk for agent in q]

Expand Down
6 changes: 5 additions & 1 deletion api/tacticalrmm/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ def version(request):
@api_view()
def dashboard_info(request):
return Response(
{"trmm_version": settings.TRMM_VERSION, "dark_mode": request.user.dark_mode}
{
"trmm_version": settings.TRMM_VERSION,
"dark_mode": request.user.dark_mode,
"show_community_scripts": request.user.show_community_scripts,
}
)


Expand Down
3 changes: 0 additions & 3 deletions api/tacticalrmm/scripts/baker_recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,5 @@
name="Test Script",
description="Test Desc",
shell="cmd",
filename="test.bat",
script_type="userdefined",
)

builtin_script = script.extend(script_type="builtin")
28 changes: 28 additions & 0 deletions api/tacticalrmm/scripts/migrations/0004_auto_20201207_1558.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 3.1.3 on 2020-12-07 15:58

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('scripts', '0003_auto_20200922_1344'),
]

operations = [
migrations.AddField(
model_name='script',
name='category',
field=models.CharField(blank=True, max_length=100, null=True),
),
migrations.AddField(
model_name='script',
name='favorite',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='script',
name='script_base64',
field=models.TextField(blank=True, null=True),
),
]
18 changes: 18 additions & 0 deletions api/tacticalrmm/scripts/migrations/0005_auto_20201207_1606.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.3 on 2020-12-07 16:06

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('scripts', '0004_auto_20201207_1558'),
]

operations = [
migrations.RenameField(
model_name='script',
old_name='script_base64',
new_name='code_base64',
),
]
38 changes: 38 additions & 0 deletions api/tacticalrmm/scripts/migrations/0006_auto_20201210_2145.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 3.1.4 on 2020-12-10 21:45

from django.db import migrations
from django.conf import settings
import os
import base64
from pathlib import Path


def move_scripts_to_db(apps, schema_editor):
print("")
Script = apps.get_model("scripts", "Script")
for script in Script.objects.all():
if not script.script_type == "builtin":

filepath = f"{settings.SCRIPTS_DIR}/userdefined/{script.filename}"

# test if file exists
if os.path.exists(filepath):
print(f"Found script {script.name}. Importing code.")

with open(filepath, "rb") as f:
script_bytes = f.read().decode("utf-8").encode("ascii", "ignore")
script.code_base64 = base64.b64encode(script_bytes).decode("ascii")
script.save(update_fields=["code_base64"])
else:
print(
f"Script file {script.name} was not found on the disk. You will need to edit the script in the UI"
)


class Migration(migrations.Migration):

dependencies = [
("scripts", "0005_auto_20201207_1606"),
]

operations = [migrations.RunPython(move_scripts_to_db, migrations.RunPython.noop)]
Loading

0 comments on commit fb43978

Please sign in to comment.