handle deployment config updates

This commit is contained in:
wh1te909
2024-10-31 19:06:39 +00:00
parent a6166a1ad7
commit ec0a2dc053
11 changed files with 102 additions and 47 deletions

View File

@@ -50,7 +50,7 @@ function django_setup {
DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1)
BASE_DOMAIN=$(echo "$APP_HOST" | awk -F. '{print $(NF-1)"."$NF}') BASE_DOMAIN=$(echo "import tldextract; no_fetch_extract = tldextract.TLDExtract(suffix_list_urls=()); extracted = no_fetch_extract('${API_HOST}'); print(f'{extracted.domain}.{extracted.suffix}')" | python)
localvars="$( localvars="$(
cat <<EOF cat <<EOF
@@ -72,15 +72,12 @@ ADMIN_URL = 'admin/'
ALLOWED_HOSTS = ['${API_HOST}', '${APP_HOST}', '*'] ALLOWED_HOSTS = ['${API_HOST}', '${APP_HOST}', '*']
CORS_ORIGIN_WHITELIST = ['https://${APP_HOST}'] CORS_ORIGIN_WHITELIST = ['https://${APP_HOST}']
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_DOMAIN = '${BASE_DOMAIN}' SESSION_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${BASE_DOMAIN}' CSRF_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ['https://${API_HOST}', 'https://${APP_HOST}'] CSRF_TRUSTED_ORIGINS = ['https://${API_HOST}', 'https://${APP_HOST}']
HEADLESS_FRONTEND_URLS = { HEADLESS_FRONTEND_URLS = {'socialaccount_login_error': 'https://${APP_HOST}/account/provider/callback'}
'socialaccount_login_error': 'https://${APP_HOST}/account/provider/callback'
}
DATABASES = { DATABASES = {
'default': { 'default': {

View File

@@ -17,6 +17,12 @@ class Command(BaseCommand):
match kwargs["name"]: match kwargs["name"]:
case "api": case "api":
self.stdout.write(settings.ALLOWED_HOSTS[0]) self.stdout.write(settings.ALLOWED_HOSTS[0])
case "rootdomain":
import tldextract
no_fetch_extract = tldextract.TLDExtract(suffix_list_urls=())
extracted = no_fetch_extract(settings.ALLOWED_HOSTS[0])
self.stdout.write(f"{extracted.domain}.{extracted.suffix}")
case "version": case "version":
self.stdout.write(settings.TRMM_VERSION) self.stdout.write(settings.TRMM_VERSION)
case "webversion": case "webversion":

View File

@@ -1,5 +1,9 @@
import base64 import base64
import os
import shutil
from pathlib import Path
from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from accounts.models import User from accounts.models import User
@@ -10,6 +14,7 @@ from core.models import CoreSettings
from core.tasks import remove_orphaned_history_results, sync_mesh_perms_task from core.tasks import remove_orphaned_history_results, sync_mesh_perms_task
from scripts.models import Script from scripts.models import Script
from tacticalrmm.constants import AGENT_DEFER, ScriptType from tacticalrmm.constants import AGENT_DEFER, ScriptType
from tacticalrmm.helpers import get_webdomain
class Command(BaseCommand): class Command(BaseCommand):
@@ -18,6 +23,37 @@ class Command(BaseCommand):
def handle(self, *args, **kwargs) -> None: def handle(self, *args, **kwargs) -> None:
self.stdout.write("Running post update tasks") self.stdout.write("Running post update tasks")
# for 0.20.0 release
if not settings.DOCKER_BUILD:
needs_frontend = False
frontend_domain = get_webdomain().split(":")[0]
local_settings = os.path.join(
settings.BASE_DIR, "tacticalrmm", "local_settings.py"
)
with open(local_settings) as f:
lines = f.readlines()
modified_lines = []
for line in lines:
if line.strip().startswith("ALLOWED_HOSTS"):
exec(line, globals())
if frontend_domain not in settings.ALLOWED_HOSTS:
needs_frontend = True
settings.ALLOWED_HOSTS.append(frontend_domain)
line = f"ALLOWED_HOSTS = {settings.ALLOWED_HOSTS}\n"
modified_lines.append(line)
if needs_frontend:
backup = Path.home() / (Path("local_settings_0.20.0.bak"))
shutil.copy2(local_settings, backup)
with open(local_settings, "w") as f:
f.writelines(modified_lines)
# load community scripts into the db # load community scripts into the db
Script.load_community_scripts() Script.load_community_scripts()

View File

@@ -5,10 +5,8 @@ For details, see: https://license.tacticalrmm.com/ee
""" """
import urllib.parse import urllib.parse
from time import sleep
from typing import Any, Optional from typing import Any, Optional
import requests
from core.models import CodeSignToken from core.models import CodeSignToken
from django.conf import settings from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
@@ -26,39 +24,12 @@ class Command(BaseCommand):
self.stdout.write(url) self.stdout.write(url)
return return
attempts = 0 if t.is_valid:
while 1:
try:
r = requests.post(
settings.REPORTING_CHECK_URL,
json={"token": t.token, "api": settings.ALLOWED_HOSTS[0]},
headers={"Content-type": "application/json"},
timeout=15,
)
except Exception as e:
self.stderr.write(str(e))
attempts += 1
sleep(3)
else:
if r.status_code // 100 in (3, 5):
self.stderr.write(f"Error getting web tarball: {r.status_code}")
attempts += 1
sleep(3)
else:
attempts = 0
if attempts == 0:
break
elif attempts > 5:
self.stdout.write(url)
return
if r.status_code == 200: # type: ignore
params = { params = {
"token": t.token, "token": t.token,
"webver": settings.WEB_VERSION, "webver": settings.WEB_VERSION,
"api": settings.ALLOWED_HOSTS[0], "api": settings.ALLOWED_HOSTS[0],
} }
url = settings.REPORTING_DL_URL + urllib.parse.urlencode(params) url = settings.WEBTAR_DL_URL + urllib.parse.urlencode(params)
self.stdout.write(url) self.stdout.write(url)

View File

@@ -16,3 +16,4 @@ SOCIALACCOUNT_EMAIL_VERIFICATION = True
SOCIALACCOUNT_PROVIDERS = {"openid_connect": {"OAUTH_PKCE_ENABLED": True}} SOCIALACCOUNT_PROVIDERS = {"openid_connect": {"OAUTH_PKCE_ENABLED": True}}
SESSION_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
CORS_ALLOW_CREDENTIALS = True

View File

@@ -30,6 +30,7 @@ redis==5.0.8
requests==2.32.3 requests==2.32.3
six==1.16.0 six==1.16.0
sqlparse==0.5.1 sqlparse==0.5.1
tldextract==5.1.2
twilio==8.13.0 twilio==8.13.0
urllib3==2.2.3 urllib3==2.2.3
uvicorn[standard]==0.31.1 uvicorn[standard]==0.31.1

View File

@@ -126,8 +126,7 @@ with suppress(ImportError):
CHECK_TOKEN_URL = f"{AGENT_BASE_URL}/api/v2/checktoken" CHECK_TOKEN_URL = f"{AGENT_BASE_URL}/api/v2/checktoken"
AGENTS_URL = f"{AGENT_BASE_URL}/api/v2/agents/?" AGENTS_URL = f"{AGENT_BASE_URL}/api/v2/agents/?"
EXE_GEN_URL = f"{AGENT_BASE_URL}/api/v2/exe" EXE_GEN_URL = f"{AGENT_BASE_URL}/api/v2/exe"
REPORTING_CHECK_URL = f"{AGENT_BASE_URL}/api/v2/reporting/check" WEBTAR_DL_URL = f"{AGENT_BASE_URL}/api/v2/webtar/?"
REPORTING_DL_URL = f"{AGENT_BASE_URL}/api/v2/reporting/download/?"
if "GHACTIONS" in os.environ: if "GHACTIONS" in os.environ:
DEBUG = False DEBUG = False

View File

@@ -71,6 +71,7 @@ if [ "$1" = 'tactical-init' ]; then
MESH_TOKEN=$(cat ${TACTICAL_DIR}/tmp/mesh_token) MESH_TOKEN=$(cat ${TACTICAL_DIR}/tmp/mesh_token)
ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1) ADMINURL=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 70 | head -n 1)
DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1) DJANGO_SEKRET=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1)
BASE_DOMAIN=$(echo "import tldextract; no_fetch_extract = tldextract.TLDExtract(suffix_list_urls=()); extracted = no_fetch_extract('${API_HOST}'); print(f'{extracted.domain}.{extracted.suffix}')" | python)
localvars="$( localvars="$(
cat <<EOF cat <<EOF
@@ -93,15 +94,12 @@ ALLOWED_HOSTS = ['${API_HOST}', '${APP_HOST}', 'tactical-backend']
ADMIN_URL = '${ADMINURL}/' ADMIN_URL = '${ADMINURL}/'
CORS_ORIGIN_WHITELIST = ['https://${APP_HOST}'] CORS_ORIGIN_WHITELIST = ['https://${APP_HOST}']
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_DOMAIN = '${BASE_DOMAIN}' SESSION_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${BASE_DOMAIN}' CSRF_COOKIE_DOMAIN = '${BASE_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ['https://${API_HOST}', 'https://${APP_HOST}'] CSRF_TRUSTED_ORIGINS = ['https://${API_HOST}', 'https://${APP_HOST}']
HEADLESS_FRONTEND_URLS = { HEADLESS_FRONTEND_URLS = {'socialaccount_login_error': 'https://${APP_HOST}/account/provider/callback'}
'socialaccount_login_error': 'https://${APP_HOST}/account/provider/callback'
}
DATABASES = { DATABASES = {
'default': { 'default': {

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
SCRIPT_VERSION="86" SCRIPT_VERSION="87"
SCRIPT_URL="https://raw.githubusercontent.com/amidaware/tacticalrmm/master/install.sh" SCRIPT_URL="https://raw.githubusercontent.com/amidaware/tacticalrmm/master/install.sh"
sudo apt install -y curl wget dirmngr gnupg lsb-release ca-certificates sudo apt install -y curl wget dirmngr gnupg lsb-release ca-certificates
@@ -570,6 +570,7 @@ python manage.py load_chocos
python manage.py load_community_scripts python manage.py load_community_scripts
WEB_VERSION=$(python manage.py get_config webversion) WEB_VERSION=$(python manage.py get_config webversion)
WEBTAR_URL=$(python manage.py get_webtar_url) WEBTAR_URL=$(python manage.py get_webtar_url)
ROOT_DOMAIN=$(python manage.py get_config rootdomain)
printf >&2 "${YELLOW}%0.s*${NC}" {1..80} printf >&2 "${YELLOW}%0.s*${NC}" {1..80}
printf >&2 "\n" printf >&2 "\n"
printf >&2 "${YELLOW}Please create your login for the RMM website${NC}\n" printf >&2 "${YELLOW}Please create your login for the RMM website${NC}\n"
@@ -585,6 +586,16 @@ python manage.py generate_barcode ${RANDBASE} ${djangousername} ${frontenddomain
deactivate deactivate
read -n 1 -s -r -p "Press any key to continue..." read -n 1 -s -r -p "Press any key to continue..."
allauth="$(
cat <<EOF
SESSION_COOKIE_DOMAIN = '${ROOT_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${ROOT_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ["https://${frontenddomain}", "https://${rmmdomain}"]
HEADLESS_FRONTEND_URLS = {"socialaccount_login_error": "https://${frontenddomain}/account/provider/callback"}
EOF
)"
echo "${allauth}" | tee --append $local_settings >/dev/null
rmmservice="$( rmmservice="$(
cat <<EOF cat <<EOF
[Unit] [Unit]

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
SCRIPT_VERSION="60" SCRIPT_VERSION="61"
SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/restore.sh' SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/restore.sh'
sudo apt update sudo apt update
@@ -15,6 +15,7 @@ NC='\033[0m'
SCRIPTS_DIR='/opt/trmm-community-scripts' SCRIPTS_DIR='/opt/trmm-community-scripts'
PYTHON_VER='3.11.8' PYTHON_VER='3.11.8'
SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py' SETTINGS_FILE='/rmm/api/tacticalrmm/tacticalrmm/settings.py'
local_settings='/rmm/api/tacticalrmm/tacticalrmm/local_settings.py'
TMP_FILE=$(mktemp -p "" "rmmrestore_XXXXXXXXXX") TMP_FILE=$(mktemp -p "" "rmmrestore_XXXXXXXXXX")
curl -s -L "${SCRIPT_URL}" >${TMP_FILE} curl -s -L "${SCRIPT_URL}" >${TMP_FILE}
@@ -445,8 +446,8 @@ sudo chmod +x /usr/local/bin/nats-api
print_green 'Restoring the trmm database' print_green 'Restoring the trmm database'
pgusername=$(grep -w USER /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') pgusername=$(grep -w USER $local_settings | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//')
pgpw=$(grep -w PASSWORD /rmm/api/tacticalrmm/tacticalrmm/local_settings.py | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//') pgpw=$(grep -w PASSWORD $local_settings | sed 's/^.*: //' | sed 's/.//' | sed -r 's/.{2}$//')
sudo -iu postgres psql -c "CREATE DATABASE tacticalrmm" sudo -iu postgres psql -c "CREATE DATABASE tacticalrmm"
sudo -iu postgres psql -c "CREATE USER ${pgusername} WITH PASSWORD '${pgpw}'" sudo -iu postgres psql -c "CREATE USER ${pgusername} WITH PASSWORD '${pgpw}'"
@@ -500,6 +501,23 @@ CERT_PUB_KEY=$(python manage.py get_config certfile)
CERT_PRIV_KEY=$(python manage.py get_config keyfile) CERT_PRIV_KEY=$(python manage.py get_config keyfile)
deactivate deactivate
HAS_ALLAUTH=$(grep HEADLESS_FRONTEND_URLS $local_settings)
if ! [[ $HAS_ALLAUTH ]]; then
source /rmm/api/env/bin/activate
cd /rmm/api/tacticalrmm
ROOT_DOMAIN=$(python manage.py get_config rootdomain)
deactivate
allauth="$(
cat <<EOF
SESSION_COOKIE_DOMAIN = '${ROOT_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${ROOT_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ["https://${FRONTEND}", "https://${API}"]
HEADLESS_FRONTEND_URLS = {"socialaccount_login_error": "https://${FRONTEND}/account/provider/callback"}
EOF
)"
echo "${allauth}" | tee --append $local_settings >/dev/null
fi
print_green 'Restoring hosts file' print_green 'Restoring hosts file'
if grep -q manage_etc_hosts /etc/hosts; then if grep -q manage_etc_hosts /etc/hosts; then

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
SCRIPT_VERSION="154" SCRIPT_VERSION="155"
SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/update.sh' SCRIPT_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/update.sh'
LATEST_SETTINGS_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/api/tacticalrmm/tacticalrmm/settings.py' LATEST_SETTINGS_URL='https://raw.githubusercontent.com/amidaware/tacticalrmm/master/api/tacticalrmm/tacticalrmm/settings.py'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
@@ -452,6 +452,23 @@ CERT_PUB_KEY=$(python manage.py get_config certfile)
CERT_PRIV_KEY=$(python manage.py get_config keyfile) CERT_PRIV_KEY=$(python manage.py get_config keyfile)
deactivate deactivate
HAS_ALLAUTH=$(grep HEADLESS_FRONTEND_URLS $local_settings)
if ! [[ $HAS_ALLAUTH ]]; then
source /rmm/api/env/bin/activate
cd /rmm/api/tacticalrmm
ROOT_DOMAIN=$(python manage.py get_config rootdomain)
deactivate
allauth="$(
cat <<EOF
SESSION_COOKIE_DOMAIN = '${ROOT_DOMAIN}'
CSRF_COOKIE_DOMAIN = '${ROOT_DOMAIN}'
CSRF_TRUSTED_ORIGINS = ["https://${FRONTEND}", "https://${API}"]
HEADLESS_FRONTEND_URLS = {"socialaccount_login_error": "https://${FRONTEND}/account/provider/callback"}
EOF
)"
echo "${allauth}" | tee --append $local_settings >/dev/null
fi
if grep -q manage_etc_hosts /etc/hosts; then if grep -q manage_etc_hosts /etc/hosts; then
sudo sed -i '/manage_etc_hosts: true/d' /etc/cloud/cloud.cfg >/dev/null sudo sed -i '/manage_etc_hosts: true/d' /etc/cloud/cloud.cfg >/dev/null
if ! grep -q "manage_etc_hosts: false" /etc/cloud/cloud.cfg; then if ! grep -q "manage_etc_hosts: false" /etc/cloud/cloud.cfg; then