Release 0.4.5

This commit is contained in:
wh1te909
2021-02-01 20:57:53 +00:00
5 changed files with 57 additions and 111 deletions

View File

@@ -75,13 +75,8 @@ def agent_update(pk: int) -> str:
@app.task @app.task
def send_agent_update_task(pks: List[int], version: str) -> None: def send_agent_update_task(pks: List[int]) -> None:
q = Agent.objects.filter(pk__in=pks) chunks = (pks[i : i + 30] for i in range(0, len(pks), 30))
agents = [i.pk for i in q]
""" agents: List[int] = [
i.pk for i in q if pyver.parse(i.version) < pyver.parse(version)
] """
chunks = (agents[i : i + 30] for i in range(0, len(agents), 30))
for chunk in chunks: for chunk in chunks:
for pk in chunk: for pk in chunk:
agent_update(pk) agent_update(pk)

View File

@@ -4,16 +4,19 @@ from unittest.mock import patch
from model_bakery import baker from model_bakery import baker
from itertools import cycle from itertools import cycle
from typing import List
from packaging import version as pyver
from django.test import TestCase, override_settings
from django.conf import settings from django.conf import settings
from django.utils import timezone as djangotime
from logs.models import PendingAction from logs.models import PendingAction
from tacticalrmm.test import TacticalTestCase from tacticalrmm.test import TacticalTestCase
from .serializers import AgentSerializer from .serializers import AgentSerializer
from winupdate.serializers import WinUpdatePolicySerializer from winupdate.serializers import WinUpdatePolicySerializer
from .models import Agent from .models import Agent
from .tasks import auto_self_agent_update_task
from winupdate.models import WinUpdatePolicy from winupdate.models import WinUpdatePolicy
@@ -64,12 +67,34 @@ class TestAgentViews(TacticalTestCase):
@patch("agents.tasks.send_agent_update_task.delay") @patch("agents.tasks.send_agent_update_task.delay")
def test_update_agents(self, mock_task): def test_update_agents(self, mock_task):
url = "/agents/updateagents/" url = "/agents/updateagents/"
data = {"pks": [1, 2, 3, 5, 10], "version": "0.11.1"} baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version=settings.LATEST_AGENT_VER,
_quantity=15,
)
baker.make_recipe(
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.3.0",
_quantity=15,
)
pks: List[int] = list(
Agent.objects.only("pk", "version").values_list("pk", flat=True)
)
data = {"pks": pks}
expected: List[int] = [
i.pk
for i in Agent.objects.only("pk", "version")
if pyver.parse(i.version) < pyver.parse(settings.LATEST_AGENT_VER)
]
r = self.client.post(url, data, format="json") r = self.client.post(url, data, format="json")
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
mock_task.assert_called_with(pks=data["pks"], version=data["version"]) mock_task.assert_called_with(pks=expected)
self.check_not_authenticated("post", url) self.check_not_authenticated("post", url)
@@ -827,107 +852,30 @@ class TestAgentTasks(TacticalTestCase):
self.assertEqual(action.action_type, "agentupdate") self.assertEqual(action.action_type, "agentupdate")
self.assertEqual(action.status, "pending") self.assertEqual(action.status, "pending")
""" @patch("agents.models.Agent.salt_api_async") @patch("agents.tasks.agent_update")
@patch("agents.tasks.sleep", return_value=None) @patch("agents.tasks.sleep", return_value=None)
def test_auto_self_agent_update_task(self, mock_sleep, salt_api_async): def test_auto_self_agent_update_task(self, mock_sleep, agent_update):
# test 64bit golang agent baker.make_recipe(
self.agent64 = baker.make_recipe(
"agents.agent", "agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)", operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.0.0", version=settings.LATEST_AGENT_VER,
_quantity=23,
) )
salt_api_async.return_value = True baker.make_recipe(
ret = auto_self_agent_update_task.s().apply()
salt_api_async.assert_called_with(
func="win_agent.do_agent_update_v2",
kwargs={
"inno": f"winagent-v{settings.LATEST_AGENT_VER}.exe",
"url": settings.DL_64,
},
)
self.assertEqual(ret.status, "SUCCESS")
self.agent64.delete()
salt_api_async.reset_mock()
# test 32bit golang agent
self.agent32 = baker.make_recipe(
"agents.agent",
operating_system="Windows 7 Professional, 32 bit (build 7601.24544)",
version="1.0.0",
)
salt_api_async.return_value = True
ret = auto_self_agent_update_task.s().apply()
salt_api_async.assert_called_with(
func="win_agent.do_agent_update_v2",
kwargs={
"inno": f"winagent-v{settings.LATEST_AGENT_VER}-x86.exe",
"url": settings.DL_32,
},
)
self.assertEqual(ret.status, "SUCCESS")
self.agent32.delete()
salt_api_async.reset_mock()
# test agent that has a null os field
self.agentNone = baker.make_recipe(
"agents.agent",
operating_system=None,
version="1.0.0",
)
ret = auto_self_agent_update_task.s().apply()
salt_api_async.assert_not_called()
self.agentNone.delete()
salt_api_async.reset_mock()
# test auto update disabled in global settings
self.agent64 = baker.make_recipe(
"agents.agent", "agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)", operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="1.0.0", version="1.3.0",
_quantity=33,
) )
self.coresettings.agent_auto_update = False self.coresettings.agent_auto_update = False
self.coresettings.save(update_fields=["agent_auto_update"]) self.coresettings.save(update_fields=["agent_auto_update"])
ret = auto_self_agent_update_task.s().apply()
salt_api_async.assert_not_called()
# reset core settings r = auto_self_agent_update_task.s().apply()
self.agent64.delete() self.assertEqual(agent_update.call_count, 0)
salt_api_async.reset_mock()
self.coresettings.agent_auto_update = True self.coresettings.agent_auto_update = True
self.coresettings.save(update_fields=["agent_auto_update"]) self.coresettings.save(update_fields=["agent_auto_update"])
# test 64bit python agent r = auto_self_agent_update_task.s().apply()
self.agent64py = baker.make_recipe( self.assertEqual(agent_update.call_count, 33)
"agents.agent",
operating_system="Windows 10 Pro, 64 bit (build 19041.450)",
version="0.11.1",
)
salt_api_async.return_value = True
ret = auto_self_agent_update_task.s().apply()
salt_api_async.assert_called_with(
func="win_agent.do_agent_update_v2",
kwargs={
"inno": "winagent-v0.11.2.exe",
"url": OLD_64_PY_AGENT,
},
)
self.assertEqual(ret.status, "SUCCESS")
self.agent64py.delete()
salt_api_async.reset_mock()
# test 32bit python agent
self.agent32py = baker.make_recipe(
"agents.agent",
operating_system="Windows 7 Professional, 32 bit (build 7601.24544)",
version="0.11.1",
)
salt_api_async.return_value = True
ret = auto_self_agent_update_task.s().apply()
salt_api_async.assert_called_with(
func="win_agent.do_agent_update_v2",
kwargs={
"inno": "winagent-v0.11.2-x86.exe",
"url": OLD_32_PY_AGENT,
},
)
self.assertEqual(ret.status, "SUCCESS") """

View File

@@ -59,9 +59,13 @@ def get_agent_versions(request):
@api_view(["POST"]) @api_view(["POST"])
def update_agents(request): def update_agents(request):
pks = request.data["pks"] q = Agent.objects.filter(pk__in=request.data["pks"]).only("pk", "version")
version = request.data["version"] pks: List[int] = [
send_agent_update_task.delay(pks=pks, version=version) i.pk
for i in q
if pyver.parse(i.version) < pyver.parse(settings.LATEST_AGENT_VER)
]
send_agent_update_task.delay(pks=pks)
return Response("ok") return Response("ok")

View File

@@ -15,11 +15,11 @@ 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.4.4" TRMM_VERSION = "0.4.5"
# 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.109" APP_VER = "0.0.110"
# https://github.com/wh1te909/rmmagent # https://github.com/wh1te909/rmmagent
LATEST_AGENT_VER = "1.4.2" LATEST_AGENT_VER = "1.4.2"

View File

@@ -38,7 +38,6 @@
</template> </template>
<script> <script>
import axios from "axios";
import mixins from "@/mixins/mixins"; import mixins from "@/mixins/mixins";
export default { export default {
name: "UpdateAgents", name: "UpdateAgents",
@@ -58,7 +57,7 @@ export default {
}, },
getVersions() { getVersions() {
this.$q.loading.show(); this.$q.loading.show();
axios this.$axios
.get("/agents/getagentversions/") .get("/agents/getagentversions/")
.then(r => { .then(r => {
this.versions = r.data.versions; this.versions = r.data.versions;
@@ -72,8 +71,8 @@ export default {
}); });
}, },
update() { update() {
const data = { version: this.version, pks: this.group }; const data = { pks: this.group };
axios this.$axios
.post("/agents/updateagents/", data) .post("/agents/updateagents/", data)
.then(r => { .then(r => {
this.$emit("close"); this.$emit("close");