Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4942f262f1 | ||
|
|
a20b1a973e | ||
|
|
eae5e00706 | ||
|
|
5c92d4b454 | ||
|
|
38179b9d38 | ||
|
|
8f510dde5a | ||
|
|
be42d56e37 | ||
|
|
c5c8f5fab1 | ||
|
|
3d41d79078 | ||
|
|
3005061a11 | ||
|
|
65ea46f457 |
@@ -13,12 +13,17 @@ EXPOSE 8000 8383 8005
|
|||||||
RUN groupadd -g 1000 tactical && \
|
RUN groupadd -g 1000 tactical && \
|
||||||
useradd -u 1000 -g 1000 tactical
|
useradd -u 1000 -g 1000 tactical
|
||||||
|
|
||||||
# Copy Dev python reqs
|
# Copy nats-api file
|
||||||
COPY ./requirements.txt /
|
COPY natsapi/bin/nats-api /usr/local/bin/
|
||||||
|
RUN chmod +x /usr/local/bin/nats-api
|
||||||
|
|
||||||
# Copy Docker Entrypoint
|
# Copy dev python reqs
|
||||||
COPY ./entrypoint.sh /
|
COPY .devcontainer/requirements.txt /
|
||||||
|
|
||||||
|
# Copy docker entrypoint.sh
|
||||||
|
COPY .devcontainer/entrypoint.sh /
|
||||||
RUN chmod +x /entrypoint.sh
|
RUN chmod +x /entrypoint.sh
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
ENTRYPOINT ["/entrypoint.sh"]
|
||||||
|
|
||||||
WORKDIR ${WORKSPACE_DIR}/api/tacticalrmm
|
WORKDIR ${WORKSPACE_DIR}/api/tacticalrmm
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ services:
|
|||||||
image: api-dev
|
image: api-dev
|
||||||
restart: always
|
restart: always
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ..
|
||||||
dockerfile: ./api.dockerfile
|
dockerfile: .devcontainer/api.dockerfile
|
||||||
command: ["tactical-api"]
|
command: ["tactical-api"]
|
||||||
environment:
|
environment:
|
||||||
API_PORT: ${API_PORT}
|
API_PORT: ${API_PORT}
|
||||||
@@ -127,9 +127,6 @@ services:
|
|||||||
init-dev:
|
init-dev:
|
||||||
container_name: trmm-init-dev
|
container_name: trmm-init-dev
|
||||||
image: api-dev
|
image: api-dev
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./api.dockerfile
|
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
command: ["tactical-init-dev"]
|
command: ["tactical-init-dev"]
|
||||||
environment:
|
environment:
|
||||||
@@ -156,9 +153,6 @@ services:
|
|||||||
celery-dev:
|
celery-dev:
|
||||||
container_name: trmm-celery-dev
|
container_name: trmm-celery-dev
|
||||||
image: api-dev
|
image: api-dev
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./api.dockerfile
|
|
||||||
command: ["tactical-celery-dev"]
|
command: ["tactical-celery-dev"]
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
@@ -174,9 +168,6 @@ services:
|
|||||||
celerybeat-dev:
|
celerybeat-dev:
|
||||||
container_name: trmm-celerybeat-dev
|
container_name: trmm-celerybeat-dev
|
||||||
image: api-dev
|
image: api-dev
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./api.dockerfile
|
|
||||||
command: ["tactical-celerybeat-dev"]
|
command: ["tactical-celerybeat-dev"]
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
@@ -192,9 +183,6 @@ services:
|
|||||||
websockets-dev:
|
websockets-dev:
|
||||||
container_name: trmm-websockets-dev
|
container_name: trmm-websockets-dev
|
||||||
image: api-dev
|
image: api-dev
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./api.dockerfile
|
|
||||||
command: ["tactical-websockets-dev"]
|
command: ["tactical-websockets-dev"]
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
@@ -234,9 +222,6 @@ services:
|
|||||||
container_name: trmm-mkdocs-dev
|
container_name: trmm-mkdocs-dev
|
||||||
image: api-dev
|
image: api-dev
|
||||||
restart: always
|
restart: always
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ./api.dockerfile
|
|
||||||
command: ["tactical-mkdocs-dev"]
|
command: ["tactical-mkdocs-dev"]
|
||||||
ports:
|
ports:
|
||||||
- "8005:8005"
|
- "8005:8005"
|
||||||
|
|||||||
@@ -644,7 +644,11 @@ def run_script(request):
|
|||||||
else:
|
else:
|
||||||
return notify_error("Custom Field was invalid")
|
return notify_error("Custom Field was invalid")
|
||||||
|
|
||||||
value = r if request.data["save_all_output"] else r.split("\n")[-1].strip()
|
value = (
|
||||||
|
r.strip()
|
||||||
|
if request.data["save_all_output"]
|
||||||
|
else r.strip().split("\n")[-1].strip()
|
||||||
|
)
|
||||||
|
|
||||||
field.save_to_field(value)
|
field.save_to_field(value)
|
||||||
return Response(r)
|
return Response(r)
|
||||||
|
|||||||
@@ -361,7 +361,6 @@ class TaskRunner(APIView):
|
|||||||
|
|
||||||
def patch(self, request, pk, agentid):
|
def patch(self, request, pk, agentid):
|
||||||
from alerts.models import Alert
|
from alerts.models import Alert
|
||||||
from logs.models import AuditLog
|
|
||||||
|
|
||||||
agent = get_object_or_404(Agent, agent_id=agentid)
|
agent = get_object_or_404(Agent, agent_id=agentid)
|
||||||
task = get_object_or_404(AutomatedTask, pk=pk)
|
task = get_object_or_404(AutomatedTask, pk=pk)
|
||||||
|
|||||||
@@ -413,9 +413,9 @@ class AutomatedTask(BaseAuditModel):
|
|||||||
agent_field = self.custom_field.get_or_create_field_value(self.agent)
|
agent_field = self.custom_field.get_or_create_field_value(self.agent)
|
||||||
|
|
||||||
value = (
|
value = (
|
||||||
self.stdout
|
self.stdout.strip()
|
||||||
if self.collector_all_output
|
if self.collector_all_output
|
||||||
else self.stdout.split("\n")[-1].strip()
|
else self.stdout.strip().split("\n")[-1].strip()
|
||||||
)
|
)
|
||||||
agent_field.save_to_field(value)
|
agent_field.save_to_field(value)
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class TestScript(APIView):
|
|||||||
agent = get_object_or_404(Agent, pk=request.data["agent"])
|
agent = get_object_or_404(Agent, pk=request.data["agent"])
|
||||||
|
|
||||||
parsed_args = Script.parse_script_args(
|
parsed_args = Script.parse_script_args(
|
||||||
self, request.data["shell"], request.data["args"]
|
agent, request.data["shell"], request.data["args"]
|
||||||
)
|
)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ 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.8.0"
|
TRMM_VERSION = "0.8.2"
|
||||||
|
|
||||||
# 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.142"
|
APP_VER = "0.0.144"
|
||||||
|
|
||||||
# https://github.com/wh1te909/rmmagent
|
# https://github.com/wh1te909/rmmagent
|
||||||
LATEST_AGENT_VER = "1.6.0"
|
LATEST_AGENT_VER = "1.6.1"
|
||||||
|
|
||||||
MESH_VER = "0.9.15"
|
MESH_VER = "0.9.16"
|
||||||
|
|
||||||
NATS_SERVER_VER = "2.3.3"
|
NATS_SERVER_VER = "2.3.3"
|
||||||
|
|
||||||
|
|||||||
@@ -265,7 +265,9 @@ def run_nats_api_cmd(mode: str, ids: list[str] = [], timeout: int = 30) -> None:
|
|||||||
"dbname": db["NAME"],
|
"dbname": db["NAME"],
|
||||||
}
|
}
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile() as fp:
|
with tempfile.NamedTemporaryFile(
|
||||||
|
dir="/opt/tactical/tmp" if settings.DOCKER_BUILD else None
|
||||||
|
) as fp:
|
||||||
with open(fp.name, "w") as f:
|
with open(fp.name, "w") as f:
|
||||||
json.dump(config, f)
|
json.dump(config, f)
|
||||||
|
|
||||||
|
|||||||
@@ -479,7 +479,8 @@ export default {
|
|||||||
if (filter === "actionspending") actions = true;
|
if (filter === "actionspending") actions = true;
|
||||||
else if (filter === "checksfailing") checks = true;
|
else if (filter === "checksfailing") checks = true;
|
||||||
else if (filter === "rebootneeded") reboot = true;
|
else if (filter === "rebootneeded") reboot = true;
|
||||||
else if (filter === "online" || filter === "offline" || filter === "expired") availability = filter;
|
else if (filter === "online" || filter === "offline" || filter === "expired" || filter === "overdue")
|
||||||
|
availability = filter;
|
||||||
} else {
|
} else {
|
||||||
search = param + "";
|
search = param + "";
|
||||||
}
|
}
|
||||||
@@ -492,7 +493,8 @@ export default {
|
|||||||
if (actions && row.pending_actions_count === 0) return false;
|
if (actions && row.pending_actions_count === 0) return false;
|
||||||
if (reboot && !row.needs_reboot) return false;
|
if (reboot && !row.needs_reboot) return false;
|
||||||
if (availability === "online" && row.status !== "online") return false;
|
if (availability === "online" && row.status !== "online") return false;
|
||||||
else if (availability === "offline" && row.status !== "overdue") return false;
|
else if (availability === "offline" && row.status !== "offline") return false;
|
||||||
|
else if (availability === "overdue" && row.status !== "overdue") return false;
|
||||||
else if (availability === "expired") {
|
else if (availability === "expired") {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
let lastSeen = date.extractDate(row.last_seen, "MM DD YYYY HH:mm");
|
let lastSeen = date.extractDate(row.last_seen, "MM DD YYYY HH:mm");
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ export default {
|
|||||||
// script form logic
|
// script form logic
|
||||||
const script = props.script
|
const script = props.script
|
||||||
? ref(Object.assign({}, props.script))
|
? ref(Object.assign({}, props.script))
|
||||||
: ref({ shell: "powershell", default_timeout: 90 });
|
: ref({ shell: "powershell", default_timeout: 90, args: [] });
|
||||||
|
|
||||||
if (props.clone) script.value.name = `(Copy) ${script.value.name}`;
|
if (props.clone) script.value.name = `(Copy) ${script.value.name}`;
|
||||||
const code = ref("");
|
const code = ref("");
|
||||||
|
|||||||
@@ -337,6 +337,16 @@
|
|||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
||||||
|
<q-item>
|
||||||
|
<q-item-section side>
|
||||||
|
<q-radio val="overdue" v-model="filterAvailability" />
|
||||||
|
</q-item-section>
|
||||||
|
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>Show Overdue Only</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
<q-item>
|
<q-item>
|
||||||
<q-item-section side>
|
<q-item-section side>
|
||||||
<q-radio val="offline_30days" v-model="filterAvailability" />
|
<q-radio val="offline_30days" v-model="filterAvailability" />
|
||||||
@@ -809,7 +819,10 @@ export default {
|
|||||||
// clear search if availability changes to all
|
// clear search if availability changes to all
|
||||||
if (
|
if (
|
||||||
this.filterAvailability === "all" &&
|
this.filterAvailability === "all" &&
|
||||||
(this.search.includes("is:online") || this.search.includes("is:offline") || this.search.includes("is:expired"))
|
(this.search.includes("is:online") ||
|
||||||
|
this.search.includes("is:offline") ||
|
||||||
|
this.search.includes("is:expired") ||
|
||||||
|
this.search.includes("is:overdue"))
|
||||||
)
|
)
|
||||||
this.clearFilter();
|
this.clearFilter();
|
||||||
|
|
||||||
@@ -841,6 +854,8 @@ export default {
|
|||||||
filterText += "is:offline ";
|
filterText += "is:offline ";
|
||||||
} else if (this.filterAvailability === "offline_30days") {
|
} else if (this.filterAvailability === "offline_30days") {
|
||||||
filterText += "is:expired ";
|
filterText += "is:expired ";
|
||||||
|
} else if (this.filterAvailability === "overdue") {
|
||||||
|
filterText += "is:overdue ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user