Compare commits
	
		
			9 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2b3cec06b3 | ||
|  | 8536754d14 | ||
|  | 1f36235801 | ||
|  | a4194b14f9 | ||
|  | 2dcc629d9d | ||
|  | 98ddadc6bc | ||
|  | f6e47b7383 | ||
|  | f073ddc906 | ||
|  | 3e00631925 | 
| @@ -1,3 +1,4 @@ | ||||
| import asyncio | ||||
| from loguru import logger | ||||
| from time import sleep | ||||
| import random | ||||
| @@ -54,7 +55,15 @@ def send_agent_update_task(pks, version): | ||||
|                 if agent.pendingactions.filter( | ||||
|                     action_type="agentupdate", status="pending" | ||||
|                 ).exists(): | ||||
|                     continue | ||||
|                     action = agent.pendingactions.filter( | ||||
|                         action_type="agentupdate", status="pending" | ||||
|                     ).last() | ||||
|                     if pyver.parse(action.details["version"]) < pyver.parse( | ||||
|                         settings.LATEST_AGENT_VER | ||||
|                     ): | ||||
|                         action.delete() | ||||
|                     else: | ||||
|                         continue | ||||
|  | ||||
|                 PendingAction.objects.create( | ||||
|                     agent=agent, | ||||
| @@ -122,7 +131,15 @@ def auto_self_agent_update_task(): | ||||
|                 if agent.pendingactions.filter( | ||||
|                     action_type="agentupdate", status="pending" | ||||
|                 ).exists(): | ||||
|                     continue | ||||
|                     action = agent.pendingactions.filter( | ||||
|                         action_type="agentupdate", status="pending" | ||||
|                     ).last() | ||||
|                     if pyver.parse(action.details["version"]) < pyver.parse( | ||||
|                         settings.LATEST_AGENT_VER | ||||
|                     ): | ||||
|                         action.delete() | ||||
|                     else: | ||||
|                         continue | ||||
|  | ||||
|                 PendingAction.objects.create( | ||||
|                     agent=agent, | ||||
| @@ -146,6 +163,18 @@ def auto_self_agent_update_task(): | ||||
|         sleep(5) | ||||
|  | ||||
|  | ||||
| @app.task | ||||
| def sync_sysinfo_task(): | ||||
|     agents = Agent.objects.all() | ||||
|     online = [ | ||||
|         i | ||||
|         for i in agents | ||||
|         if pyver.parse(i.version) >= pyver.parse("1.1.3") and i.status == "online" | ||||
|     ] | ||||
|     for agent in online: | ||||
|         asyncio.run(agent.nats_cmd({"func": "sync"}, wait=False)) | ||||
|  | ||||
|  | ||||
| @app.task | ||||
| def sync_salt_modules_task(pk): | ||||
|     agent = Agent.objects.get(pk=pk) | ||||
|   | ||||
| @@ -9,21 +9,6 @@ class TestServiceViews(TacticalTestCase): | ||||
|     def setUp(self): | ||||
|         self.authenticate() | ||||
|  | ||||
|     def test_get_services(self): | ||||
|  | ||||
|         # test a call where agent doesn't exist | ||||
|         resp = self.client.get("/services/500/services/", format="json") | ||||
|         self.assertEqual(resp.status_code, 404) | ||||
|  | ||||
|         agent = baker.make_recipe("agents.agent_with_services") | ||||
|         url = f"/services/{agent.pk}/services/" | ||||
|         serializer = ServicesSerializer(agent) | ||||
|         resp = self.client.get(url, format="json") | ||||
|         self.assertEqual(resp.status_code, 200) | ||||
|         self.assertEqual(serializer.data, resp.data) | ||||
|  | ||||
|         self.check_not_authenticated("get", url) | ||||
|  | ||||
|     def test_default_services(self): | ||||
|         url = "/services/defaultservices/" | ||||
|         resp = self.client.get(url, format="json") | ||||
| @@ -33,13 +18,13 @@ class TestServiceViews(TacticalTestCase): | ||||
|         self.check_not_authenticated("get", url) | ||||
|  | ||||
|     @patch("agents.models.Agent.nats_cmd") | ||||
|     def test_get_refreshed_services(self, nats_cmd): | ||||
|     def test_get_services(self, nats_cmd): | ||||
|         # test a call where agent doesn't exist | ||||
|         resp = self.client.get("/services/500/refreshedservices/", format="json") | ||||
|         resp = self.client.get("/services/500/services/", format="json") | ||||
|         self.assertEqual(resp.status_code, 404) | ||||
|  | ||||
|         agent = baker.make_recipe("agents.agent_with_services") | ||||
|         url = f"/services/{agent.pk}/refreshedservices/" | ||||
|         url = f"/services/{agent.pk}/services/" | ||||
|  | ||||
|         nats_return = [ | ||||
|             { | ||||
|   | ||||
| @@ -4,7 +4,6 @@ from . import views | ||||
| urlpatterns = [ | ||||
|     path("<int:pk>/services/", views.get_services), | ||||
|     path("defaultservices/", views.default_services), | ||||
|     path("<int:pk>/refreshedservices/", views.get_refreshed_services), | ||||
|     path("serviceaction/", views.service_action), | ||||
|     path("<int:pk>/<svcname>/servicedetail/", views.service_detail), | ||||
|     path("editservice/", views.edit_service), | ||||
|   | ||||
| @@ -19,17 +19,6 @@ logger.configure(**settings.LOG_CONFIG) | ||||
|  | ||||
| @api_view() | ||||
| def get_services(request, pk): | ||||
|     agent = get_object_or_404(Agent, pk=pk) | ||||
|     return Response(ServicesSerializer(agent).data) | ||||
|  | ||||
|  | ||||
| @api_view() | ||||
| def default_services(request): | ||||
|     return Response(Check.load_default_services()) | ||||
|  | ||||
|  | ||||
| @api_view() | ||||
| def get_refreshed_services(request, pk): | ||||
|     agent = get_object_or_404(Agent, pk=pk) | ||||
|     if not agent.has_nats: | ||||
|         return notify_error("Requires agent version 1.1.0 or greater") | ||||
| @@ -43,6 +32,11 @@ def get_refreshed_services(request, pk): | ||||
|     return Response(ServicesSerializer(agent).data) | ||||
|  | ||||
|  | ||||
| @api_view() | ||||
| def default_services(request): | ||||
|     return Response(Check.load_default_services()) | ||||
|  | ||||
|  | ||||
| @api_view(["POST"]) | ||||
| def service_action(request): | ||||
|     agent = get_object_or_404(Agent, pk=request.data["pk"]) | ||||
|   | ||||
| @@ -41,6 +41,10 @@ app.conf.beat_schedule = { | ||||
|         "task": "agents.tasks.auto_self_agent_update_task", | ||||
|         "schedule": crontab(minute=35, hour="*"), | ||||
|     }, | ||||
|     "agents-sync": { | ||||
|         "task": "agents.tasks.sync_sysinfo_task", | ||||
|         "schedule": crontab(minute=55, hour="*"), | ||||
|     }, | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -23,7 +23,7 @@ EXCLUDE_PATHS = ( | ||||
|     "/logs/downloadlog", | ||||
| ) | ||||
|  | ||||
| ENDS_WITH = "/refreshedservices/" | ||||
| ENDS_WITH = "/services/" | ||||
|  | ||||
|  | ||||
| class AuditMiddleware: | ||||
|   | ||||
| @@ -15,19 +15,19 @@ EXE_DIR = os.path.join(BASE_DIR, "tacticalrmm/private/exe") | ||||
| AUTH_USER_MODEL = "accounts.User" | ||||
|  | ||||
| # latest release | ||||
| TRMM_VERSION = "0.2.6" | ||||
| TRMM_VERSION = "0.2.9" | ||||
|  | ||||
| # bump this version everytime vue code is changed | ||||
| # to alert user they need to manually refresh their browser | ||||
| APP_VER = "0.0.96" | ||||
| APP_VER = "0.0.98" | ||||
|  | ||||
| # https://github.com/wh1te909/salt | ||||
| LATEST_SALT_VER = "1.1.0" | ||||
|  | ||||
| # https://github.com/wh1te909/rmmagent | ||||
| LATEST_AGENT_VER = "1.1.2" | ||||
| LATEST_AGENT_VER = "1.1.4" | ||||
|  | ||||
| MESH_VER = "0.7.10" | ||||
| MESH_VER = "0.7.14" | ||||
|  | ||||
| SALT_MASTER_VER = "3002.2" | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|       hide-bottom | ||||
|     > | ||||
|       <template v-slot:top> | ||||
|         <q-btn dense flat push @click="refreshServices" icon="refresh" /> | ||||
|         <q-btn dense flat push @click="getServices" icon="refresh" /> | ||||
|         <q-space /> | ||||
|         <q-input v-model="filter" outlined label="Search" dense clearable> | ||||
|           <template v-slot:prepend> | ||||
| @@ -242,7 +242,7 @@ export default { | ||||
|         .then(r => { | ||||
|           this.serviceDetailVisible = false; | ||||
|           this.serviceDetailsModal = false; | ||||
|           this.refreshServices(); | ||||
|           this.getServices(); | ||||
|           this.notifySuccess(`Service ${name} was edited!`); | ||||
|         }) | ||||
|         .catch(e => { | ||||
| @@ -303,7 +303,7 @@ export default { | ||||
|       this.$axios | ||||
|         .post("/services/serviceaction/", data) | ||||
|         .then(r => { | ||||
|           this.refreshServices(); | ||||
|           this.getServices(); | ||||
|           this.serviceDetailsModal = false; | ||||
|           this.notifySuccess(`Service ${fullname} was ${status}!`); | ||||
|         }) | ||||
| @@ -313,19 +313,9 @@ export default { | ||||
|         }); | ||||
|     }, | ||||
|     getServices() { | ||||
|       this.$q.loading.show({ message: "Loading services..." }); | ||||
|       this.$axios | ||||
|         .get(`/services/${this.pk}/services/`) | ||||
|         .then(r => { | ||||
|           this.servicesData = [r.data][0].services; | ||||
|         }) | ||||
|         .catch(e => { | ||||
|           this.notifyError(e.response.data); | ||||
|         }); | ||||
|     }, | ||||
|     refreshServices() { | ||||
|       this.$q.loading.show({ message: "Reloading services..." }); | ||||
|       this.$axios | ||||
|         .get(`/services/${this.pk}/refreshedservices/`) | ||||
|         .then(r => { | ||||
|           this.servicesData = [r.data][0].services; | ||||
|           this.$q.loading.hide(); | ||||
|   | ||||
| @@ -27,10 +27,13 @@ | ||||
|         <p>Fix issues with the Tactical Checkrunner windows service which handles running all checks.</p> | ||||
|       </q-card-section> | ||||
|       <q-card-section v-show="mode === 'salt'"> | ||||
|         <p>Fix issues with the salt-minion which handles windows updates, chocolatey and scheduled tasks.</p> | ||||
|         <p>Fix issues with the salt-minion which handles windows updates and chocolatey.</p> | ||||
|       </q-card-section> | ||||
|       <q-card-section v-show="mode === 'rpc'"> | ||||
|         <p>Fix issues with the Tactical RPC service which handles most of the agent's realtime functions.</p> | ||||
|         <p> | ||||
|           Fix issues with the Tactical RPC service which handles most of the agent's realtime functions and scheduled | ||||
|           tasks. | ||||
|         </p> | ||||
|       </q-card-section> | ||||
|       <q-card-section v-show="mode === 'command'"> | ||||
|         <p>Run a shell command on the agent.</p> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user