mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-04 06:21:15 +02:00
Merge branch '3.1' into image-manager-out-of-sync
This commit is contained in:
129 files changed
+944
-863
No files matched your search
@@ -14,7 +14,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from .base import BaseTable, GUID
|
||||
|
||||
@@ -22,8 +25,10 @@ from .base import BaseTable, GUID
|
||||
class ApiKey(BaseTable):
|
||||
__tablename__ = "api_keys"
|
||||
|
||||
api_key_id = Column(GUID, primary_key=True)
|
||||
user_id = Column(GUID, ForeignKey("users.user_id", ondelete="CASCADE"), nullable=False, index=True)
|
||||
api_key_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
GUID, ForeignKey("users.user_id", ondelete="CASCADE"), nullable=False, index=True
|
||||
)
|
||||
name = Column(String(128), nullable=False)
|
||||
key_hash = Column(String(128), nullable=False)
|
||||
key_prefix = Column(String(8), nullable=False)
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from sqlalchemy import Column, DateTime, func, inspect
|
||||
from sqlalchemy.types import TypeDecorator, CHAR, VARCHAR
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
||||
|
||||
|
||||
class Base(DeclarativeBase):
|
||||
@@ -105,7 +107,9 @@ class BaseTable(Base):
|
||||
__abstract__ = True
|
||||
|
||||
created_at = Column(DateTime, server_default=func.current_timestamp())
|
||||
updated_at = Column(DateTime, server_default=func.current_timestamp(), onupdate=func.current_timestamp())
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime, server_default=func.current_timestamp(), onupdate=func.current_timestamp()
|
||||
)
|
||||
|
||||
__mapper_args__ = {"eager_defaults": True}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sqlalchemy import Table, Column, String, ForeignKey, BigInteger, Integer, DateTime, JSON, Boolean
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .base import Base, BaseTable, GUID
|
||||
|
||||
@@ -32,9 +32,9 @@ image_template_map = Table(
|
||||
class Image(BaseTable):
|
||||
__tablename__ = "images"
|
||||
|
||||
image_id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
image_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
filename = Column(String, index=True)
|
||||
path = Column(String, unique=True)
|
||||
path: Mapped[str] = mapped_column(String, unique=True, nullable=True)
|
||||
image_type = Column(String)
|
||||
image_size = Column(BigInteger)
|
||||
checksum = Column(String, index=True)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sqlalchemy import Column, Boolean, ForeignKey, CheckConstraint, Index, Integer, String, text, JSON
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .base import BaseTable, generate_uuid, GUID
|
||||
|
||||
@@ -36,11 +36,13 @@ class LLMModelConfig(BaseTable):
|
||||
config_id = Column(GUID, primary_key=True, default=generate_uuid)
|
||||
name = Column(String(100), nullable=False) # Configuration name (table-level for indexing)
|
||||
model_type = Column(String(50), nullable=False) # Model type: text, vision, stt, tts, multimodal, etc.
|
||||
config = Column(JSON, nullable=False) # Config fields: provider, base_url, model, temperature, api_key, etc.
|
||||
config: Mapped[dict] = mapped_column(
|
||||
JSON, nullable=False
|
||||
) # Config fields: provider, base_url, model, temperature, api_key, etc.
|
||||
user_id = Column(GUID, ForeignKey("users.user_id", ondelete="CASCADE"), nullable=True)
|
||||
group_id = Column(GUID, ForeignKey("user_groups.user_group_id", ondelete="CASCADE"), nullable=True)
|
||||
is_default = Column(Boolean, default=False, nullable=False)
|
||||
version = Column(Integer, default=0, nullable=False) # Optimistic locking version
|
||||
version: Mapped[int] = mapped_column(Integer, default=0, nullable=False) # Optimistic locking version
|
||||
|
||||
# Relationships
|
||||
user = relationship("User", backref="llm_model_configs")
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Table, Column, String, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .base import Base, BaseTable, generate_uuid, GUID
|
||||
|
||||
@@ -36,7 +38,7 @@ resource_pool_map = Table(
|
||||
class Resource(BaseTable):
|
||||
__tablename__ = "resources"
|
||||
|
||||
resource_id = Column(GUID, primary_key=True)
|
||||
resource_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True)
|
||||
name = Column(String, unique=True, index=True)
|
||||
resource_type = Column(String)
|
||||
resource_pools = relationship("ResourcePool", secondary=resource_pool_map, back_populates="resources")
|
||||
@@ -45,6 +47,6 @@ class Resource(BaseTable):
|
||||
class ResourcePool(BaseTable):
|
||||
__tablename__ = "resource_pools"
|
||||
|
||||
resource_pool_id = Column(GUID, primary_key=True, default=generate_uuid)
|
||||
resource_pool_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
|
||||
name = Column(String, unique=True, index=True)
|
||||
resources = relationship("Resource", secondary=resource_pool_map, back_populates="resource_pools")
|
||||
@@ -15,8 +15,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import Column, String, Boolean, event
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .base import BaseTable, generate_uuid, GUID
|
||||
from .privileges import privilege_role_map
|
||||
@@ -29,7 +31,7 @@ log = logging.getLogger(__name__)
|
||||
class Role(BaseTable):
|
||||
__tablename__ = "roles"
|
||||
|
||||
role_id = Column(GUID, primary_key=True, default=generate_uuid)
|
||||
role_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
|
||||
name = Column(String, unique=True, index=True)
|
||||
description = Column(String)
|
||||
is_builtin = Column(Boolean, default=False)
|
||||
|
||||
@@ -16,19 +16,26 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import Boolean, Column, String, Integer, Float, ForeignKey, JSON
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .base import BaseTable, generate_uuid, GUID
|
||||
from .images import image_template_map
|
||||
|
||||
|
||||
def template_id_column() -> Mapped[uuid.UUID]:
|
||||
return mapped_column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
|
||||
|
||||
class Template(BaseTable):
|
||||
__tablename__ = "templates"
|
||||
|
||||
template_id = Column(GUID, primary_key=True, default=generate_uuid)
|
||||
template_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
|
||||
name = Column(String, index=True)
|
||||
version = Column(String)
|
||||
version: Mapped[Optional[str]] = mapped_column(String)
|
||||
category = Column(String)
|
||||
default_name_format = Column(String)
|
||||
symbol = Column(String)
|
||||
@@ -36,7 +43,7 @@ class Template(BaseTable):
|
||||
usage = Column(String)
|
||||
netmiko_device_type = Column(String)
|
||||
appliance_metadata = Column(JSON)
|
||||
template_type = Column(String)
|
||||
template_type: Mapped[str] = mapped_column(String, nullable=True)
|
||||
tags = Column(JSON)
|
||||
compute_id = Column(String)
|
||||
images = relationship("Image", secondary=image_template_map, back_populates="templates")
|
||||
@@ -50,7 +57,7 @@ class Template(BaseTable):
|
||||
class CloudTemplate(Template):
|
||||
__tablename__ = "cloud_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
ports_mapping = Column(JSON)
|
||||
remote_console_host = Column(String)
|
||||
remote_console_port = Column(Integer)
|
||||
@@ -63,7 +70,7 @@ class CloudTemplate(Template):
|
||||
class DockerTemplate(Template):
|
||||
__tablename__ = "docker_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
image = Column(String)
|
||||
adapters = Column(Integer)
|
||||
mac_address = Column(String)
|
||||
@@ -88,10 +95,10 @@ class DockerTemplate(Template):
|
||||
class DynamipsTemplate(Template):
|
||||
__tablename__ = "dynamips_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
platform = Column(String)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
platform: Mapped[str] = mapped_column(String, nullable=True)
|
||||
chassis = Column(String)
|
||||
image = Column(String)
|
||||
image: Mapped[str] = mapped_column(String, nullable=True)
|
||||
exec_area = Column(Integer)
|
||||
mmap = Column(Boolean)
|
||||
mac_addr = Column(String)
|
||||
@@ -130,7 +137,7 @@ class DynamipsTemplate(Template):
|
||||
class EthernetHubTemplate(Template):
|
||||
__tablename__ = "ethernet_hub_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
ports_mapping = Column(JSON)
|
||||
|
||||
__mapper_args__ = {"polymorphic_identity": "ethernet_hub", "polymorphic_load": "selectin"}
|
||||
@@ -139,7 +146,7 @@ class EthernetHubTemplate(Template):
|
||||
class EthernetSwitchTemplate(Template):
|
||||
__tablename__ = "ethernet_switch_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
ports_mapping = Column(JSON)
|
||||
console_type = Column(String)
|
||||
|
||||
@@ -149,8 +156,8 @@ class EthernetSwitchTemplate(Template):
|
||||
class IOUTemplate(Template):
|
||||
__tablename__ = "iou_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
path = Column(String)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
path: Mapped[str] = mapped_column(String, nullable=True)
|
||||
ethernet_adapters = Column(Integer)
|
||||
serial_adapters = Column(Integer)
|
||||
ram = Column(Integer)
|
||||
@@ -168,7 +175,7 @@ class IOUTemplate(Template):
|
||||
class QemuTemplate(Template):
|
||||
__tablename__ = "qemu_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
qemu_path = Column(String)
|
||||
platform = Column(String)
|
||||
linked_clone = Column(Boolean)
|
||||
@@ -214,7 +221,7 @@ class QemuTemplate(Template):
|
||||
class VirtualBoxTemplate(Template):
|
||||
__tablename__ = "virtualbox_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
vmname = Column(String)
|
||||
ram = Column(Integer)
|
||||
linked_clone = Column(Boolean)
|
||||
@@ -236,7 +243,7 @@ class VirtualBoxTemplate(Template):
|
||||
class VMwareTemplate(Template):
|
||||
__tablename__ = "vmware_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
vmx_path = Column(String)
|
||||
linked_clone = Column(Boolean)
|
||||
first_port_name = Column(String)
|
||||
@@ -257,7 +264,7 @@ class VMwareTemplate(Template):
|
||||
class VPCSTemplate(Template):
|
||||
__tablename__ = "vpcs_templates"
|
||||
|
||||
template_id = Column(GUID, ForeignKey("templates.template_id", ondelete="CASCADE"), primary_key=True)
|
||||
template_id: Mapped[uuid.UUID] = template_id_column()
|
||||
base_script_file = Column(String)
|
||||
console_type = Column(String)
|
||||
console_auto_start = Column(Boolean, default=False)
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import Table, Boolean, Column, Integer, String, DateTime, ForeignKey, event
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from .base import Base, BaseTable, generate_uuid, GUID
|
||||
|
||||
@@ -24,6 +27,7 @@ from gns3server.config import Config
|
||||
from gns3server.services import auth_service
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -43,8 +47,8 @@ class User(BaseTable):
|
||||
email = Column(String, unique=True, index=True)
|
||||
full_name = Column(String)
|
||||
hashed_password = Column(String)
|
||||
last_login = Column(DateTime)
|
||||
token_version = Column(Integer, default=0, nullable=False, server_default="0")
|
||||
last_login: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
token_version: Mapped[int] = mapped_column(Integer, default=0, nullable=False, server_default="0")
|
||||
is_active = Column(Boolean, default=True)
|
||||
is_superadmin = Column(Boolean, default=False)
|
||||
groups = relationship("UserGroup", secondary=user_group_map, back_populates="users")
|
||||
@@ -72,7 +76,7 @@ def create_default_super_admin(target, connection, **kw):
|
||||
class UserGroup(BaseTable):
|
||||
__tablename__ = "user_groups"
|
||||
|
||||
user_group_id = Column(GUID, primary_key=True, default=generate_uuid)
|
||||
user_group_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
|
||||
name = Column(String, unique=True, index=True)
|
||||
is_builtin = Column(Boolean, default=False)
|
||||
users = relationship("User", secondary=user_group_map, back_populates="groups")
|
||||
|
||||
Reference in new issue
Block a user