mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'dev' into refactor/rework-css
This commit is contained in:
commit
252b37ad53
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,7 +1,20 @@
|
||||
# Changelog
|
||||
## --- [4.2.4] - 2023/TBD
|
||||
## --- [4.3.1] - 2023/TBD
|
||||
### New features
|
||||
TBD
|
||||
### Bug fixes
|
||||
TBD
|
||||
### Tweaks
|
||||
TBD
|
||||
### Lang
|
||||
TBD
|
||||
<br><br>
|
||||
|
||||
## --- [4.3.0] - 2023/03/09
|
||||
### Breaking Changes
|
||||
- This release includes database migrations that are not revertable. Once you update to this version you will not be able to rollback to a previous version.
|
||||
- In this release, we've implemented a breaking change to enhance server identification within Crafty: instead of relying on numerical integers (1, 2, 3, etc.), Servers are now uniquely identified by their UUIDs. Please adapt your API clients accordingly.
|
||||
|
||||
### Refactor
|
||||
- Refactor remote file downloads ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/719))
|
||||
### Bug fixes
|
||||
@ -10,9 +23,10 @@ TBD
|
||||
- Do not allow users at server limit to clone servers ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/718))
|
||||
- Fix bug where you cannot get to config with unloaded server ([Commit](https://gitlab.com/crafty-controller/crafty-4/-/commit/9de08973b6bb2ddf91283c5c6b0e189ff34f7e24))
|
||||
- Fix forge install v1.20, 1.20.1 and 1.20.2 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/710))
|
||||
- Fix Sanitisation on Passwords ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/715))
|
||||
- Fix Sanitisation on Passwords ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/715) | [Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/725))
|
||||
- Fix `Upload Imports` on unix systems, that have a space in the root dir name ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/722))
|
||||
- Fix Bedrock downloads, add `www` to download URL ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/723))
|
||||
- Fire backup webhook 'after' backup has finished ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/727))
|
||||
### Tweaks
|
||||
- Bump pyOpenSSL & cryptography for CVE-2024-0727, CVE-2023-50782 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/716))
|
||||
- Bump cryptography for CVE-2024-26130 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/724))
|
||||
|
@ -1,5 +1,5 @@
|
||||
[![Crafty Logo](app/frontend/static/assets/images/logo_long.svg)](https://craftycontrol.com)
|
||||
# Crafty Controller 4.2.4
|
||||
# Crafty Controller 4.3.1
|
||||
> Python based Control Panel for your Minecraft Server
|
||||
|
||||
## What is Crafty Controller?
|
||||
|
@ -80,8 +80,8 @@ class ServersController(metaclass=Singleton):
|
||||
PeeweeException: If the server already exists
|
||||
"""
|
||||
return HelperServers.create_server(
|
||||
name,
|
||||
server_uuid,
|
||||
name,
|
||||
server_dir,
|
||||
backup_path,
|
||||
server_command,
|
||||
@ -161,9 +161,9 @@ class ServersController(metaclass=Singleton):
|
||||
# Servers Methods
|
||||
# **********************************************************************************
|
||||
|
||||
def get_server_instance_by_id(self, server_id: t.Union[str, int]) -> ServerInstance:
|
||||
def get_server_instance_by_id(self, server_id: t.Union[str, str]) -> ServerInstance:
|
||||
for server in self.servers_list:
|
||||
if int(server["server_id"]) == int(server_id):
|
||||
if server["server_id"] == server_id:
|
||||
return server["server_obj"]
|
||||
|
||||
logger.warning(f"Unable to find server object for server id {server_id}")
|
||||
|
@ -31,9 +31,9 @@ class AuditLog(BaseModel):
|
||||
user_name = CharField(default="")
|
||||
user_id = IntegerField(default=0, index=True)
|
||||
source_ip = CharField(default="127.0.0.1")
|
||||
server_id = IntegerField(
|
||||
default=None, index=True
|
||||
) # When auditing global events, use server ID 0
|
||||
server_id = ForeignKeyField(
|
||||
Servers, backref="audit_server", null=True
|
||||
) # When auditing global events, use server ID null
|
||||
log_msg = TextField(default="")
|
||||
|
||||
class Meta:
|
||||
@ -79,7 +79,7 @@ class HostStats(BaseModel):
|
||||
# **********************************************************************************
|
||||
class Webhooks(BaseModel):
|
||||
id = AutoField()
|
||||
server_id = IntegerField(null=True)
|
||||
server_id = ForeignKeyField(Servers, backref="webhook_server", null=True)
|
||||
name = CharField(default="Custom Webhook", max_length=64)
|
||||
url = CharField(default="")
|
||||
webhook_type = CharField(default="Custom")
|
||||
@ -337,7 +337,7 @@ class HelpersManagement:
|
||||
|
||||
@staticmethod
|
||||
def delete_scheduled_task_by_server(server_id):
|
||||
Schedules.delete().where(Schedules.server_id == int(server_id)).execute()
|
||||
Schedules.delete().where(Schedules.server_id == server_id).execute()
|
||||
|
||||
@staticmethod
|
||||
def get_scheduled_task(schedule_id):
|
||||
|
@ -71,7 +71,7 @@ class HelperServerStats:
|
||||
database = None
|
||||
|
||||
def __init__(self, server_id):
|
||||
self.server_id = int(server_id)
|
||||
self.server_id = server_id
|
||||
self.init_database(self.server_id)
|
||||
|
||||
def init_database(self, server_id):
|
||||
|
@ -3,7 +3,6 @@ import datetime
|
||||
import typing as t
|
||||
from peewee import (
|
||||
CharField,
|
||||
AutoField,
|
||||
DateTimeField,
|
||||
BooleanField,
|
||||
IntegerField,
|
||||
@ -13,6 +12,9 @@ from playhouse.shortcuts import model_to_dict
|
||||
from app.classes.shared.main_models import DatabaseShortcuts
|
||||
from app.classes.models.base_model import BaseModel
|
||||
|
||||
# from app.classes.models.users import Users
|
||||
from app.classes.shared.helpers import Helpers
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -20,9 +22,8 @@ logger = logging.getLogger(__name__)
|
||||
# Servers Model
|
||||
# **********************************************************************************
|
||||
class Servers(BaseModel):
|
||||
server_id = AutoField()
|
||||
server_id = CharField(primary_key=True, default=Helpers.create_uuid())
|
||||
created = DateTimeField(default=datetime.datetime.now)
|
||||
server_uuid = CharField(default="", index=True)
|
||||
server_name = CharField(default="Server", index=True)
|
||||
path = CharField(default="")
|
||||
backup_path = CharField(default="")
|
||||
@ -40,6 +41,7 @@ class Servers(BaseModel):
|
||||
type = CharField(default="minecraft-java")
|
||||
show_status = BooleanField(default=1)
|
||||
created_by = IntegerField(default=-100)
|
||||
# created_by = ForeignKeyField(Users, backref="creator_server", null=True)
|
||||
shutdown_timeout = IntegerField(default=60)
|
||||
ignored_exits = CharField(default="0")
|
||||
count_players = BooleanField(default=True)
|
||||
@ -60,8 +62,8 @@ class HelperServers:
|
||||
# **********************************************************************************
|
||||
@staticmethod
|
||||
def create_server(
|
||||
server_id: str,
|
||||
name: str,
|
||||
server_uuid: str,
|
||||
server_dir: str,
|
||||
backup_path: str,
|
||||
server_command: str,
|
||||
@ -95,25 +97,24 @@ class HelperServers:
|
||||
Raises:
|
||||
PeeweeException: If the server already exists
|
||||
"""
|
||||
return Servers.insert(
|
||||
{
|
||||
Servers.server_name: name,
|
||||
Servers.server_uuid: server_uuid,
|
||||
Servers.path: server_dir,
|
||||
Servers.executable: server_file,
|
||||
Servers.execution_command: server_command,
|
||||
Servers.auto_start: False,
|
||||
Servers.auto_start_delay: 10,
|
||||
Servers.crash_detection: False,
|
||||
Servers.log_path: server_log_file,
|
||||
Servers.server_port: server_port,
|
||||
Servers.server_ip: server_host,
|
||||
Servers.stop_command: server_stop,
|
||||
Servers.backup_path: backup_path,
|
||||
Servers.type: server_type,
|
||||
Servers.created_by: created_by,
|
||||
}
|
||||
).execute()
|
||||
return Servers.create(
|
||||
server_id=server_id,
|
||||
server_uuid=server_id,
|
||||
server_name=name,
|
||||
path=server_dir,
|
||||
executable=server_file,
|
||||
execution_command=server_command,
|
||||
auto_start=False,
|
||||
auto_start_delay=10,
|
||||
crash_detection=False,
|
||||
log_path=server_log_file,
|
||||
server_port=server_port,
|
||||
server_ip=server_host,
|
||||
stop_command=server_stop,
|
||||
backup_path=backup_path,
|
||||
type=server_type,
|
||||
created_by=created_by,
|
||||
).server_id
|
||||
|
||||
@staticmethod
|
||||
def get_server_obj(server_id):
|
||||
|
@ -18,7 +18,12 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class MainPrompt(cmd.Cmd):
|
||||
def __init__(
|
||||
self, helper, tasks_manager, migration_manager, main_controller, import3
|
||||
self,
|
||||
helper,
|
||||
tasks_manager,
|
||||
migration_manager,
|
||||
main_controller,
|
||||
import3,
|
||||
):
|
||||
super().__init__()
|
||||
self.helper: Helpers = helper
|
||||
|
@ -239,7 +239,7 @@ class Controller:
|
||||
try:
|
||||
os.mkdir(final_path)
|
||||
except FileExistsError:
|
||||
final_path += "_" + server["server_uuid"]
|
||||
final_path += "_" + server["server_id"]
|
||||
os.mkdir(final_path)
|
||||
try:
|
||||
FileHelpers.copy_file(
|
||||
@ -632,11 +632,11 @@ class Controller:
|
||||
# and add the user to it if he's not a superuser
|
||||
if len(captured_roles) == 0:
|
||||
if not exec_user["superuser"]:
|
||||
new_server_uuid = self.servers.get_server_data_by_id(new_server_id).get(
|
||||
"server_uuid"
|
||||
new_server_id = self.servers.get_server_data_by_id(new_server_id).get(
|
||||
"server_id"
|
||||
)
|
||||
role_id = self.roles.add_role(
|
||||
f"Creator of Server with uuid={new_server_uuid}",
|
||||
f"Creator of Server with id={new_server_id}",
|
||||
exec_user["user_id"],
|
||||
)
|
||||
self.server_perms.add_role_server(new_server_id, role_id, "11111111")
|
||||
@ -647,7 +647,7 @@ class Controller:
|
||||
role_id = role
|
||||
self.server_perms.add_role_server(new_server_id, role_id, "11111111")
|
||||
|
||||
return new_server_id, server_fs_uuid
|
||||
return new_server_id
|
||||
|
||||
@staticmethod
|
||||
def verify_jar_server(server_path: str, server_jar: str):
|
||||
@ -1095,7 +1095,7 @@ class Controller:
|
||||
for server in servers:
|
||||
server_path = server.get("path")
|
||||
new_local_server_path = os.path.join(
|
||||
new_server_path, server.get("server_uuid")
|
||||
new_server_path, server.get("server_id")
|
||||
)
|
||||
if os.path.isdir(server_path):
|
||||
WebSocketManager().broadcast_page(
|
||||
|
@ -200,6 +200,21 @@ class Migrator(object):
|
||||
)
|
||||
return model
|
||||
|
||||
@get_model
|
||||
def alter_column_type(
|
||||
self,
|
||||
model: peewee.Model,
|
||||
column_name: str,
|
||||
field: peewee.Field,
|
||||
) -> peewee.Model:
|
||||
"""
|
||||
Alter field data type in database.
|
||||
"""
|
||||
self.operations.append(
|
||||
self.migrator.alter_column_type(model._meta.table_name, column_name, field)
|
||||
)
|
||||
return model
|
||||
|
||||
@get_model
|
||||
def rename_table(self, model: peewee.Model, new_name: str) -> peewee.Model:
|
||||
"""
|
||||
|
@ -208,7 +208,7 @@ class ServerInstance:
|
||||
self.dir_scheduler.start()
|
||||
self.start_dir_calc_task()
|
||||
self.backup_thread = threading.Thread(
|
||||
target=self.a_backup_server, daemon=True, name=f"backup_{self.name}"
|
||||
target=self.backup_server, daemon=True, name=f"backup_{self.name}"
|
||||
)
|
||||
self.is_backingup = False
|
||||
# Reset crash and update at initialization
|
||||
@ -1110,13 +1110,12 @@ class ServerInstance:
|
||||
f.write("eula=true")
|
||||
self.run_threaded_server(user_id)
|
||||
|
||||
@callback
|
||||
def backup_server(self):
|
||||
def a_backup_server(self):
|
||||
if self.settings["backup_path"] == "":
|
||||
logger.critical("Backup path is None. Canceling Backup!")
|
||||
return
|
||||
backup_thread = threading.Thread(
|
||||
target=self.a_backup_server, daemon=True, name=f"backup_{self.name}"
|
||||
target=self.backup_server, daemon=True, name=f"backup_{self.name}"
|
||||
)
|
||||
logger.info(
|
||||
f"Starting Backup Thread for server {self.settings['server_name']}."
|
||||
@ -1143,7 +1142,8 @@ class ServerInstance:
|
||||
return False
|
||||
logger.info(f"Backup Thread started for server {self.settings['server_name']}.")
|
||||
|
||||
def a_backup_server(self):
|
||||
@callback
|
||||
def backup_server(self):
|
||||
was_server_running = None
|
||||
logger.info(f"Starting server {self.name} (ID {self.server_id}) backup")
|
||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||
@ -1373,7 +1373,7 @@ class ServerInstance:
|
||||
def a_jar_update(self):
|
||||
server_users = PermissionsServers.get_server_user_list(self.server_id)
|
||||
was_started = "-1"
|
||||
self.backup_server()
|
||||
self.a_backup_server()
|
||||
# checks if server is running. Calls shutdown if it is running.
|
||||
if self.check_running():
|
||||
was_started = True
|
||||
|
@ -140,7 +140,7 @@ class TasksManager:
|
||||
)
|
||||
|
||||
elif command == "backup_server":
|
||||
svr.backup_server()
|
||||
svr.a_backup_server()
|
||||
|
||||
elif command == "update_executable":
|
||||
svr.jar_update()
|
||||
|
@ -174,7 +174,7 @@ class PanelHandler(BaseHandler):
|
||||
self.redirect("/panel/error?error=Invalid Server ID")
|
||||
return None
|
||||
for server in self.controller.servers.failed_servers:
|
||||
if int(server_id) == server["server_id"]:
|
||||
if server_id == server["server_id"]:
|
||||
self.failed_server = True
|
||||
return server_id
|
||||
# Does this server exist?
|
||||
@ -557,7 +557,7 @@ class PanelHandler(BaseHandler):
|
||||
"server_id": {
|
||||
"server_id": server_id,
|
||||
"server_name": server_temp_obj["server_name"],
|
||||
"server_uuid": server_temp_obj["server_uuid"],
|
||||
"server_uuid": server_temp_obj["server_id"],
|
||||
"path": server_temp_obj["path"],
|
||||
"log_path": server_temp_obj["log_path"],
|
||||
"executable": server_temp_obj["executable"],
|
||||
|
@ -208,92 +208,92 @@ def api_handlers(handler_args):
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/?",
|
||||
ApiServersServerIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/backups/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/backups/?",
|
||||
ApiServersServerBackupsIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/backups/backup/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/backups/backup/?",
|
||||
ApiServersServerBackupsBackupIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/files/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/files/?",
|
||||
ApiServersServerFilesIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/files/create/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/files/create/?",
|
||||
ApiServersServerFilesCreateHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/files/zip/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/files/zip/?",
|
||||
ApiServersServerFilesZipHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/tasks/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/tasks/?",
|
||||
ApiServersServerTasksIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/tasks/([0-9]+)/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/tasks/([0-9]+)/?",
|
||||
ApiServersServerTasksTaskIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/tasks/([0-9]+)/children/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/tasks/([0-9]+)/children/?",
|
||||
ApiServersServerTasksTaskChildrenHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/stats/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/stats/?",
|
||||
ApiServersServerStatsHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/history/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/history/?",
|
||||
ApiServersServerHistoryHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/webhook/([0-9]+)/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/webhook/([0-9]+)/?",
|
||||
ApiServersServerWebhooksManagementIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/webhook/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/webhook/?",
|
||||
ApiServersServerWebhooksIndexHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/action/([a-z_]+)/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/action/([a-z_]+)/?",
|
||||
ApiServersServerActionHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/logs/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/logs/?",
|
||||
ApiServersServerLogsHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/users/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/users/?",
|
||||
ApiServersServerUsersHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/public/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/public/?",
|
||||
ApiServersServerPublicHandler,
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/api/v2/servers/([0-9]+)/stdin/?",
|
||||
r"/api/v2/servers/([a-z0-9-]+)/stdin/?",
|
||||
ApiServersServerStdinHandler,
|
||||
handler_args,
|
||||
),
|
||||
|
@ -723,9 +723,7 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
405, {"status": "error", "error": "DATA CONSTRAINT FAILED"}
|
||||
)
|
||||
return
|
||||
new_server_id, new_server_uuid = self.controller.create_api_server(
|
||||
data, user["user_id"]
|
||||
)
|
||||
new_server_id = self.controller.create_api_server(data, user["user_id"])
|
||||
|
||||
self.controller.servers.stats.record_stats()
|
||||
|
||||
@ -734,7 +732,7 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
(
|
||||
f"created server {data['name']}"
|
||||
f" (ID: {new_server_id})"
|
||||
f" (UUID: {new_server_uuid})"
|
||||
f" (UUID: {new_server_id})"
|
||||
),
|
||||
server_id=new_server_id,
|
||||
source_ip=self.get_remote_ip(),
|
||||
@ -746,7 +744,7 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"new_server_id": str(new_server_id),
|
||||
"new_server_uuid": new_server_uuid,
|
||||
"new_server_uuid": new_server_id,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -3,7 +3,6 @@ import os
|
||||
from app.classes.models.server_permissions import EnumPermissionsServer
|
||||
from app.classes.models.servers import Servers
|
||||
from app.classes.shared.file_helpers import FileHelpers
|
||||
from app.classes.shared.helpers import Helpers
|
||||
from app.classes.web.base_api_handler import BaseApiHandler
|
||||
|
||||
|
||||
@ -68,10 +67,20 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
name_counter += 1
|
||||
new_server_name = server_data.get("server_name") + f" (Copy {name_counter})"
|
||||
|
||||
new_server_uuid = Helpers.create_uuid()
|
||||
while os.path.exists(os.path.join(self.helper.servers_dir, new_server_uuid)):
|
||||
new_server_uuid = Helpers.create_uuid()
|
||||
new_server_path = os.path.join(self.helper.servers_dir, new_server_uuid)
|
||||
new_server_id = self.controller.servers.create_server(
|
||||
new_server_name,
|
||||
None,
|
||||
"",
|
||||
None,
|
||||
server_data.get("executable"),
|
||||
None,
|
||||
server_data.get("stop_command"),
|
||||
server_data.get("type"),
|
||||
user_id,
|
||||
server_data.get("server_port"),
|
||||
)
|
||||
|
||||
new_server_path = os.path.join(self.helper.servers_dir, new_server_id)
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
user_id,
|
||||
@ -89,19 +98,12 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
self.helper.get_os_understandable_path(server_data.get("log_path"))
|
||||
)
|
||||
|
||||
new_server_id = self.controller.servers.create_server(
|
||||
new_server_name,
|
||||
new_server_uuid,
|
||||
new_server_path,
|
||||
"",
|
||||
new_server_command,
|
||||
server_data.get("executable"),
|
||||
new_server_log_file,
|
||||
server_data.get("stop_command"),
|
||||
server_data.get("type"),
|
||||
user_id,
|
||||
server_data.get("server_port"),
|
||||
)
|
||||
server: Servers = self.controller.servers.get_server_obj(new_server_id)
|
||||
server.path = new_server_path
|
||||
server.log_path = new_server_log_file
|
||||
server.execution_command = new_server_command
|
||||
self.controller.servers.update_server(server)
|
||||
|
||||
for role in self.controller.server_perms.get_server_roles(server_id):
|
||||
mask = self.controller.server_perms.get_permissions_mask(
|
||||
role.role_id, server_id
|
||||
|
@ -145,7 +145,7 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
new_server_id = new_server
|
||||
new_server = self.controller.servers.get_server_data(new_server)
|
||||
self.controller.rename_backup_dir(
|
||||
server_id, new_server_id, new_server["server_uuid"]
|
||||
server_id, new_server_id, new_server["server_id"]
|
||||
)
|
||||
# preserve current schedules
|
||||
for schedule in self.controller.management.get_schedules_by_server(
|
||||
|
@ -176,7 +176,7 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
self.tasks_manager.remove_all_server_tasks(server_id)
|
||||
failed = False
|
||||
for item in self.controller.servers.failed_servers[:]:
|
||||
if item["server_id"] == int(server_id):
|
||||
if item["server_id"] == server_id:
|
||||
self.controller.servers.failed_servers.remove(item)
|
||||
failed = True
|
||||
|
||||
|
@ -17,7 +17,7 @@ def metrics_handlers(handler_args):
|
||||
handler_args,
|
||||
),
|
||||
(
|
||||
r"/metrics/servers/([0-9]+)/?",
|
||||
r"/metrics/servers/([a-z0-9-]+)/?",
|
||||
ApiOpenMetricsServersHandler,
|
||||
handler_args,
|
||||
),
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"major": 4,
|
||||
"minor": 2,
|
||||
"sub": 4
|
||||
"minor": 3,
|
||||
"sub": 1
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -454,7 +454,7 @@
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
try {
|
||||
if ($('#backup_path').val() == '') {
|
||||
console.log('true')
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -235,7 +235,7 @@
|
||||
if (key != "start_time" && key != "cron_string" && key != "interval_type") {
|
||||
if (typeof value == "boolean") {
|
||||
return value
|
||||
}
|
||||
}
|
||||
console.log(key)
|
||||
if (key === "interval" && value === ""){
|
||||
return 0;
|
||||
@ -298,7 +298,7 @@
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#schedule_form").on("submit", async function (e) {
|
||||
@ -332,7 +332,7 @@
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'X-XSRFToken': token,
|
||||
"Content-Type": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: formDataJsonString,
|
||||
});
|
||||
@ -345,7 +345,7 @@
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
@ -161,7 +161,7 @@
|
||||
if (key != "start_time" && key != "cron_string" && key != "interval_type") {
|
||||
if (typeof value == "boolean") {
|
||||
return value
|
||||
}
|
||||
}
|
||||
console.log(key)
|
||||
if (key === "interval" && value === ""){
|
||||
return 0;
|
||||
@ -221,7 +221,7 @@
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#webhook_form").on("submit", async function (e) {
|
||||
@ -249,7 +249,7 @@
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'X-XSRFToken': token,
|
||||
"Content-Type": "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: formDataJsonString,
|
||||
});
|
||||
@ -262,15 +262,15 @@
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
function hexToDiscordInt(hexColor) {
|
||||
// Remove the hash at the start if it's there
|
||||
const sanitizedHex = hexColor.startsWith('#') ? hexColor.slice(1) : hexColor;
|
||||
|
||||
|
||||
// Convert the hex to an integer
|
||||
return parseInt(sanitizedHex, 16);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
{{ translate('serverDetails', 'serverDetails', data['lang']) }} - {{
|
||||
data['server_stats']['server_id']['server_name'] }}
|
||||
<br />
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_uuid'] }}</small>
|
||||
<small>UUID: {{ data['server_stats']['server_id']['server_id'] }}</small>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
244
app/migrations/20240216_rework_servers_uuid.py
Normal file
244
app/migrations/20240216_rework_servers_uuid.py
Normal file
@ -0,0 +1,244 @@
|
||||
import datetime
|
||||
import uuid
|
||||
import peewee
|
||||
import logging
|
||||
|
||||
from app.classes.shared.console import Console
|
||||
from app.classes.shared.migration import Migrator, MigrateHistory
|
||||
from app.classes.models.management import (
|
||||
AuditLog,
|
||||
Webhooks,
|
||||
Schedules,
|
||||
Backups,
|
||||
)
|
||||
from app.classes.models.server_permissions import RoleServers
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def migrate(migrator: Migrator, database, **kwargs):
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
db = database
|
||||
|
||||
# **********************************************************************************
|
||||
# Servers New Model from Old (easier to migrate without dunmping Database)
|
||||
# **********************************************************************************
|
||||
class Servers(peewee.Model):
|
||||
server_id = peewee.CharField(primary_key=True, default=str(uuid.uuid4()))
|
||||
created = peewee.DateTimeField(default=datetime.datetime.now)
|
||||
server_uuid = peewee.CharField(default="", index=True)
|
||||
server_name = peewee.CharField(default="Server", index=True)
|
||||
path = peewee.CharField(default="")
|
||||
backup_path = peewee.CharField(default="")
|
||||
executable = peewee.CharField(default="")
|
||||
log_path = peewee.CharField(default="")
|
||||
execution_command = peewee.CharField(default="")
|
||||
auto_start = peewee.BooleanField(default=0)
|
||||
auto_start_delay = peewee.IntegerField(default=10)
|
||||
crash_detection = peewee.BooleanField(default=0)
|
||||
stop_command = peewee.CharField(default="stop")
|
||||
executable_update_url = peewee.CharField(default="")
|
||||
server_ip = peewee.CharField(default="127.0.0.1")
|
||||
server_port = peewee.IntegerField(default=25565)
|
||||
logs_delete_after = peewee.IntegerField(default=0)
|
||||
type = peewee.CharField(default="minecraft-java")
|
||||
show_status = peewee.BooleanField(default=1)
|
||||
created_by = peewee.IntegerField(default=-100)
|
||||
shutdown_timeout = peewee.IntegerField(default=60)
|
||||
ignored_exits = peewee.CharField(default="0")
|
||||
|
||||
class Meta:
|
||||
table_name = "servers"
|
||||
database = db
|
||||
|
||||
try:
|
||||
logger.info("Migrating Data from Int to UUID (Type Change)")
|
||||
Console.info("Migrating Data from Int to UUID (Type Change)")
|
||||
|
||||
# Changes on Server Table
|
||||
migrator.alter_column_type(
|
||||
Servers,
|
||||
"server_id",
|
||||
peewee.CharField(primary_key=True, default=str(uuid.uuid4())),
|
||||
)
|
||||
|
||||
# Changes on Audit Log Table
|
||||
migrator.alter_column_type(
|
||||
AuditLog,
|
||||
"server_id",
|
||||
peewee.ForeignKeyField(
|
||||
Servers,
|
||||
backref="audit_server",
|
||||
null=True,
|
||||
field=peewee.CharField(primary_key=True, default=str(uuid.uuid4())),
|
||||
),
|
||||
)
|
||||
# Changes on Webhook Table
|
||||
migrator.alter_column_type(
|
||||
Webhooks,
|
||||
"server_id",
|
||||
peewee.ForeignKeyField(
|
||||
Servers,
|
||||
backref="webhook_server",
|
||||
null=True,
|
||||
field=peewee.CharField(primary_key=True, default=str(uuid.uuid4())),
|
||||
),
|
||||
)
|
||||
|
||||
migrator.run()
|
||||
|
||||
logger.info("Migrating Data from Int to UUID (Type Change) : SUCCESS")
|
||||
Console.info("Migrating Data from Int to UUID (Type Change) : SUCCESS")
|
||||
|
||||
except Exception as ex:
|
||||
logger.error("Error while migrating Data from Int to UUID (Type Change)")
|
||||
logger.error(ex)
|
||||
Console.error("Error while migrating Data from Int to UUID (Type Change)")
|
||||
Console.error(ex)
|
||||
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||
last_migration.delete()
|
||||
return
|
||||
|
||||
try:
|
||||
logger.info("Migrating Data from Int to UUID (Foreign Keys)")
|
||||
Console.info("Migrating Data from Int to UUID (Foreign Keys)")
|
||||
# Changes on Audit Log Table
|
||||
for audit_log in AuditLog.select():
|
||||
old_server_id = audit_log.server_id_id
|
||||
if old_server_id == "0" or old_server_id is None:
|
||||
server_uuid = None
|
||||
else:
|
||||
try:
|
||||
server = Servers.get_by_id(old_server_id)
|
||||
server_uuid = server.server_uuid
|
||||
except:
|
||||
server_uuid = old_server_id
|
||||
AuditLog.update(server_id=server_uuid).where(
|
||||
AuditLog.audit_id == audit_log.audit_id
|
||||
).execute()
|
||||
|
||||
# Changes on Webhooks Log Table
|
||||
for webhook in Webhooks.select():
|
||||
old_server_id = webhook.server_id_id
|
||||
try:
|
||||
server = Servers.get_by_id(old_server_id)
|
||||
server_uuid = server.server_uuid
|
||||
except:
|
||||
server_uuid = old_server_id
|
||||
Webhooks.update(server_id=server_uuid).where(
|
||||
Webhooks.id == webhook.id
|
||||
).execute()
|
||||
|
||||
# Changes on Schedules Log Table
|
||||
for schedule in Schedules.select():
|
||||
old_server_id = schedule.server_id_id
|
||||
try:
|
||||
server = Servers.get_by_id(old_server_id)
|
||||
server_uuid = server.server_uuid
|
||||
except:
|
||||
server_uuid = old_server_id
|
||||
Schedules.update(server_id=server_uuid).where(
|
||||
Schedules.schedule_id == schedule.schedule_id
|
||||
).execute()
|
||||
|
||||
# Changes on Backups Log Table
|
||||
for backup in Backups.select():
|
||||
old_server_id = backup.server_id_id
|
||||
try:
|
||||
server = Servers.get_by_id(old_server_id)
|
||||
server_uuid = server.server_uuid
|
||||
except:
|
||||
server_uuid = old_server_id
|
||||
Backups.update(server_id=server_uuid).where(
|
||||
Backups.server_id == old_server_id
|
||||
).execute()
|
||||
|
||||
# Changes on RoleServers Log Table
|
||||
for role_servers in RoleServers.select():
|
||||
old_server_id = role_servers.server_id_id
|
||||
try:
|
||||
server = Servers.get_by_id(old_server_id)
|
||||
server_uuid = server.server_uuid
|
||||
except:
|
||||
server_uuid = old_server_id
|
||||
RoleServers.update(server_id=server_uuid).where(
|
||||
RoleServers.role_id == role_servers.id
|
||||
and RoleServers.server_id == old_server_id
|
||||
).execute()
|
||||
|
||||
logger.info("Migrating Data from Int to UUID (Foreign Keys) : SUCCESS")
|
||||
Console.info("Migrating Data from Int to UUID (Foreign Keys) : SUCCESS")
|
||||
|
||||
except Exception as ex:
|
||||
logger.error("Error while migrating Data from Int to UUID (Foreign Keys)")
|
||||
logger.error(ex)
|
||||
Console.error("Error while migrating Data from Int to UUID (Foreign Keys)")
|
||||
Console.error(ex)
|
||||
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||
last_migration.delete()
|
||||
return
|
||||
|
||||
try:
|
||||
logger.info("Migrating Data from Int to UUID (Primary Keys)")
|
||||
Console.info("Migrating Data from Int to UUID (Primary Keys)")
|
||||
# Migrating servers from the old id type to the new one
|
||||
for server in Servers.select():
|
||||
Servers.update(server_id=server.server_uuid).where(
|
||||
Servers.server_id == server.server_id
|
||||
).execute()
|
||||
|
||||
logger.info("Migrating Data from Int to UUID (Primary Keys) : SUCCESS")
|
||||
Console.info("Migrating Data from Int to UUID (Primary Keys) : SUCCESS")
|
||||
|
||||
except Exception as ex:
|
||||
logger.error("Error while migrating Data from Int to UUID (Primary Keys)")
|
||||
logger.error(ex)
|
||||
Console.error("Error while migrating Data from Int to UUID (Primary Keys)")
|
||||
Console.error(ex)
|
||||
last_migration = MigrateHistory.get_by_id(MigrateHistory.select().count())
|
||||
last_migration.delete()
|
||||
return
|
||||
|
||||
# Changes on Server Table
|
||||
logger.info("Migrating Data from Int to UUID (Removing UUID Field from Servers)")
|
||||
Console.info("Migrating Data from Int to UUID (Removing UUID Field from Servers)")
|
||||
migrator.drop_columns("servers", ["server_uuid"])
|
||||
migrator.run()
|
||||
logger.info(
|
||||
"Migrating Data from Int to UUID (Removing UUID Field from Servers) : SUCCESS"
|
||||
)
|
||||
Console.info(
|
||||
"Migrating Data from Int to UUID (Removing UUID Field from Servers) : SUCCESS"
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
|
||||
def rollback(migrator: Migrator, database, **kwargs):
|
||||
"""
|
||||
Write your rollback migrations here.
|
||||
"""
|
||||
db = database
|
||||
|
||||
# Changes on Server Table
|
||||
migrator.alter_column_type(
|
||||
"servers",
|
||||
"server_id",
|
||||
peewee.AutoField(),
|
||||
)
|
||||
|
||||
# Changes on Audit Log Table
|
||||
migrator.alter_column_type(
|
||||
AuditLog,
|
||||
"server_id",
|
||||
peewee.IntegerField(default=None, index=True),
|
||||
)
|
||||
|
||||
# Changes on Webhook Table
|
||||
migrator.alter_column_type(
|
||||
Webhooks,
|
||||
"server_id",
|
||||
peewee.IntegerField(null=True),
|
||||
)
|
@ -3,7 +3,7 @@ sonar.organization=crafty-controller
|
||||
|
||||
# This is the name and version displayed in the SonarCloud UI.
|
||||
sonar.projectName=Crafty 4
|
||||
sonar.projectVersion=4.2.4
|
||||
sonar.projectVersion=4.3.1
|
||||
sonar.python.version=3.9, 3.10, 3.11
|
||||
sonar.exclusions=app/migrations/**, app/frontend/static/assets/vendors/**
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user