Skip to content

Commit

Permalink
Remote Initiate/Terminate MC Server
Browse files Browse the repository at this point in the history
  • Loading branch information
WasinUddy committed Oct 18, 2023
1 parent 99477f6 commit a78de1e
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from app.models.mc_server import MCServer
from app.schemas.mc_server import MCServerInfo

def get_minecraft_server(db: Session = Depends(get_db)) -> List[MCServerInfo]:
def get_minecraft_servers(db: Session = Depends(get_db)) -> List[MCServerInfo]:
"""
Returns a list of all Minecraft servers by querying it from database.
Expand Down
42 changes: 42 additions & 0 deletions app/api/rest/minecraft/endpoints/start_minecraft_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from fastapi import Depends
from app.db.session import get_db
from app.models.mc_server import MCServer
from app.schemas.mc_server import MCServerInitiateResponse
from sqlalchemy.orm import Session

import os
from io import StringIO

import paramiko

def start_minecraft_server(server_id: int, db: Session = Depends(get_db)) -> MCServerInitiateResponse:
"""
Start a minecraft server by server_id.
"""
server_info = db.query(MCServer).filter(MCServer.id == server_id).first()


# Establish SSH connection
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

private_key = paramiko.RSAKey(file_obj=StringIO(os.environ.get("SSH_KEY")))

# Connect to the server
client.connect(
hostname=server_info.server_ip,
port=server_info.ssh_port,
username=server_info.ssh_username,
pkey=private_key
)

cmd = server_info.start_cmd

_, stdout, stderr = client.exec_command(cmd)

# Close the connection
client.close()


return MCServerInitiateResponse(stdout=stdout.read().decode(), stderr=stderr.read().decode())
42 changes: 42 additions & 0 deletions app/api/rest/minecraft/endpoints/stop_minecraft_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from fastapi import Depends
from app.db.session import get_db
from app.models.mc_server import MCServer
from app.schemas.mc_server import MCServerTerminateResponse
from sqlalchemy.orm import Session

import os
from io import StringIO

import paramiko

def stop_minecraft_server(server_id: int, db: Session = Depends(get_db)) -> MCServerTerminateResponse:
"""
Stop a minecraft server by server_id.
"""
server_info = db.query(MCServer).filter(MCServer.id == server_id).first()


# Establish SSH connection
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

private_key = paramiko.RSAKey(file_obj=StringIO(os.environ.get("SSH_KEY")))

# Connect to the server
client.connect(
hostname=server_info.server_ip,
port=server_info.ssh_port,
username=server_info.ssh_username,
pkey=private_key
)

cmd = server_info.stop_cmd

_, stdout, stderr = client.exec_command(cmd)

# Close the connection
client.close()


return MCServerTerminateResponse(stdout=stdout.read().decode(), stderr=stderr.read().decode())
26 changes: 20 additions & 6 deletions app/api/rest/minecraft/router.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from fastapi import APIRouter, Depends
from fastapi import APIRouter, Depends, Header
from typing import List
from app.schemas.mc_server import MCServerInfo

from .endpoints.get_minecraft_server import get_minecraft_server as gms
from app.schemas.mc_server import MCServerInfo, MCServerInitiateResponse, MCServerTerminateResponse
from .endpoints.get_minecraft_servers import get_minecraft_servers as gmss
from .endpoints.start_minecraft_server import start_minecraft_server as sms
from .endpoints.stop_minecraft_server import stop_minecraft_server as stms

router = APIRouter()

@router.get("/server_list")
def get_minecraft_server(server_list: List[MCServerInfo] = Depends(gms)) -> List[MCServerInfo]:
@router.get("/server/list")
def get_minecraft_server(server_list: List[MCServerInfo] = Depends(gmss)):
"""
Returns a list of all Minecraft servers by querying it from database.
Expand All @@ -17,4 +18,17 @@ def get_minecraft_server(server_list: List[MCServerInfo] = Depends(gms)) -> List
return server_list


@router.post("/server/start")
def start_minecraft_server(response: MCServerInitiateResponse = Depends(sms)):
"""
Starts a Minecraft server by server_id.
"""
return response


@router.post("/server/stop")
def stop_minecraft_server(response: MCServerTerminateResponse = Depends(stms)):
"""
Stops a Minecraft server by server_id.
"""
return response
18 changes: 4 additions & 14 deletions app/models/mc_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,17 @@
from app.db.session import Base

class MCServer(Base):
"""
Represents a Minecraft server entity within the application.
Attributes:
- __tablename__ (str): The name of the table in the database.
- id (Column): The unique identifier for a server, primary key.
- server_name (Column): The name of the Minecraft server.
- server_ip (Column): The IP address of the Minecraft server.
- server_port (Column): The port number of the Minecraft server.
- server_version (Column): The version of the Minecraft server.
- server_executable (Column): The path or name of the server's executable file.
"""


__tablename__ = "mc_servers"

id = Column(Integer, primary_key=True, index=True)
server_name = Column(String)
server_ip = Column(String)
server_port = Column(Integer)
server_version = Column(String)
server_executable = Column(String)
server_note = Column(String)
ssh_username = Column(String)
ssh_port = Column(Integer)
ssh_public_key = Column(String)
start_cmd = Column(String)
stop_cmd = Column(String)
15 changes: 13 additions & 2 deletions app/schemas/mc_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,30 @@ class MCServerInfo(BaseModel):
A Pydantic model that defines the data structure for server information.
Attributes:
- id (int): The unique identifier for a server, primary key.
- server_name (str): The name of the Minecraft server.
- server_ip (str): The IP address of the Minecraft server.
- server_port (int): The port number of the Minecraft server.
- server_version (str): The version of the Minecraft server.
- server_executable (str): The path or name of the server's executable file.
- server_execute_cmd (str): The path or name of the server's executable file.
"""
id: int
server_name: str
server_ip: str
server_port: int
server_version: str
server_executable: str
server_execute_cmd: str
server_note: str
ssh_username: str
ssh_port: int
ssh_public_key: str


class MCServerInitiateResponse(BaseModel):
stdout: str
stderr: str


class MCServerTerminateResponse(BaseModel):
stdout: str
stderr: str

0 comments on commit a78de1e

Please sign in to comment.