feat: SFTP-Anbindung und Zugangsdatenart im Datenmodell
Neuer Anbindungstyp sftp (share = entfernter Basispfad, port, host_key), credentials.kind (password|ssh_key) und public_key. Migration 0001 vor dem ersten Release angepasst. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a60daf0039
commit
278180c541
@@ -23,9 +23,22 @@ def upgrade() -> None:
|
||||
"credentials",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("name", sa.String(length=100), nullable=False),
|
||||
sa.Column(
|
||||
"kind",
|
||||
sa.Enum(
|
||||
"password",
|
||||
"ssh_key",
|
||||
name="credential_kind",
|
||||
native_enum=False,
|
||||
create_constraint=True,
|
||||
length=24,
|
||||
),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("username", sa.String(length=255), nullable=False),
|
||||
sa.Column("domain", sa.String(length=255), nullable=True),
|
||||
sa.Column("secret_enc", sa.Text(), nullable=False),
|
||||
sa.Column("public_key", sa.Text(), nullable=True),
|
||||
sa.Column("created_at", netmover.models.UTCDateTime(), nullable=False),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_credentials")),
|
||||
sa.UniqueConstraint("name", name=op.f("uq_credentials_name")),
|
||||
@@ -47,6 +60,7 @@ def upgrade() -> None:
|
||||
"cifs",
|
||||
"nfs4",
|
||||
"nfs3",
|
||||
"sftp",
|
||||
name="mount_type",
|
||||
native_enum=False,
|
||||
create_constraint=True,
|
||||
@@ -56,7 +70,9 @@ def upgrade() -> None:
|
||||
),
|
||||
sa.Column("server", sa.String(length=255), nullable=False),
|
||||
sa.Column("share", sa.String(length=1024), nullable=False),
|
||||
sa.Column("mountpoint", sa.String(length=1024), nullable=False),
|
||||
sa.Column("port", sa.Integer(), nullable=True),
|
||||
sa.Column("host_key", sa.Text(), nullable=True),
|
||||
sa.Column("mountpoint", sa.String(length=1024), nullable=True),
|
||||
sa.Column("cred_id", sa.Integer(), nullable=True),
|
||||
sa.Column("uid", sa.Integer(), nullable=True),
|
||||
sa.Column("gid", sa.Integer(), nullable=True),
|
||||
|
||||
+22
-2
@@ -2,6 +2,10 @@
|
||||
|
||||
Abweichungen bzw. Ergänzungen gegenüber dem Mindestumfang aus der Spezifikation:
|
||||
|
||||
* Typ ``sftp``: Ziel per SSH/SFTP ohne Kernel-Mount (z. B. Paperless im LXC).
|
||||
``share`` ist dort der entfernte Basispfad, dazu ``port`` und ``host_key``
|
||||
(beim ersten Test festgehaltener Hostschlüssel, danach verbindlich).
|
||||
* ``credentials.kind`` (``password`` | ``ssh_key``) und ``credentials.public_key``.
|
||||
* ``credentials.domain`` – Windows-/AD-Freigaben brauchen oft eine Domäne.
|
||||
* ``mounts.state_since`` – für „hängt seit …“ / „gestört seit …“ auf der Statusseite.
|
||||
* ``mounts.write_ok`` / ``mounts.root_squash`` / ``mounts.last_test_*`` – Ergebnis
|
||||
@@ -93,6 +97,16 @@ class MountType(enum.StrEnum):
|
||||
CIFS = "cifs"
|
||||
NFS4 = "nfs4"
|
||||
NFS3 = "nfs3"
|
||||
SFTP = "sftp"
|
||||
|
||||
@property
|
||||
def is_kernel_mount(self) -> bool:
|
||||
return self is not MountType.SFTP
|
||||
|
||||
|
||||
class CredentialKind(enum.StrEnum):
|
||||
PASSWORD = "password" # noqa: S105 – Art der Zugangsdaten, kein Passwort
|
||||
SSH_KEY = "ssh_key"
|
||||
|
||||
|
||||
class MountState(enum.StrEnum):
|
||||
@@ -145,9 +159,13 @@ class Credential(Base):
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
name: Mapped[str] = mapped_column(String(100), unique=True)
|
||||
kind: Mapped[CredentialKind] = mapped_column(
|
||||
_enum(CredentialKind, "credential_kind"), default=CredentialKind.PASSWORD
|
||||
)
|
||||
username: Mapped[str] = mapped_column(String(255))
|
||||
domain: Mapped[str | None] = mapped_column(String(255))
|
||||
secret_enc: Mapped[str] = mapped_column(Text)
|
||||
secret_enc: Mapped[str] = mapped_column(Text) # Passwort bzw. privater Schlüssel (Fernet)
|
||||
public_key: Mapped[str | None] = mapped_column(Text) # nur ssh_key, OpenSSH-Format
|
||||
created_at: Mapped[datetime] = mapped_column(UTCDateTime, default=utcnow)
|
||||
|
||||
# passive_deletes="all": das ORM soll cred_id nicht still auf NULL setzen,
|
||||
@@ -164,7 +182,9 @@ class Mount(Base):
|
||||
type: Mapped[MountType] = mapped_column(_enum(MountType, "mount_type"))
|
||||
server: Mapped[str] = mapped_column(String(255))
|
||||
share: Mapped[str] = mapped_column(String(1024))
|
||||
mountpoint: Mapped[str] = mapped_column(String(1024), unique=True)
|
||||
port: Mapped[int | None] = mapped_column(Integer) # nur sftp
|
||||
host_key: Mapped[str | None] = mapped_column(Text) # nur sftp, "<typ> <base64>"
|
||||
mountpoint: Mapped[str | None] = mapped_column(String(1024), unique=True) # NULL bei sftp
|
||||
cred_id: Mapped[int | None] = mapped_column(ForeignKey("credentials.id", ondelete="RESTRICT"))
|
||||
uid: Mapped[int | None] = mapped_column(Integer)
|
||||
gid: Mapped[int | None] = mapped_column(Integer)
|
||||
|
||||
Reference in New Issue
Block a user