Skip to content

Commit

Permalink
Release 0.2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
wh1te909 committed Dec 2, 2020
2 parents 198c485 + 70dc771 commit 361cc08
Show file tree
Hide file tree
Showing 69 changed files with 993 additions and 1,225 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.git
.cache
**/*.env
**/env
**/node_modules
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Publish Tactical Docker Images
on:
release:
types: [published]
push:
tags:
- "v*.*.*"
jobs:
docker:
name: Build and Push Docker Images
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"python.pythonPath": "api/tacticalrmm/env/bin/python",
"python.languageServer": "Pylance",
"python.analysis.extraPaths": [
"api/tacticalrmm"
"api/tacticalrmm",
],
"python.analysis.typeCheckingMode": "basic",
"python.formatting.provider": "black",
Expand Down
2 changes: 1 addition & 1 deletion api/tacticalrmm/agents/baker_recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get_wmi_data():
agent = Recipe(
Agent,
hostname="DESKTOP-TEST123",
version="1.1.0",
version="1.1.1",
monitoring_type=cycle(["workstation", "server"]),
salt_id=generate_agent_id("DESKTOP-TEST123"),
agent_id="71AHC-AA813-HH1BC-AAHH5-00013|DESKTOP-TEST123",
Expand Down
62 changes: 4 additions & 58 deletions api/tacticalrmm/agents/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import requests
import datetime as dt
import time
import base64
from Crypto.Cipher import AES
Expand All @@ -8,9 +7,7 @@
from Crypto.Util.Padding import pad
import validators
import msgpack
import random
import re
import string
from collections import Counter
from loguru import logger
from packaging import version as pyver
Expand Down Expand Up @@ -89,6 +86,10 @@ def client(self):
def has_nats(self):
return pyver.parse(self.version) >= pyver.parse("1.1.0")

@property
def has_gotasks(self):
return pyver.parse(self.version) >= pyver.parse("1.1.1")

@property
def timezone(self):
# return the default timezone unless the timezone is explicity set per agent
Expand Down Expand Up @@ -573,61 +574,6 @@ def salt_batch_async(**kwargs):

return resp

def schedule_reboot(self, obj):

start_date = dt.datetime.strftime(obj, "%Y-%m-%d")
start_time = dt.datetime.strftime(obj, "%H:%M")

# let windows task scheduler automatically delete the task after it runs
end_obj = obj + dt.timedelta(minutes=15)
end_date = dt.datetime.strftime(end_obj, "%Y-%m-%d")
end_time = dt.datetime.strftime(end_obj, "%H:%M")

task_name = "TacticalRMM_SchedReboot_" + "".join(
random.choice(string.ascii_letters) for _ in range(10)
)

r = self.salt_api_cmd(
timeout=15,
func="task.create_task",
arg=[
f"name={task_name}",
"force=True",
"action_type=Execute",
'cmd="C:\\Windows\\System32\\shutdown.exe"',
'arguments="/r /t 5 /f"',
"trigger_type=Once",
f'start_date="{start_date}"',
f'start_time="{start_time}"',
f'end_date="{end_date}"',
f'end_time="{end_time}"',
"ac_only=False",
"stop_if_on_batteries=False",
"delete_after=Immediately",
],
)

if r == "error" or (isinstance(r, bool) and not r):
return "failed"
elif r == "timeout":
return "timeout"
elif isinstance(r, bool) and r:
from logs.models import PendingAction

details = {
"taskname": task_name,
"time": str(obj),
}
PendingAction(agent=self, action_type="schedreboot", details=details).save()

nice_time = dt.datetime.strftime(obj, "%B %d, %Y at %I:%M %p")
return {"msg": {"time": nice_time, "agent": self.hostname}}
else:
return "failed"

def not_supported(self, version_added):
return pyver.parse(self.version) < pyver.parse(version_added)

def delete_superseded_updates(self):
try:
pks = [] # list of pks to delete
Expand Down
5 changes: 5 additions & 0 deletions api/tacticalrmm/agents/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ class Meta:

class AgentTableSerializer(serializers.ModelSerializer):
patches_pending = serializers.ReadOnlyField(source="has_patches_pending")
pending_actions = serializers.SerializerMethodField()
status = serializers.ReadOnlyField()
checks = serializers.ReadOnlyField()
last_seen = serializers.SerializerMethodField()
client_name = serializers.ReadOnlyField(source="client.name")
site_name = serializers.ReadOnlyField(source="site.name")

def get_pending_actions(self, obj):
return obj.pendingactions.filter(status="pending").count()

def get_last_seen(self, obj):
if obj.time_zone is not None:
agent_tz = pytz.timezone(obj.time_zone)
Expand All @@ -62,6 +66,7 @@ class Meta:
"description",
"needs_reboot",
"patches_pending",
"pending_actions",
"status",
"overdue_text_alert",
"overdue_email_alert",
Expand Down
88 changes: 16 additions & 72 deletions api/tacticalrmm/agents/tasks.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import asyncio
from loguru import logger
from time import sleep
import random
import requests
from packaging import version as pyver


from django.conf import settings


from tacticalrmm.celery import app
from agents.models import Agent, AgentOutage
from core.models import CoreSettings
Expand Down Expand Up @@ -52,9 +49,6 @@ def send_agent_update_task(pks, version):
else:
url = agent.winagent_dl
inno = agent.win_inno_exe
logger.info(
f"Updating {agent.salt_id} current version {agent.version} using {inno}"
)

if agent.has_nats:
if agent.pendingactions.filter(
Expand All @@ -81,7 +75,7 @@ def send_agent_update_task(pks, version):
"url": url,
},
)
sleep(10)
sleep(5)


@app.task
Expand All @@ -97,7 +91,6 @@ def auto_self_agent_update_task():
for i in q
if pyver.parse(i.version) < pyver.parse(settings.LATEST_AGENT_VER)
]
logger.info(f"Updating {len(agents)}")

chunks = (agents[i : i + 30] for i in range(0, len(agents), 30))

Expand All @@ -124,9 +117,6 @@ def auto_self_agent_update_task():
else:
url = agent.winagent_dl
inno = agent.win_inno_exe
logger.info(
f"Updating {agent.salt_id} current version {agent.version} using {inno}"
)

if agent.has_nats:
if agent.pendingactions.filter(
Expand All @@ -153,37 +143,7 @@ def auto_self_agent_update_task():
"url": url,
},
)
sleep(10)


@app.task
def update_salt_minion_task():
q = Agent.objects.all()
agents = [
i.pk
for i in q
if pyver.parse(i.version) >= pyver.parse("0.11.0")
and pyver.parse(i.salt_ver) < pyver.parse(settings.LATEST_SALT_VER)
]

chunks = (agents[i : i + 50] for i in range(0, len(agents), 50))

for chunk in chunks:
for pk in chunk:
agent = Agent.objects.get(pk=pk)
r = agent.salt_api_async(func="win_agent.update_salt")
sleep(20)


@app.task
def get_wmi_detail_task(pk):
agent = Agent.objects.get(pk=pk)
if agent.has_nats:
asyncio.run(agent.nats_cmd({"func": "sysinfo"}, wait=False))
else:
agent.salt_api_async(timeout=30, func="win_agent.local_sys_info")

return "ok"
sleep(5)


@app.task
Expand All @@ -209,25 +169,6 @@ def batch_sync_modules_task():
sleep(10)


@app.task
def batch_sysinfo_task():
# update system info using WMI
agents = Agent.objects.all()

agents_nats = [agent for agent in agents if agent.has_nats]
minions = [
agent.salt_id
for agent in agents
if not agent.has_nats and pyver.parse(agent.version) >= pyver.parse("0.11.0")
]

if minions:
Agent.salt_batch_async(minions=minions, func="win_agent.local_sys_info")

for agent in agents_nats:
asyncio.run(agent.nats_cmd({"func": "sysinfo"}, wait=False))


@app.task
def uninstall_agent_task(salt_id, has_nats):
attempts = 0
Expand Down Expand Up @@ -331,19 +272,22 @@ def agent_recovery_sms_task(pk):

@app.task
def agent_outages_task():
agents = Agent.objects.only("pk")
agents = Agent.objects.only(
"pk", "last_seen", "overdue_time", "overdue_email_alert", "overdue_text_alert"
)

for agent in agents:
if agent.status == "overdue":
outages = AgentOutage.objects.filter(agent=agent)
if outages and outages.last().is_active:
continue
if agent.overdue_email_alert or agent.overdue_text_alert:
if agent.status == "overdue":
outages = AgentOutage.objects.filter(agent=agent)
if outages and outages.last().is_active:
continue

outage = AgentOutage(agent=agent)
outage.save()
outage = AgentOutage(agent=agent)
outage.save()

if agent.overdue_email_alert and not agent.maintenance_mode:
agent_outage_email_task.delay(pk=outage.pk)
if agent.overdue_email_alert and not agent.maintenance_mode:
agent_outage_email_task.delay(pk=outage.pk)

if agent.overdue_text_alert and not agent.maintenance_mode:
agent_outage_sms_task.delay(pk=outage.pk)
if agent.overdue_text_alert and not agent.maintenance_mode:
agent_outage_sms_task.delay(pk=outage.pk)
Loading

0 comments on commit 361cc08

Please sign in to comment.