mirror of
https://github.com/fergalmoran/bitchmin.git
synced 2025-12-22 09:27:53 +00:00
Add MX and tests
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
from .dns import DnsZone, DnsNameServer, DnsHost
|
from .dns import DnsZone, DnsNameServer, DnsMailExchanger, DnsHost
|
||||||
from .user import User
|
from .user import User
|
||||||
|
|||||||
@@ -10,30 +10,6 @@ from app import db
|
|||||||
from app.models._basemodel import _BaseModelMixin
|
from app.models._basemodel import _BaseModelMixin
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DnsNameServer(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
|
||||||
__tablename__ = 'dns_nameservers'
|
|
||||||
|
|
||||||
host = db.Column(db.String(255), unique=True, nullable=False)
|
|
||||||
ip = db.Column(IPAddressType(255), nullable=False)
|
|
||||||
ttl = db.Column(db.Integer(), nullable=False, default=30)
|
|
||||||
zone_id = db.Column(db.Integer, db.ForeignKey('dns_zones.id'))
|
|
||||||
zone = relationship("DnsZone", back_populates="nameservers")
|
|
||||||
|
|
||||||
def __init__(self, zone, host, ip, ttl=30):
|
|
||||||
self.zone = zone
|
|
||||||
self.host = host
|
|
||||||
self.ip = ip
|
|
||||||
self.ttl = ttl
|
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
return {
|
|
||||||
'name': self.host,
|
|
||||||
'ip': self.ip,
|
|
||||||
'ttl': self.ttl
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
||||||
__tablename__ = 'dns_zones'
|
__tablename__ = 'dns_zones'
|
||||||
@@ -64,6 +40,7 @@ class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
|||||||
'serial': self.serial,
|
'serial': self.serial,
|
||||||
'admin': self.admin,
|
'admin': self.admin,
|
||||||
'nameservers': [ns.to_dict() for ns in self.nameservers],
|
'nameservers': [ns.to_dict() for ns in self.nameservers],
|
||||||
|
'mailexchangers': [mx.to_dict() for mx in self.mailexchangers],
|
||||||
'hosts': [host.to_dict() for host in self.hosts]
|
'hosts': [host.to_dict() for host in self.hosts]
|
||||||
}
|
}
|
||||||
return ret_data
|
return ret_data
|
||||||
@@ -77,6 +54,60 @@ class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
|||||||
|
|
||||||
hosts = relationship("DnsHost", back_populates="zone")
|
hosts = relationship("DnsHost", back_populates="zone")
|
||||||
nameservers = relationship("DnsNameServer", back_populates="zone")
|
nameservers = relationship("DnsNameServer", back_populates="zone")
|
||||||
|
mailexchangers = relationship("DnsMailExchanger", back_populates="zone")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DnsNameServer(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
||||||
|
__tablename__ = 'dns_nameservers'
|
||||||
|
|
||||||
|
host = db.Column(db.String(255), unique=True, nullable=False)
|
||||||
|
ip = db.Column(IPAddressType(255), nullable=False)
|
||||||
|
ttl = db.Column(db.Integer(), nullable=False, default=30)
|
||||||
|
zone_id = db.Column(db.Integer, db.ForeignKey('dns_zones.id'))
|
||||||
|
zone = relationship("DnsZone", back_populates="nameservers")
|
||||||
|
|
||||||
|
def __init__(self, zone, host, ip, ttl=30):
|
||||||
|
self.zone = zone
|
||||||
|
self.host = host
|
||||||
|
self.ip = ip
|
||||||
|
self.ttl = ttl
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
'name': self.host,
|
||||||
|
'ip': self.ip,
|
||||||
|
'ttl': self.ttl
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DnsMailExchanger(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
||||||
|
__tablename__ = 'dns_mailexchangers'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
zone_id = db.Column(db.Integer, db.ForeignKey('dns_zones.id'))
|
||||||
|
zone = relationship("DnsZone", back_populates="mailexchangers")
|
||||||
|
|
||||||
|
host = db.Column(db.String(255), unique=True, nullable=False)
|
||||||
|
preference = db.Column(db.Integer, nullable=False)
|
||||||
|
ttl = db.Column(db.Integer(), nullable=False)
|
||||||
|
|
||||||
|
def __init__(self, zone, host, preference, ttl=30):
|
||||||
|
self.zone = zone
|
||||||
|
self.host = host
|
||||||
|
self.ttl = ttl
|
||||||
|
self.preference = preference
|
||||||
|
pass
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
'id': self.id,
|
||||||
|
'name': self.host,
|
||||||
|
'preference': self.preference,
|
||||||
|
'ttl': self.ttl,
|
||||||
|
'created_on': self.created_on,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from app.models import DnsZone, User, DnsHost, DnsNameServer
|
from app.models import DnsZone, User, DnsHost, DnsNameServer, DnsMailExchanger
|
||||||
|
|
||||||
|
|
||||||
class DbSeeder(object):
|
class DbSeeder(object):
|
||||||
@@ -28,16 +28,16 @@ class DbSeeder(object):
|
|||||||
)
|
)
|
||||||
self._db.session.add(ns)
|
self._db.session.add(ns)
|
||||||
|
|
||||||
def _create_hosts(self, zone):
|
def _create_mailexchangers(self, zone):
|
||||||
for i in range(1, 11):
|
for i in range(1, 11):
|
||||||
host = DnsHost(
|
host = DnsMailExchanger(
|
||||||
zone,
|
zone,
|
||||||
'host-{}'.format(i),
|
'mail-{}.bitchmints.com'.format(i),
|
||||||
'10.1.1.{}'.format(i)
|
i
|
||||||
)
|
)
|
||||||
self._db.session.add(host)
|
self._db.session.add(host)
|
||||||
|
|
||||||
def _create_mx_records(self, zone):
|
def _create_hosts(self, zone):
|
||||||
for i in range(1, 11):
|
for i in range(1, 11):
|
||||||
host = DnsHost(
|
host = DnsHost(
|
||||||
zone,
|
zone,
|
||||||
@@ -53,6 +53,7 @@ class DbSeeder(object):
|
|||||||
self._create_user()
|
self._create_user()
|
||||||
z = self._create_zone()
|
z = self._create_zone()
|
||||||
self._create_nameservers(z)
|
self._create_nameservers(z)
|
||||||
|
self._create_mailexchangers(z)
|
||||||
self._create_hosts(z)
|
self._create_hosts(z)
|
||||||
|
|
||||||
self._db.session.commit()
|
self._db.session.commit()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from app.models import User, DnsZone, DnsNameServer, DnsHost
|
from app.models import User, DnsZone, DnsNameServer, DnsHost, DnsMailExchanger
|
||||||
|
|
||||||
|
|
||||||
class TestDatabaseUpdate:
|
class TestDatabaseUpdate:
|
||||||
@@ -8,6 +8,7 @@ class TestDatabaseUpdate:
|
|||||||
assert db.session.query(User).count() == 1
|
assert db.session.query(User).count() == 1
|
||||||
assert db.session.query(DnsZone).count() == 1
|
assert db.session.query(DnsZone).count() == 1
|
||||||
assert db.session.query(DnsNameServer).count() == 2
|
assert db.session.query(DnsNameServer).count() == 2
|
||||||
|
assert db.session.query(DnsMailExchanger).count() == 10
|
||||||
assert db.session.query(DnsHost).count() == 10
|
assert db.session.query(DnsHost).count() == 10
|
||||||
|
|
||||||
def test_serial_on_create(self, db) -> None:
|
def test_serial_on_create(self, db) -> None:
|
||||||
|
|||||||
@@ -11,7 +11,11 @@ class TestUserRoutes:
|
|||||||
assert len(zones) == 1
|
assert len(zones) == 1
|
||||||
assert zones[0]['name'] == 'bitchmints.com'
|
assert zones[0]['name'] == 'bitchmints.com'
|
||||||
assert len(zones[0]['nameservers']) == 2
|
assert len(zones[0]['nameservers']) == 2
|
||||||
assert zones[0]['nameservers'][0]['name'] == 'host-1.bitchmints.com'
|
|
||||||
assert zones[0]['nameservers'][1]['name'] == 'host-2.bitchmints.com'
|
for i in range(0, 2):
|
||||||
assert zones[0]['nameservers'][0]['ip'] == '10.1.1.101'
|
assert zones[0]['nameservers'][i]['ip'] == '10.1.1.10{}'.format(i + 1)
|
||||||
assert zones[0]['nameservers'][1]['ip'] == '10.1.1.102'
|
assert zones[0]['nameservers'][i]['name'] == 'host-{}.bitchmints.com'.format(i + 1)
|
||||||
|
|
||||||
|
for i in range(0, 10):
|
||||||
|
assert zones[0]['mailexchangers'][i]['name'] == 'mail-{}.bitchmints.com'.format(i + 1)
|
||||||
|
assert zones[0]['mailexchangers'][i]['preference'] == i + 1
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
"""Add TTL to nameserver.
|
|
||||||
|
|
||||||
Revision ID: 4fa78fdd3f74
|
|
||||||
Revises: b780f60b3019
|
|
||||||
Create Date: 2020-11-18 16:55:35.514517
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
import sqlalchemy_utils
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = '4fa78fdd3f74'
|
|
||||||
down_revision = 'b780f60b3019'
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.add_column('dns_nameservers', sa.Column('ttl', sa.Integer(), nullable=True))
|
|
||||||
op.execute('UPDATE dns_nameservers SET ttl = 30')
|
|
||||||
op.alter_column('dns_nameservers', 'ttl', nullable=False)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_column('dns_nameservers', 'ttl')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
"""Initial migration.
|
|
||||||
|
|
||||||
Revision ID: b780f60b3019
|
|
||||||
Revises:
|
|
||||||
Create Date: 2020-11-16 13:00:43.391154
|
|
||||||
|
|
||||||
"""
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
import sqlalchemy_utils
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision = 'b780f60b3019'
|
|
||||||
down_revision = None
|
|
||||||
branch_labels = None
|
|
||||||
depends_on = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.create_table('dns_zones',
|
|
||||||
sa.Column('created_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('updated_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('zone_name', sa.String(length=253), nullable=False),
|
|
||||||
sa.Column('serial', sa.Integer(), nullable=True),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('zone_name')
|
|
||||||
)
|
|
||||||
op.create_table('users',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('created_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('updated_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('email', sa.String(length=120), nullable=False),
|
|
||||||
sa.Column('full_name', sa.String(length=120), nullable=True),
|
|
||||||
sa.Column('password', sa.String(length=255), nullable=False),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('email')
|
|
||||||
)
|
|
||||||
op.create_table('dns_hosts',
|
|
||||||
sa.Column('created_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('updated_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('zone_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('host', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('ip', sqlalchemy_utils.types.ip_address.IPAddressType(length=255), nullable=False),
|
|
||||||
sa.Column('type', sa.String(length=10), nullable=False),
|
|
||||||
sa.Column('ttl', sa.Integer(), nullable=False),
|
|
||||||
sa.ForeignKeyConstraint(['zone_id'], ['dns_zones.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('host')
|
|
||||||
)
|
|
||||||
op.create_table('dns_nameservers',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('created_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('updated_on', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
|
||||||
sa.Column('host', sa.String(length=255), nullable=False),
|
|
||||||
sa.Column('ip', sqlalchemy_utils.types.ip_address.IPAddressType(length=255), nullable=False),
|
|
||||||
sa.Column('zone_id', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['zone_id'], ['dns_zones.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id'),
|
|
||||||
sa.UniqueConstraint('host')
|
|
||||||
)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_table('dns_nameservers')
|
|
||||||
op.drop_table('dns_hosts')
|
|
||||||
op.drop_table('users')
|
|
||||||
op.drop_table('dns_zones')
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
Reference in New Issue
Block a user