start prepping for go agent

This commit is contained in:
wh1te909 2020-10-12 02:37:49 +00:00
parent 75cca4e75f
commit 055b5241be
14 changed files with 2987 additions and 32 deletions

View File

@ -146,26 +146,30 @@ class Agent(BaseAuditModel):
@property
def local_ips(self):
ret = []
try:
ips = self.wmi_detail["network_config"]
ret = []
for _ in ips:
try:
addr = [x["IPAddress"] for x in _ if "IPAddress" in x][0]
except:
continue
else:
for ip in addr:
if validators.ipv4(ip):
ret.append(ip)
if len(ret) == 1:
return ret[0]
else:
return ", ".join(ret)
except:
except KeyError:
return "error getting local ips"
for i in ips:
try:
addr = [x["IPAddress"] for x in i if "IPAddress" in x][0]
except:
continue
if addr is None:
continue
for ip in addr:
if validators.ipv4(ip):
ret.append(ip)
if len(ret) == 1:
return ret[0]
else:
return ", ".join(ret) if ret else "error getting local ips"
@property
def make_model(self):
try:

View File

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class Apiv3Config(AppConfig):
name = "apiv3"

View File

@ -0,0 +1,16 @@
from tacticalrmm.test import BaseTestCase
from unittest.mock import patch
class TestAPIv3(BaseTestCase):
def test_get_checks(self):
url = f"/api/v3/{self.agent.agent_id}/checkrunner/"
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
url = "/api/v3/Maj34ACb324j234asdj2n34kASDjh34-DESKTOPTEST123/checkrunner/"
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
self.check_not_authenticated("get", url)

View File

@ -0,0 +1,7 @@
from django.urls import path
from . import views
urlpatterns = [
path("checkrunner/", views.CheckRunner.as_view()),
path("<str:agentid>/checkrunner/", views.CheckRunner.as_view()),
]

View File

@ -0,0 +1,41 @@
from django.shortcuts import get_object_or_404
from django.utils import timezone as djangotime
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from agents.models import Agent
from checks.models import Check
from checks.serializers import (
CheckResultsSerializer,
CheckRunnerGetSerializerV3,
)
class CheckRunner(APIView):
"""
For the windows golang agent
"""
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request, agentid):
agent = get_object_or_404(Agent, agent_id=agentid)
checks = Check.objects.filter(agent__pk=agent.pk, overriden_by_policy=False)
ret = {
"agent": agent.pk,
"check_interval": agent.check_interval,
"checks": CheckRunnerGetSerializerV3(checks, many=True).data,
}
return Response(ret)
def patch(self, request):
check = get_object_or_404(Check, pk=request.data["id"])
check.last_run = djangotime.now()
check.save(update_fields=["last_run"])
status = check.handle_checkv2(request.data)
return Response(status)

View File

@ -246,7 +246,12 @@ class Check(BaseAuditModel):
self.stdout = data["stdout"]
self.stderr = data["stderr"]
self.retcode = data["retcode"]
self.execution_time = "{:.4f}".format(data["stop"] - data["start"])
try:
# python agent
self.execution_time = "{:.4f}".format(data["stop"] - data["start"])
except:
# golang agent
self.execution_time = "{:.4f}".format(data["runtime"])
if data["retcode"] != 0:
self.status = "failing"

View File

@ -4,7 +4,7 @@ from rest_framework import serializers
from .models import Check
from autotasks.models import AutomatedTask
from scripts.serializers import ScriptSerializer
from scripts.serializers import ScriptSerializer, ScriptCheckSerializer
class AssignedTaskField(serializers.ModelSerializer):
@ -88,23 +88,13 @@ class CheckRunnerGetSerializer(serializers.ModelSerializer):
task = obj.assignedtask.first()
return AssignedTaskCheckRunnerField(task).data
class CheckRunnerGetSerializerV2(serializers.ModelSerializer):
# for the windows agent
# only send data needed for agent to run a check
assigned_tasks = serializers.SerializerMethodField()
script = ScriptSerializer(read_only=True)
def get_assigned_tasks(self, obj):
if obj.assignedtask.exists():
tasks = obj.assignedtask.all()
return AssignedTaskCheckRunnerField(tasks, many=True).data
class Meta:
model = Check
exclude = [
"policy",
"managed_by_policy",
"overriden_by_policy",
"parent_check",
"name",
"more_info",
"last_run",
@ -122,6 +112,101 @@ class CheckRunnerGetSerializerV2(serializers.ModelSerializer):
"execution_time",
"svc_display_name",
"svc_policy_mode",
"created_by",
"created_time",
"modified_by",
"modified_time",
"history",
]
class CheckRunnerGetSerializerV2(serializers.ModelSerializer):
# for the windows __python__ agent
# only send data needed for agent to run a check
assigned_tasks = serializers.SerializerMethodField()
script = ScriptSerializer(read_only=True)
def get_assigned_tasks(self, obj):
if obj.assignedtask.exists():
tasks = obj.assignedtask.all()
return AssignedTaskCheckRunnerField(tasks, many=True).data
class Meta:
model = Check
exclude = [
"policy",
"managed_by_policy",
"overriden_by_policy",
"parent_check",
"name",
"more_info",
"last_run",
"email_alert",
"text_alert",
"fails_b4_alert",
"fail_count",
"email_sent",
"text_sent",
"outage_history",
"extra_details",
"stdout",
"stderr",
"retcode",
"execution_time",
"svc_display_name",
"svc_policy_mode",
"created_by",
"created_time",
"modified_by",
"modified_time",
"history",
]
class CheckRunnerGetSerializerV3(serializers.ModelSerializer):
# for the windows __golang__ agent
# only send data needed for agent to run a check
# the difference here is in the script serializer
# script checks no longer rely on salt and are executed directly by the go agent
assigned_tasks = serializers.SerializerMethodField()
script = ScriptCheckSerializer(read_only=True)
def get_assigned_tasks(self, obj):
if obj.assignedtask.exists():
tasks = obj.assignedtask.all()
return AssignedTaskCheckRunnerField(tasks, many=True).data
class Meta:
model = Check
exclude = [
"policy",
"managed_by_policy",
"overriden_by_policy",
"parent_check",
"name",
"more_info",
"last_run",
"email_alert",
"text_alert",
"fails_b4_alert",
"fail_count",
"email_sent",
"text_sent",
"outage_history",
"extra_details",
"stdout",
"stderr",
"retcode",
"execution_time",
"svc_display_name",
"svc_policy_mode",
"created_by",
"created_time",
"modified_by",
"modified_time",
"history",
]

View File

@ -35,3 +35,11 @@ class ScriptSerializer(ModelSerializer):
)
return val
class ScriptCheckSerializer(ModelSerializer):
code = ReadOnlyField()
class Meta:
model = Script
fields = ["code", "shell"]

View File

@ -40,6 +40,7 @@ INSTALLED_APPS = [
"accounts",
"api",
"apiv2",
"apiv3",
"clients",
"agents",
"checks",

View File

@ -1,8 +1,11 @@
import json
import os
import random
import string
from django.test import TestCase, override_settings
from django.utils import timezone as djangotime
from django.conf import settings
from rest_framework.test import APIClient
from rest_framework.test import force_authenticate
@ -30,7 +33,9 @@ class TacticalTestCase(TestCase):
self.client = APIClient()
# fixes tests waiting 2 minutes for mesh token to appear
@override_settings(MESH_TOKEN_KEY="41410834b8bb4481446027f87d88ec6f119eb9aa97860366440b778540c7399613f7cabfef4f1aa5c0bd9beae03757e17b2e990e5876b0d9924da59bdf24d3437b3ed1a8593b78d65a72a76c794160d9")
@override_settings(
MESH_TOKEN_KEY="41410834b8bb4481446027f87d88ec6f119eb9aa97860366440b778540c7399613f7cabfef4f1aa5c0bd9beae03757e17b2e990e5876b0d9924da59bdf24d3437b3ed1a8593b78d65a72a76c794160d9"
)
def setup_coresettings(self):
self.coresettings = CoreSettings.objects.create()
@ -168,6 +173,13 @@ class BaseTestCase(TestCase):
self.assertEqual(r.status_code, 401)
def create_agent(self, hostname, client, site, monitoring_type="server"):
with open(
os.path.join(
settings.BASE_DIR, "tacticalrmm/test_data/wmi_python_agent.json"
)
) as f:
wmi_py = json.load(f)
return Agent.objects.create(
operating_system="Windows 10",
plat="windows",
@ -219,6 +231,7 @@ class BaseTestCase(TestCase):
description="Test PC",
mesh_node_id="abcdefghijklmnopAABBCCDD77443355##!!AI%@#$%#*",
last_seen=djangotime.now(),
wmi_detail=wmi_py,
)
def generate_agent_id(self, hostname):

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ urlpatterns = [
path("logoutall/", knox_views.LogoutAllView.as_view()),
path("api/v1/", include("api.urls")),
path("api/v2/", include("apiv2.urls")),
path("api/v3/", include("apiv3.urls")),
path("clients/", include("clients.urls")),
path("agents/", include("agents.urls")),
path("checks/", include("checks.urls")),