mirror of
https://github.com/fergalmoran/bitchmin.git
synced 2025-12-22 09:27:53 +00:00
armv7 build
This commit is contained in:
1
bitchmin-api/.gitignore
vendored
1
bitchmin-api/.gitignore
vendored
@@ -144,3 +144,4 @@ cython_debug/
|
|||||||
app.db
|
app.db
|
||||||
bitchmin.db
|
bitchmin.db
|
||||||
.idea/
|
.idea/
|
||||||
|
app/dashboard.cfg
|
||||||
@@ -1 +1 @@
|
|||||||
BitchMin
|
bitchmin-api
|
||||||
27
bitchmin-api/.working/Dockerfile.alpine
Normal file
27
bitchmin-api/.working/Dockerfile.alpine
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
FROM python:3.7-alpine
|
||||||
|
|
||||||
|
COPY ./requirements.txt /requirements.txt
|
||||||
|
|
||||||
|
RUN apk update && \
|
||||||
|
apk add --no-cache --virtual build-deps gcc python3-dev musl-dev bind-tools lapack libstdc++ && \
|
||||||
|
apk --no-cache add --virtual .builddeps g++ gcc gfortran musl-dev lapack-dev && \
|
||||||
|
apk add postgresql-dev && \
|
||||||
|
pip install scipy && apk del .builddeps && rm -rf /root/.cache && \
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
RUN pip install gunicorn
|
||||||
|
|
||||||
|
COPY app /app
|
||||||
|
COPY migrations /migrations
|
||||||
|
COPY server.py boot.sh ./
|
||||||
|
RUN chmod +x boot.sh
|
||||||
|
|
||||||
|
ENV FLASK_ENV production
|
||||||
|
ENV FLASK_APP server.py
|
||||||
|
|
||||||
|
RUN chown -R bitchmin:bitchmin ./
|
||||||
|
USER bitchmin
|
||||||
|
|
||||||
|
EXPOSE 5000
|
||||||
|
ENTRYPOINT ["./boot.sh"]
|
||||||
@@ -1,30 +1,22 @@
|
|||||||
FROM python:3.7.4-alpine
|
FROM python:3.7
|
||||||
|
|
||||||
RUN adduser -D bitchmin
|
COPY ./requirements.txt /requirements.txt
|
||||||
RUN mkdir /bitchmin
|
RUN apt update && \
|
||||||
WORKDIR /bitchmin
|
apt install libblas-dev && \
|
||||||
COPY ./requirements.txt requirements.txt
|
pip install gunicorn
|
||||||
|
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
|
||||||
RUN apk update && \
|
COPY app /app
|
||||||
apk add --no-cache --virtual build-deps gcc python3-dev musl-dev bind-tools && \
|
COPY migrations /migrations
|
||||||
apk add postgresql-dev && \
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
|
|
||||||
RUN python3.7 -m venv venv
|
|
||||||
RUN venv/bin/pip install -r requirements.txt
|
|
||||||
RUN venv/bin/pip install gunicorn
|
|
||||||
|
|
||||||
COPY app app
|
|
||||||
COPY migrations migrations
|
|
||||||
COPY server.py boot.sh ./
|
COPY server.py boot.sh ./
|
||||||
RUN chmod +x boot.sh
|
RUN chmod +x boot.sh
|
||||||
|
|
||||||
|
ENV FLASK_ENV production
|
||||||
ENV FLASK_APP server.py
|
ENV FLASK_APP server.py
|
||||||
|
|
||||||
RUN chown -R bitchmin:bitchmin ./
|
#RUN chown -R bitchmin:bitchmin ./
|
||||||
USER bitchmin
|
#USER bitchmin
|
||||||
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
ENTRYPOINT ["./boot.sh"]
|
ENTRYPOINT ["./boot.sh"]
|
||||||
@@ -9,8 +9,9 @@ from flask_jwt_extended import JWTManager
|
|||||||
from flask_mail import Mail
|
from flask_mail import Mail
|
||||||
from flask_migrate import Migrate
|
from flask_migrate import Migrate
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
import flask_monitoringdashboard as dashboard
|
||||||
|
|
||||||
from app.config import Config
|
from app.conf import load_config
|
||||||
from app.utils.encoders import IPAddressFieldEncoder
|
from app.utils.encoders import IPAddressFieldEncoder
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -18,19 +19,20 @@ logger = logging.getLogger(__name__)
|
|||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
jwt = JWTManager()
|
jwt = JWTManager()
|
||||||
mail = Mail()
|
mail = Mail()
|
||||||
|
|
||||||
migrate = Migrate()
|
migrate = Migrate()
|
||||||
|
|
||||||
CELERY_TASK_LIST = [
|
CELERY_TASK_LIST = [
|
||||||
'app.tasks.hosts',
|
'app.tasks.hosts',
|
||||||
]
|
]
|
||||||
import flask_monitoringdashboard as dashboard
|
|
||||||
|
|
||||||
|
|
||||||
def create_app(app_name='bitchmin', config_class=Config):
|
def create_app(app_name='bitchmin'):
|
||||||
logger.info('Creating app {}'.format(app_name))
|
logger.info('Creating app {}'.format(app_name))
|
||||||
app = Flask(app_name)
|
app = Flask(app_name)
|
||||||
app.config.from_object(config_class)
|
|
||||||
|
app.config.from_object(
|
||||||
|
load_config(os.environ.get('FLASK_ENV'))
|
||||||
|
)
|
||||||
|
|
||||||
logger.info('Creating database {}'.format(app.config['SQLALCHEMY_DATABASE_URI']))
|
logger.info('Creating database {}'.format(app.config['SQLALCHEMY_DATABASE_URI']))
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
@@ -69,6 +71,8 @@ def create_app(app_name='bitchmin', config_class=Config):
|
|||||||
app.logger.addHandler(file_handler)
|
app.logger.addHandler(file_handler)
|
||||||
|
|
||||||
app.json_encoder = IPAddressFieldEncoder
|
app.json_encoder = IPAddressFieldEncoder
|
||||||
|
dashboard.bind(app)
|
||||||
|
dashboard.config.init_from(envvar='FLASK_MONITORING_DASHBOARD_CONFIG')
|
||||||
|
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
|
||||||
@@ -95,6 +99,3 @@ def create_celery_app(app=None):
|
|||||||
|
|
||||||
celery.Task = ContextTask
|
celery.Task = ContextTask
|
||||||
return celery
|
return celery
|
||||||
|
|
||||||
|
|
||||||
celery = create_celery_app()
|
|
||||||
|
|||||||
@@ -1,41 +1,38 @@
|
|||||||
import logging
|
import logging
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from flask import jsonify, request
|
from flask import jsonify, request, current_app
|
||||||
from flask_jwt_extended import (
|
from flask_jwt_extended import (
|
||||||
create_access_token,
|
jwt_refresh_token_required, get_current_user
|
||||||
jwt_refresh_token_required, create_refresh_token,
|
|
||||||
get_current_user
|
|
||||||
)
|
)
|
||||||
|
from sqlalchemy.orm.exc import NoResultFound
|
||||||
|
|
||||||
from app import db, jwt
|
from app import db, jwt
|
||||||
from app.api import api
|
from app.api import api
|
||||||
from app.config import Config
|
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def __create_token(user_id):
|
|
||||||
expiry = timedelta(days=14) if Config.ISDEV else timedelta(minutes=15)
|
|
||||||
return create_access_token(
|
|
||||||
identity=user_id,
|
|
||||||
expires_delta=expiry,
|
|
||||||
fresh=True)
|
|
||||||
|
|
||||||
|
|
||||||
@jwt.user_loader_callback_loader
|
@jwt.user_loader_callback_loader
|
||||||
def user_loader_callback(identity):
|
def user_loader_callback(identity):
|
||||||
return User.by_id(identity)
|
return db.session.query(User).get(identity)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/auth/register/', methods=('POST',))
|
@api.route('/auth/register/', methods=('POST',))
|
||||||
def register():
|
def register():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
user = User(**data)
|
user = User(**data)
|
||||||
db.session.add(user)
|
try:
|
||||||
db.session.commit()
|
db.session.query(User).filter_by(email=user.email).one()
|
||||||
return jsonify(user.to_dict()), 201
|
return jsonify({
|
||||||
|
'status': 'error',
|
||||||
|
'payload': 'User with email {} already exists.'.format(user.email)
|
||||||
|
}), 409
|
||||||
|
except NoResultFound:
|
||||||
|
db.session.add(user)
|
||||||
|
db.session.commit()
|
||||||
|
return jsonify(user.to_dict()), 201
|
||||||
|
|
||||||
|
|
||||||
@api.route('/auth/login/', methods=('POST',))
|
@api.route('/auth/login/', methods=('POST',))
|
||||||
@@ -45,8 +42,8 @@ def login():
|
|||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
return jsonify({'message': 'Invalid credentials', 'authenticated': False}), 401
|
return jsonify({'message': 'Invalid credentials', 'authenticated': False}), 401
|
||||||
access_token = __create_token(user.id)
|
access_token = user.create_token(timedelta(days=14) if current_app.config['ISDEV'] else timedelta(minutes=15))
|
||||||
refresh_token = create_refresh_token(user.id)
|
refresh_token = user.create_refresh_token()
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'accessToken': access_token,
|
'accessToken': access_token,
|
||||||
@@ -61,8 +58,8 @@ def login():
|
|||||||
@jwt_refresh_token_required
|
@jwt_refresh_token_required
|
||||||
def token_refresh():
|
def token_refresh():
|
||||||
user = get_current_user()
|
user = get_current_user()
|
||||||
access_token = __create_token(user.id)
|
access_token = user.create_token()
|
||||||
refresh_token = create_refresh_token(user.id)
|
refresh_token = user.create_refresh_token()
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'accessToken': access_token,
|
'accessToken': access_token,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -17,9 +18,9 @@ from app.utils.iputils import is_valid_ip, is_valid_hostname
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@api.route('/dns/hosts')
|
@api.route('/dns/zones')
|
||||||
def get_hosts():
|
def get_zones():
|
||||||
return DnsZone.get_delete_put_post()
|
return jsonify([zone.to_dict() for zone in db.session.query(DnsZone).all()]), 200
|
||||||
|
|
||||||
|
|
||||||
@api.route('/dns/refresh', methods=['POST'])
|
@api.route('/dns/refresh', methods=['POST'])
|
||||||
|
|||||||
18
bitchmin-api/app/conf/__init__.py
Normal file
18
bitchmin-api/app/conf/__init__.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(mode=os.environ.get('FLASK_ENV')):
|
||||||
|
"""Load config."""
|
||||||
|
try:
|
||||||
|
if mode == 'production':
|
||||||
|
from .production import ProductionConfig
|
||||||
|
return ProductionConfig
|
||||||
|
elif mode == 'testing':
|
||||||
|
from .testing import TestingConfig
|
||||||
|
return TestingConfig
|
||||||
|
else:
|
||||||
|
from .development import DevelopmentConfig
|
||||||
|
return DevelopmentConfig
|
||||||
|
except ImportError:
|
||||||
|
from .config import Config
|
||||||
|
return Config
|
||||||
@@ -4,17 +4,14 @@ from datetime import timedelta
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
basedir = os.path.abspath(os.path.dirname(__file__))
|
basedir = os.path.abspath(os.path.dirname(__file__))
|
||||||
load_dotenv(os.path.join(basedir, '../.env'))
|
load_dotenv(os.path.join(basedir, '../../.env'))
|
||||||
|
|
||||||
ISDEV = os.getenv('FLASK_ENV') == 'development'
|
ISDEV = os.getenv('FLASK_ENV') == 'development'
|
||||||
DEBUG_CONNECTION = 'postgresql+psycopg2://bitchmin:bitchmin@localhost/bitchmin'
|
|
||||||
# DEBUG_CONNECTION = 'sqlite:///' + os.path.join(basedir, '../app.db')
|
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
ISDEV = ISDEV
|
ISDEV = ISDEV
|
||||||
SECRET_KEY = os.getenv('SECRET_KEY') or 'you-will-never-guess'
|
SECRET_KEY = os.getenv('SECRET_KEY') or 'you-will-never-guess'
|
||||||
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or DEBUG_CONNECTION
|
|
||||||
|
|
||||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||||
LOG_TO_STDOUT = os.getenv('LOG_TO_STDOUT')
|
LOG_TO_STDOUT = os.getenv('LOG_TO_STDOUT')
|
||||||
@@ -37,21 +34,3 @@ class Config(object):
|
|||||||
'schedule': timedelta(minutes=15)
|
'schedule': timedelta(minutes=15)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ProductionConfig(Config):
|
|
||||||
DEBUG = False
|
|
||||||
|
|
||||||
|
|
||||||
class StagingConfig(Config):
|
|
||||||
DEVELOPMENT = True
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
|
|
||||||
class DevelopmentConfig(Config):
|
|
||||||
DEVELOPMENT = True
|
|
||||||
DEBUG = True
|
|
||||||
|
|
||||||
|
|
||||||
class TestingConfig(Config):
|
|
||||||
TESTING = True
|
|
||||||
6
bitchmin-api/app/conf/development.py
Normal file
6
bitchmin-api/app/conf/development.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from .config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class DevelopmentConfig(Config):
|
||||||
|
DEBUG = True
|
||||||
|
SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://bitchmin:bitchmin@localhost/bitchmin'
|
||||||
0
bitchmin-api/app/conf/init.py
Normal file
0
bitchmin-api/app/conf/init.py
Normal file
7
bitchmin-api/app/conf/production.py
Normal file
7
bitchmin-api/app/conf/production.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from .config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class ProductionConfig(Config):
|
||||||
|
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
|
||||||
6
bitchmin-api/app/conf/testing.py
Normal file
6
bitchmin-api/app/conf/testing.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from .config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class TestingConfig(Config):
|
||||||
|
TESTING = True
|
||||||
|
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/test.db'
|
||||||
@@ -24,6 +24,12 @@ class DnsNameServer(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
|||||||
self.host = host
|
self.host = host
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
'host': self.host,
|
||||||
|
'ip': self.ip
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
||||||
@@ -48,6 +54,19 @@ class DnsZone(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
|||||||
|
|
||||||
return self._create_serial()
|
return self._create_serial()
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
ret_data = {
|
||||||
|
'name': self.zone_name,
|
||||||
|
'serial': self.serial,
|
||||||
|
'admin': self.admin,
|
||||||
|
'nameservers': [ns.to_dict() for ns in self.nameservers],
|
||||||
|
'hosts': [host.to_dict() for host in self.hosts]
|
||||||
|
}
|
||||||
|
return ret_data
|
||||||
|
|
||||||
|
# TODO: FUCK!!
|
||||||
|
admin = 'Ferg@lMoran.me'
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
zone_name = db.Column(db.String(253), unique=True, nullable=False)
|
zone_name = db.Column(db.String(253), unique=True, nullable=False)
|
||||||
serial = db.Column(db.Integer, default=_create_serial)
|
serial = db.Column(db.Integer, default=_create_serial)
|
||||||
@@ -66,15 +85,24 @@ class DnsHost(db.Model, _BaseModelMixin, FlaskSerializeMixin):
|
|||||||
|
|
||||||
host = db.Column(db.String(255), unique=True, nullable=False)
|
host = db.Column(db.String(255), unique=True, nullable=False)
|
||||||
ip = db.Column(IPAddressType(255), nullable=False)
|
ip = db.Column(IPAddressType(255), nullable=False)
|
||||||
|
type = db.Column(db.String(10), nullable=False)
|
||||||
|
ttl = db.Column(db.Integer(), nullable=False)
|
||||||
|
|
||||||
def __init__(self, zone, host, ip):
|
def __init__(self, zone, host, ip, ttl=30, record_type='A'):
|
||||||
self.zone = zone
|
self.zone = zone
|
||||||
self.host = host
|
self.host = host
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
|
self.ttl = ttl
|
||||||
|
self.type = record_type
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return dict(id=self.id, host=self.host, ip=self.ip)
|
return {
|
||||||
|
'name': self.host,
|
||||||
|
'type': self.type,
|
||||||
|
'ttl': self.ttl,
|
||||||
|
'ip': self.ip,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# @event.listens_for(DnsZone.hosts, 'append')
|
# @event.listens_for(DnsZone.hosts, 'append')
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
from flask_jwt_extended import create_access_token, create_refresh_token
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from werkzeug.security import check_password_hash, generate_password_hash
|
from werkzeug.security import check_password_hash, generate_password_hash
|
||||||
|
|
||||||
@@ -49,6 +50,15 @@ class User(db.Model, _BaseModelMixin):
|
|||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
def create_refresh_token(self):
|
||||||
|
return create_refresh_token(self.id)
|
||||||
|
|
||||||
|
def create_token(self, expiry=timedelta(days=14)):
|
||||||
|
return create_access_token(
|
||||||
|
identity=self.id,
|
||||||
|
expires_delta=expiry,
|
||||||
|
fresh=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def by_id(cls, user_id):
|
def by_id(cls, user_id):
|
||||||
return cls.query.get(user_id)
|
return cls.query.get(user_id)
|
||||||
|
|||||||
32
bitchmin-api/app/tests/conftest.py
Normal file
32
bitchmin-api/app/tests/conftest.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from app import create_app
|
||||||
|
from app import db as _db
|
||||||
|
from seeder import DbSeeder
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def app(request):
|
||||||
|
app = create_app()
|
||||||
|
ctx = app.app_context()
|
||||||
|
ctx.push()
|
||||||
|
|
||||||
|
def teardown():
|
||||||
|
ctx.pop()
|
||||||
|
|
||||||
|
request.addfinalizer(teardown)
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def db(app, request):
|
||||||
|
_db.app = app
|
||||||
|
seeder = DbSeeder(_db)
|
||||||
|
seeder.seed()
|
||||||
|
|
||||||
|
def teardown():
|
||||||
|
seeder.teardown()
|
||||||
|
|
||||||
|
request.addfinalizer(teardown)
|
||||||
|
|
||||||
|
return _db
|
||||||
12
bitchmin-api/app/tests/scaffold.py
Normal file
12
bitchmin-api/app/tests/scaffold.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from app import create_app
|
||||||
|
from seeder import DbSeeder
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = create_app()
|
||||||
|
ctx = app.app_context()
|
||||||
|
ctx.push()
|
||||||
|
from app import db
|
||||||
|
|
||||||
|
db.app = app
|
||||||
|
|
||||||
|
DbSeeder(db).seed()
|
||||||
@@ -1,19 +1,10 @@
|
|||||||
import unittest
|
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
|
||||||
from sqlalchemy.orm import sessionmaker
|
|
||||||
from sqlalchemy.pool import StaticPool
|
|
||||||
|
|
||||||
from app import db
|
|
||||||
from app.models import DnsZone, User, DnsHost, DnsNameServer
|
from app.models import DnsZone, User, DnsHost, DnsNameServer
|
||||||
|
|
||||||
|
|
||||||
class Scaffolder(object):
|
class DbSeeder(object):
|
||||||
engine = create_engine(
|
|
||||||
'postgresql+psycopg2://bitchmin:bitchmin@localhost/bitchmin',
|
def __init__(self, database):
|
||||||
poolclass=StaticPool)
|
self._db = database
|
||||||
Session = sessionmaker(bind=engine)
|
|
||||||
session = Session()
|
|
||||||
|
|
||||||
def _create_user(self):
|
def _create_user(self):
|
||||||
user = User(
|
user = User(
|
||||||
@@ -21,11 +12,11 @@ class Scaffolder(object):
|
|||||||
'Fergal Moran',
|
'Fergal Moran',
|
||||||
'topsecret'
|
'topsecret'
|
||||||
)
|
)
|
||||||
self.session.add(user)
|
self._db.session.add(user)
|
||||||
|
|
||||||
def _create_zone(self):
|
def _create_zone(self):
|
||||||
zone = DnsZone('bitchmints.com')
|
zone = DnsZone('bitchmints.com')
|
||||||
self.session.add(zone)
|
self._db.session.add(zone)
|
||||||
return zone
|
return zone
|
||||||
|
|
||||||
def _create_nameservers(self, zone):
|
def _create_nameservers(self, zone):
|
||||||
@@ -36,7 +27,7 @@ class Scaffolder(object):
|
|||||||
'10.1.1.10{}'.format(i)
|
'10.1.1.10{}'.format(i)
|
||||||
|
|
||||||
)
|
)
|
||||||
self.session.add(ns)
|
self._db.session.add(ns)
|
||||||
|
|
||||||
def _create_hosts(self, zone):
|
def _create_hosts(self, zone):
|
||||||
for i in range(1, 11):
|
for i in range(1, 11):
|
||||||
@@ -45,24 +36,20 @@ class Scaffolder(object):
|
|||||||
'host-{}'.format(i),
|
'host-{}'.format(i),
|
||||||
'10.1.1.{}'.format(i)
|
'10.1.1.{}'.format(i)
|
||||||
)
|
)
|
||||||
self.session.add(host)
|
self._db.session.add(host)
|
||||||
|
|
||||||
def scaffold(self):
|
def seed(self):
|
||||||
db.metadata.drop_all(self.engine)
|
self._db.metadata.drop_all(self._db.engine)
|
||||||
db.metadata.create_all(self.engine)
|
self._db.metadata.create_all(self._db.engine)
|
||||||
|
|
||||||
self._create_user()
|
self._create_user()
|
||||||
z = self._create_zone()
|
z = self._create_zone()
|
||||||
self._create_nameservers(z)
|
self._create_nameservers(z)
|
||||||
self._create_hosts(z)
|
self._create_hosts(z)
|
||||||
|
|
||||||
self.session.commit()
|
self._db.session.commit()
|
||||||
self.session.flush()
|
self._db.session.flush()
|
||||||
|
|
||||||
def teardown(self):
|
def teardown(self):
|
||||||
db.metadata.drop_all(self.engine)
|
self._db.metadata.drop_all(self._db.engine)
|
||||||
self.engine.dispose()
|
self._db.engine.dispose()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
Scaffolder().scaffold()
|
|
||||||
51
bitchmin-api/app/tests/test_auth_routes.py
Normal file
51
bitchmin-api/app/tests/test_auth_routes.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestAuthRoutes:
|
||||||
|
def test_no_duplicate_registration(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
|
||||||
|
request = {
|
||||||
|
'email': 'fergal.moran@gmail.com',
|
||||||
|
'full_name': 'Fergal Moran',
|
||||||
|
'password': 'topsecret'
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = client.post(f"/auth/register/", json=request)
|
||||||
|
assert "409" in rv.status
|
||||||
|
|
||||||
|
def test_registration(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
|
||||||
|
request = {
|
||||||
|
'email': 'fergal.moran+testuser@gmail.com',
|
||||||
|
'full_name': 'Fergal Moran Test User',
|
||||||
|
'password': 'topsecret2'
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = client.post(f"/auth/register/", json=request)
|
||||||
|
assert "201" in rv.status
|
||||||
|
|
||||||
|
def test_login_fails(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
|
||||||
|
request = {
|
||||||
|
'email': 'fergal.moran@gmail.com',
|
||||||
|
'password': 'asdasda'
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = client.post(f"/auth/login/", json=request)
|
||||||
|
assert "401" in rv.status
|
||||||
|
|
||||||
|
def test_login_succeeds(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
|
||||||
|
request = {
|
||||||
|
'email': 'fergal.moran@gmail.com',
|
||||||
|
'password': 'topsecret'
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = client.post(f"/auth/login/", json=request)
|
||||||
|
assert "200" in rv.status
|
||||||
@@ -1,37 +1,22 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import pytest
|
|
||||||
from sqlalchemy import func
|
|
||||||
|
|
||||||
from app.models import User, DnsZone, DnsNameServer, DnsHost
|
from app.models import User, DnsZone, DnsNameServer, DnsHost
|
||||||
from scaffolder import Scaffolder
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function") # or "module" (to teardown at a module level)
|
|
||||||
def db():
|
|
||||||
scaffolder = Scaffolder()
|
|
||||||
scaffolder.teardown()
|
|
||||||
scaffolder.scaffold()
|
|
||||||
|
|
||||||
yield scaffolder.session
|
|
||||||
|
|
||||||
scaffolder.teardown()
|
|
||||||
|
|
||||||
|
|
||||||
class TestDatabaseUpdate:
|
class TestDatabaseUpdate:
|
||||||
def test_load(self, db) -> None:
|
def test_load(self, db) -> None:
|
||||||
assert db.query(User).count() == 1
|
assert db.session.query(User).count() == 1
|
||||||
assert db.query(DnsZone).count() == 1
|
assert db.session.query(DnsZone).count() == 1
|
||||||
assert db.query(DnsNameServer).count() == 2
|
assert db.session.query(DnsNameServer).count() == 2
|
||||||
assert db.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:
|
||||||
zone = db.query(DnsZone).first()
|
zone = db.session.query(DnsZone).first()
|
||||||
assert len(str(zone.serial)) == 10
|
assert len(str(zone.serial)) == 10
|
||||||
assert zone.get_serial_increment() == 10
|
assert zone.get_serial_increment() == 10
|
||||||
|
|
||||||
def test_serial_on_add_host(self, db) -> None:
|
def test_serial_on_add_host(self, db) -> None:
|
||||||
zone = db.query(DnsZone).first()
|
zone = db.session.query(DnsZone).first()
|
||||||
serial = zone.get_serial_increment()
|
serial = zone.get_serial_increment()
|
||||||
|
|
||||||
DnsHost(
|
DnsHost(
|
||||||
@@ -39,7 +24,7 @@ class TestDatabaseUpdate:
|
|||||||
host=str(uuid.uuid4()),
|
host=str(uuid.uuid4()),
|
||||||
ip='99.99.99.99'
|
ip='99.99.99.99'
|
||||||
)
|
)
|
||||||
db.commit()
|
db.session.commit()
|
||||||
"""
|
"""
|
||||||
Probably better to test that the new serial is > old serial...
|
Probably better to test that the new serial is > old serial...
|
||||||
Not hugely important that it's only ONE more than it
|
Not hugely important that it's only ONE more than it
|
||||||
@@ -47,11 +32,10 @@ class TestDatabaseUpdate:
|
|||||||
assert zone.get_serial_increment() > serial
|
assert zone.get_serial_increment() > serial
|
||||||
|
|
||||||
def test_serial_on_update_host(self, db) -> None:
|
def test_serial_on_update_host(self, db) -> None:
|
||||||
host = db.query(DnsHost).get(4)
|
host = db.session.query(DnsHost).get(4)
|
||||||
serial = host.zone.get_serial_increment()
|
serial = host.zone.get_serial_increment()
|
||||||
|
|
||||||
host.ip = '99.99.99.99'
|
host.ip = '99.99.99.99'
|
||||||
db.commit()
|
db.session.commit()
|
||||||
|
|
||||||
assert host.zone.get_serial_increment() > serial
|
assert host.zone.get_serial_increment() > serial
|
||||||
|
|
||||||
20
bitchmin-api/app/tests/test_dns_routes.py
Normal file
20
bitchmin-api/app/tests/test_dns_routes.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import json
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestUserRoutes:
|
||||||
|
|
||||||
|
def test_get_hosts(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
rv = client.get(f"/dns/zones")
|
||||||
|
assert "200" in rv.status
|
||||||
|
zones = json.loads(rv.data)
|
||||||
|
assert len(zones) == 1
|
||||||
|
assert zones[0]['name'] == 'bitchmints.com'
|
||||||
|
assert len(zones[0]['nameservers']) == 2
|
||||||
|
assert zones[0]['nameservers'][0]['host'] == 'host-1'
|
||||||
|
assert zones[0]['nameservers'][1]['host'] == 'host-2'
|
||||||
|
assert zones[0]['nameservers'][0]['ip'] == '10.1.1.101'
|
||||||
|
assert zones[0]['nameservers'][1]['ip'] == '10.1.1.102'
|
||||||
12
bitchmin-api/app/tests/test_ping_routes.py
Normal file
12
bitchmin-api/app/tests/test_ping_routes.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestUserRoutes:
|
||||||
|
|
||||||
|
def test_user_get(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
rv = client.get(f"/ping")
|
||||||
|
assert "200" in rv.status
|
||||||
|
assert "pong!" in str(rv.data)
|
||||||
14
bitchmin-api/app/tests/test_user_routes.py
Normal file
14
bitchmin-api/app/tests/test_user_routes.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestUserRoutes:
|
||||||
|
|
||||||
|
def test_user_get(self, db, app) -> None:
|
||||||
|
client = app.test_client()
|
||||||
|
user = db.session.query(User).first()
|
||||||
|
token = user.create_token(timedelta(seconds=60))
|
||||||
|
|
||||||
|
rv = client.get(f"/user", headers={"Authorization": "Bearer {}".format(token)})
|
||||||
|
assert "200" in rv.status
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
source venv/bin/activate
|
|
||||||
flask db upgrade
|
flask db upgrade
|
||||||
exec gunicorn -b :5000 --access-logfile - --error-logfile - server:app
|
exec gunicorn -b :5000 --access-logfile - --error-logfile - server:app
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--push \
|
--push \
|
||||||
--platform linux/arm/v7,linux/amd64 \
|
--platform linux/arm/v7 \
|
||||||
-t fergalmoran/bitchmin-api .
|
-t fergalmoran/bitchmin-api .
|
||||||
|
|||||||
BIN
bitchmin-api/flask_monitoringdashboard.db
Normal file
BIN
bitchmin-api/flask_monitoringdashboard.db
Normal file
Binary file not shown.
@@ -24,8 +24,8 @@ logger = logging.getLogger('alembic.env')
|
|||||||
from flask import current_app
|
from flask import current_app
|
||||||
config.set_main_option(
|
config.set_main_option(
|
||||||
'sqlalchemy.url',
|
'sqlalchemy.url',
|
||||||
str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%'))
|
str(current_app.extensions['migrate']._db.engine.url).replace('%', '%%'))
|
||||||
target_metadata = current_app.extensions['migrate'].db.metadata
|
target_metadata = current_app.extensions['migrate']._db.metadata
|
||||||
|
|
||||||
# other values from the config, defined by the needs of env.py,
|
# other values from the config, defined by the needs of env.py,
|
||||||
# can be acquired:
|
# can be acquired:
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
ls
|
|
||||||
rm -rf migrations || \
|
|
||||||
rm bitchmin/bitchmin.db || \
|
|
||||||
flask db init || \
|
|
||||||
flask db migrate -m "Initial" || \
|
|
||||||
flask db upgrade
|
|
||||||
@@ -20,7 +20,9 @@ sqlalchemy
|
|||||||
requests
|
requests
|
||||||
IPy
|
IPy
|
||||||
pydig
|
pydig
|
||||||
tinder
|
|
||||||
twilio
|
twilio
|
||||||
flask_monitoringdashboard
|
flask_monitoringdashboard
|
||||||
pytest
|
jinja2==2.11.1
|
||||||
|
pytest
|
||||||
|
pytest-flask
|
||||||
|
pytest-flask-sqlalchemy
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
from flask_migrate import Migrate, upgrade
|
from flask_migrate import Migrate, upgrade
|
||||||
from app import create_app, db
|
from app import create_app, db, create_celery_app
|
||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
celery = create_celery_app()
|
||||||
|
|
||||||
migrate = Migrate(app, db)
|
migrate = Migrate(app, db)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
BitchMin
|
|
||||||
17
bitchmin-server/Dockerfile
Normal file
17
bitchmin-server/Dockerfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
FROM python:3.7-alpine
|
||||||
|
|
||||||
|
RUN apk add --update alpine-sdk
|
||||||
|
|
||||||
|
COPY requirements.txt /
|
||||||
|
RUN pip install -r /requirements.txt
|
||||||
|
|
||||||
|
COPY . /app
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV DNS_PORT 53
|
||||||
|
ENV WORKER_PORT 10054
|
||||||
|
|
||||||
|
EXPOSE 53
|
||||||
|
EXPOSE 10054
|
||||||
|
|
||||||
|
CMD [ "python", "./server.py" ]
|
||||||
0
bitchmin-server/models/__init__.py
Normal file
0
bitchmin-server/models/__init__.py
Normal file
69
bitchmin-server/models/zone.py
Normal file
69
bitchmin-server/models/zone.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import json
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
|
||||||
|
class Zone(object):
|
||||||
|
def __init__(self, serial, name, admin, hosts):
|
||||||
|
self._serial = serial
|
||||||
|
self._name = name
|
||||||
|
self._admin = admin
|
||||||
|
self._hosts = hosts
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_json(data):
|
||||||
|
try:
|
||||||
|
zones = json.loads(data, object_hook=lambda d: SimpleNamespace(**d))
|
||||||
|
return [Zone(
|
||||||
|
x.serial,
|
||||||
|
x.name,
|
||||||
|
x.admin,
|
||||||
|
{h.name: Host(
|
||||||
|
h.ip,
|
||||||
|
h.name,
|
||||||
|
h.ttl,
|
||||||
|
h.type
|
||||||
|
) for h in x.hosts}
|
||||||
|
) for x in zones]
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def admin(self):
|
||||||
|
return self._admin
|
||||||
|
|
||||||
|
@property
|
||||||
|
def serial(self):
|
||||||
|
return self._serial
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hosts(self):
|
||||||
|
return self._hosts
|
||||||
|
|
||||||
|
|
||||||
|
class Host(object):
|
||||||
|
|
||||||
|
def __init__(self, ip, name, ttl, record_type):
|
||||||
|
self._ip = ip
|
||||||
|
self._name = name
|
||||||
|
self._ttl = ttl
|
||||||
|
self._record_type = record_type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ip(self):
|
||||||
|
return self._ip
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ttl(self):
|
||||||
|
return self._ttl
|
||||||
|
|
||||||
|
@property
|
||||||
|
def record_type(self):
|
||||||
|
return self._record_type
|
||||||
@@ -1 +1,4 @@
|
|||||||
twisted
|
twisted
|
||||||
|
pytest
|
||||||
|
dnspython
|
||||||
|
requests
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import requests
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.names import dns, error
|
from twisted.names import dns, error
|
||||||
import logging
|
import logging
|
||||||
@@ -8,7 +9,8 @@ class InvalidZoneException(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class Resolver:
|
class Resolver:
|
||||||
def _build_host(self, record_type, host, ip, ttl):
|
@staticmethod
|
||||||
|
def _build_host(record_type, host, ip, ttl):
|
||||||
return {
|
return {
|
||||||
host: {
|
host: {
|
||||||
'type': record_type,
|
'type': record_type,
|
||||||
@@ -68,7 +70,7 @@ class MemoryResolver(Resolver):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
host = self._parse_host(zone, str(query.name))
|
host = self._parse_host(zone, str(query.name))
|
||||||
record = self._zones[zone]['hosts'][host]
|
record = self._zones[zone].hosts[host]
|
||||||
|
|
||||||
if query.type == dns.NS:
|
if query.type == dns.NS:
|
||||||
payload = dns.Record_NS(
|
payload = dns.Record_NS(
|
||||||
@@ -77,14 +79,14 @@ class MemoryResolver(Resolver):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
payload = dns.Record_A(
|
payload = dns.Record_A(
|
||||||
address=record['ip'],
|
address=record.ip,
|
||||||
ttl=record['ttl']
|
ttl=record.ttl
|
||||||
)
|
)
|
||||||
|
|
||||||
answer = dns.RRHeader(
|
answer = dns.RRHeader(
|
||||||
name=zone,
|
name=zone,
|
||||||
payload=payload,
|
payload=payload,
|
||||||
ttl=record['ttl']
|
ttl=record.ttl
|
||||||
)
|
)
|
||||||
|
|
||||||
answers = [answer]
|
answers = [answer]
|
||||||
|
|||||||
@@ -1,56 +1,40 @@
|
|||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
import requests
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet.endpoints import TCP4ServerEndpoint
|
from twisted.internet.endpoints import TCP4ServerEndpoint
|
||||||
from twisted.names import client, dns, server
|
from twisted.names import client, dns, server
|
||||||
|
|
||||||
|
from models.zone import Zone
|
||||||
from resolvers.memory_resolver import MemoryResolver
|
from resolvers.memory_resolver import MemoryResolver
|
||||||
from servers.worker_server import WorkerServerFactory
|
from servers.worker_server import WorkerServerFactory
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
PORT = 10053
|
PORT = os.environ.get('DNS_PORT') or 10053
|
||||||
WORKER_PORT = 10054
|
WORKER_PORT = os.environ.get('WORKER_PORT') or 10054
|
||||||
|
API_HOST = os.environ.get('API_HOST') or 'http://localhost:5000/dns/zones'
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: This smells
|
||||||
|
def get_zones():
|
||||||
|
response = requests.get(API_HOST)
|
||||||
|
zones = Zone.from_json(response.text)
|
||||||
|
return {
|
||||||
|
zone.name: zone
|
||||||
|
for zone in zones}
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
zones = {
|
zones = get_zones()
|
||||||
'bitchmints.com': {
|
|
||||||
'serial': 'BOOO',
|
|
||||||
'admin': 'Ferg@lMoran.me',
|
|
||||||
'nameservers': [
|
|
||||||
'ns1.bitchmints.com',
|
|
||||||
'ns2.bitchmints.com'
|
|
||||||
],
|
|
||||||
'hosts': {
|
|
||||||
'ns1': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.7'},
|
|
||||||
'ns2': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.8'},
|
|
||||||
'host-1': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.1'},
|
|
||||||
'host-2': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.1'},
|
|
||||||
'host-3': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.1'},
|
|
||||||
'host-4': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.1'},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'fergl.ie': {
|
|
||||||
'serial': 'BOOO',
|
|
||||||
'admin': 'Ferg@lMoran.me',
|
|
||||||
'nameservers': [
|
|
||||||
'ns1.bitchmints.com',
|
|
||||||
'ns2.bitchmints.com'
|
|
||||||
],
|
|
||||||
'hosts': {
|
|
||||||
'farts': {'type': 'A', 'ttl': 30, 'ip': '10.1.33.8'},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memory_resolver = MemoryResolver(zones)
|
memory_resolver = MemoryResolver(zones)
|
||||||
|
|
||||||
dns_factory = server.DNSServerFactory(
|
dns_factory = server.DNSServerFactory(
|
||||||
clients=[
|
clients=[
|
||||||
memory_resolver,
|
memory_resolver,
|
||||||
client.Resolver(resolv='/etc/resolv.conf')]
|
client.Resolver(resolv='/etc/resolv.conf')]
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
protocol = dns.DNSDatagramProtocol(controller=dns_factory)
|
protocol = dns.DNSDatagramProtocol(controller=dns_factory)
|
||||||
|
|||||||
0
bitchmin-server/tests/__init__.py
Normal file
0
bitchmin-server/tests/__init__.py
Normal file
14
bitchmin-server/tests/conftest.py
Normal file
14
bitchmin-server/tests/conftest.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def resolver():
|
||||||
|
import dns.resolver
|
||||||
|
|
||||||
|
r = dns.resolver.Resolver()
|
||||||
|
|
||||||
|
r.nameservers = ['127.0.0.1']
|
||||||
|
r.nameserver_ports = {
|
||||||
|
'127.0.0.1': 10053
|
||||||
|
}
|
||||||
|
return r
|
||||||
4
bitchmin-server/tests/test_lookups.py
Normal file
4
bitchmin-server/tests/test_lookups.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
def test_zones_exist(resolver) -> None:
|
||||||
|
answer = resolver.resolve('host-1.bitchmints.com')
|
||||||
|
|
||||||
|
assert answer.address == '10.1.1.1'
|
||||||
153
working/dns-test/.editorconfig
Normal file
153
working/dns-test/.editorconfig
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
###############################
|
||||||
|
# Core EditorConfig Options #
|
||||||
|
###############################
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# All files
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# Code files
|
||||||
|
[*.{cs,csx,vb,vbx}]
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8-bom
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# .NET Coding Conventions #
|
||||||
|
###############################
|
||||||
|
|
||||||
|
[*.{cs,vb}]
|
||||||
|
# Organize usings
|
||||||
|
dotnet_sort_system_directives_first = true
|
||||||
|
dotnet_separate_import_directive_groups = false
|
||||||
|
|
||||||
|
# this. preferences
|
||||||
|
dotnet_style_qualification_for_field = false:silent
|
||||||
|
dotnet_style_qualification_for_property = false:silent
|
||||||
|
dotnet_style_qualification_for_method = false:silent
|
||||||
|
dotnet_style_qualification_for_event = false:silent
|
||||||
|
|
||||||
|
# Language keywords vs BCL types preferences
|
||||||
|
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||||
|
dotnet_style_predefined_type_for_member_access = true:silent
|
||||||
|
|
||||||
|
# Parentheses preferences
|
||||||
|
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||||
|
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||||
|
|
||||||
|
# Modifier preferences
|
||||||
|
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||||
|
dotnet_style_readonly_field = true:suggestion
|
||||||
|
|
||||||
|
# Expression-level preferences
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
|
||||||
|
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||||
|
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||||
|
dotnet_style_prefer_auto_properties = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# Naming Conventions #
|
||||||
|
###############################
|
||||||
|
|
||||||
|
# Style Definitions
|
||||||
|
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||||
|
|
||||||
|
# Use PascalCase for constant fields
|
||||||
|
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
||||||
|
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
||||||
|
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
||||||
|
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||||
|
|
||||||
|
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
|
||||||
|
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore
|
||||||
|
dotnet_naming_rule.private_members_with_underscore.severity = suggestion
|
||||||
|
dotnet_naming_symbols.private_fields.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
|
||||||
|
dotnet_naming_style.prefix_underscore.capitalization = camel_case
|
||||||
|
dotnet_naming_style.prefix_underscore.required_prefix = _
|
||||||
|
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# C# Code Style Rules #
|
||||||
|
###############################
|
||||||
|
|
||||||
|
[*.cs]
|
||||||
|
# var preferences
|
||||||
|
csharp_style_var_for_built_in_types = true:silent
|
||||||
|
csharp_style_var_when_type_is_apparent = true:silent
|
||||||
|
csharp_style_var_elsewhere = true:silent
|
||||||
|
|
||||||
|
# Expression-bodied members
|
||||||
|
csharp_style_expression_bodied_methods = false:silent
|
||||||
|
csharp_style_expression_bodied_constructors = false:silent
|
||||||
|
csharp_style_expression_bodied_operators = false:silent
|
||||||
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
|
|
||||||
|
# Pattern-matching preferences
|
||||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
|
|
||||||
|
# Null-checking preferences
|
||||||
|
csharp_style_throw_expression = true:suggestion
|
||||||
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
|
||||||
|
# Modifier preferences
|
||||||
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||||
|
|
||||||
|
# Expression-level preferences
|
||||||
|
csharp_prefer_braces = true:silent
|
||||||
|
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||||
|
csharp_prefer_simple_default_expression = true:suggestion
|
||||||
|
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||||
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
|
|
||||||
|
###############################
|
||||||
|
# C# Formatting Rules #
|
||||||
|
###############################
|
||||||
|
|
||||||
|
# New line preferences
|
||||||
|
csharp_new_line_before_open_brace = false
|
||||||
|
csharp_new_line_before_else = false
|
||||||
|
csharp_new_line_before_catch = false
|
||||||
|
csharp_new_line_before_finally = false
|
||||||
|
csharp_new_line_before_members_in_object_initializers = false
|
||||||
|
csharp_new_line_before_members_in_anonymous_types = false
|
||||||
|
csharp_new_line_between_query_expression_clauses = false
|
||||||
|
|
||||||
|
# Indentation preferences
|
||||||
|
csharp_indent_case_contents = true
|
||||||
|
csharp_indent_switch_labels = true
|
||||||
|
csharp_indent_labels = flush_left
|
||||||
|
|
||||||
|
# Space preferences
|
||||||
|
csharp_space_after_cast = false
|
||||||
|
csharp_space_after_keywords_in_control_flow_statements = true
|
||||||
|
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_parentheses = false
|
||||||
|
csharp_space_before_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_after_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_around_binary_operators = before_and_after
|
||||||
|
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||||
|
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||||
|
|
||||||
|
# Wrapping preferences
|
||||||
|
csharp_preserve_single_line_statements = true
|
||||||
|
csharp_preserve_single_line_blocks = true
|
||||||
27
working/dns-test/Program.cs
Normal file
27
working/dns-test/Program.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using DnsClient;
|
||||||
|
using DnsClient.Protocol;
|
||||||
|
|
||||||
|
Console.WriteLine("Testing lookup");
|
||||||
|
|
||||||
|
var endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10053);
|
||||||
|
var client = new LookupClient(endpoint);
|
||||||
|
|
||||||
|
for (int i = 1; i <= 10; i++) {
|
||||||
|
var host = $"host-{i}.bitchmints.com";
|
||||||
|
Console.WriteLine($"Performing lookup for {host}");
|
||||||
|
var results = client
|
||||||
|
.Query(host, QueryType.A)
|
||||||
|
.Answers
|
||||||
|
.ARecords();
|
||||||
|
|
||||||
|
if (results.Any()) {
|
||||||
|
foreach (var aRecord in results) {
|
||||||
|
Console.WriteLine($"\tDomain: {aRecord.DomainName} resolved to {aRecord.Address}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Console.WriteLine($"\tDomain: {host} was not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
working/dns-test/bin/Debug/net5.0/DnsClient.dll
Executable file
BIN
working/dns-test/bin/Debug/net5.0/DnsClient.dll
Executable file
Binary file not shown.
BIN
working/dns-test/bin/Debug/net5.0/dns-test
Executable file
BIN
working/dns-test/bin/Debug/net5.0/dns-test
Executable file
Binary file not shown.
41
working/dns-test/bin/Debug/net5.0/dns-test.deps.json
Normal file
41
working/dns-test/bin/Debug/net5.0/dns-test.deps.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"runtimeTarget": {
|
||||||
|
"name": ".NETCoreApp,Version=v5.0",
|
||||||
|
"signature": ""
|
||||||
|
},
|
||||||
|
"compilationOptions": {},
|
||||||
|
"targets": {
|
||||||
|
".NETCoreApp,Version=v5.0": {
|
||||||
|
"dns-test/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"DnsClient": "1.3.2"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"dns-test.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"DnsClient/1.3.2": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.1/DnsClient.dll": {
|
||||||
|
"assemblyVersion": "1.3.2.0",
|
||||||
|
"fileVersion": "1.3.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"dns-test/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
},
|
||||||
|
"DnsClient/1.3.2": {
|
||||||
|
"type": "package",
|
||||||
|
"serviceable": true,
|
||||||
|
"sha512": "sha512-+3pku+O8VzuAirIezOhOa0rz0bK5SDtDgYUzVDbKxzFj9/zsMjvUAqS6kkxnUyX4d3L5d5MRR7gF2wLudODBYg==",
|
||||||
|
"path": "dnsclient/1.3.2",
|
||||||
|
"hashPath": "dnsclient.1.3.2.nupkg.sha512"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
working/dns-test/bin/Debug/net5.0/dns-test.dll
Normal file
BIN
working/dns-test/bin/Debug/net5.0/dns-test.dll
Normal file
Binary file not shown.
BIN
working/dns-test/bin/Debug/net5.0/dns-test.pdb
Normal file
BIN
working/dns-test/bin/Debug/net5.0/dns-test.pdb
Normal file
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"additionalProbingPaths": [
|
||||||
|
"/home/fergalm/.dotnet/store/|arch|/|tfm|",
|
||||||
|
"/home/fergalm/.nuget/packages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net5.0",
|
||||||
|
"framework": {
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "5.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
working/dns-test/bin/Debug/net5.0/ref/dns-test.dll
Normal file
BIN
working/dns-test/bin/Debug/net5.0/ref/dns-test.dll
Normal file
Binary file not shown.
13
working/dns-test/dns-test.csproj
Normal file
13
working/dns-test/dns-test.csproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
<RootNamespace>dns_test</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="DnsClient" Version="1.3.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// <autogenerated />
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")]
|
||||||
BIN
working/dns-test/obj/Debug/net5.0/apphost
Executable file
BIN
working/dns-test/obj/Debug/net5.0/apphost
Executable file
Binary file not shown.
23
working/dns-test/obj/Debug/net5.0/dns-test.AssemblyInfo.cs
Normal file
23
working/dns-test/obj/Debug/net5.0/dns-test.AssemblyInfo.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
[assembly: System.Reflection.AssemblyCompanyAttribute("dns-test")]
|
||||||
|
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||||
|
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||||
|
[assembly: System.Reflection.AssemblyProductAttribute("dns-test")]
|
||||||
|
[assembly: System.Reflection.AssemblyTitleAttribute("dns-test")]
|
||||||
|
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||||
|
|
||||||
|
// Generated by the MSBuild WriteCodeFragment class.
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
9f361857c6c60ffd4891f6a8e0304ff6fe4b537e
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
is_global = true
|
||||||
|
build_property.TargetFramework = net5.0
|
||||||
|
build_property.TargetPlatformMinVersion =
|
||||||
|
build_property.UsingMicrosoftNETSdkWeb =
|
||||||
|
build_property.ProjectTypeGuids =
|
||||||
|
build_property.PublishSingleFile =
|
||||||
|
build_property.IncludeAllContentForSelfExtract =
|
||||||
|
build_property._SupportedPlatformList = Android,iOS,Linux,macOS,Windows
|
||||||
BIN
working/dns-test/obj/Debug/net5.0/dns-test.assets.cache
Normal file
BIN
working/dns-test/obj/Debug/net5.0/dns-test.assets.cache
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
70cfeda8d1e9e2eb58e13e423a234b2e09b3c59b
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/dns-test
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/dns-test.deps.json
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/dns-test.runtimeconfig.json
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/dns-test.runtimeconfig.dev.json
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/dns-test.dll
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/ref/dns-test.dll
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/dns-test.pdb
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.csprojAssemblyReference.cache
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.GeneratedMSBuildEditorConfig.editorconfig
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.AssemblyInfoInputs.cache
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.AssemblyInfo.cs
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.csproj.CoreCompileInputs.cache
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.dll
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/ref/dns-test.dll
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.pdb
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.genruntimeconfig.cache
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/bin/Debug/net5.0/DnsClient.dll
|
||||||
|
/home/fergalm/dev/BitchMin/working/dns-test/obj/Debug/net5.0/dns-test.csproj.CopyComplete
|
||||||
Binary file not shown.
BIN
working/dns-test/obj/Debug/net5.0/dns-test.dll
Normal file
BIN
working/dns-test/obj/Debug/net5.0/dns-test.dll
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
1e5a2e58d8a5d8f0bca0aaa4ee624df8facbe5c3
|
||||||
BIN
working/dns-test/obj/Debug/net5.0/dns-test.pdb
Normal file
BIN
working/dns-test/obj/Debug/net5.0/dns-test.pdb
Normal file
Binary file not shown.
BIN
working/dns-test/obj/Debug/net5.0/ref/dns-test.dll
Normal file
BIN
working/dns-test/obj/Debug/net5.0/ref/dns-test.dll
Normal file
Binary file not shown.
66
working/dns-test/obj/dns-test.csproj.nuget.dgspec.json
Normal file
66
working/dns-test/obj/dns-test.csproj.nuget.dgspec.json
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"format": 1,
|
||||||
|
"restore": {
|
||||||
|
"/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj": {}
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj",
|
||||||
|
"projectName": "dns-test",
|
||||||
|
"projectPath": "/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj",
|
||||||
|
"packagesPath": "/home/fergalm/.nuget/packages/",
|
||||||
|
"outputPath": "/home/fergalm/dev/BitchMin/working/dns-test/obj/",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"configFilePaths": [
|
||||||
|
"/home/fergalm/.nuget/NuGet/NuGet.Config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net5.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"https://api.nuget.org/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net5.0": {
|
||||||
|
"targetAlias": "net5.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net5.0": {
|
||||||
|
"targetAlias": "net5.0",
|
||||||
|
"dependencies": {
|
||||||
|
"DnsClient": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.3.2, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "/home/fergalm/dotnet/sdk/5.0.100/RuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
working/dns-test/obj/dns-test.csproj.nuget.g.props
Normal file
18
working/dns-test/obj/dns-test.csproj.nuget.g.props
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||||
|
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||||
|
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||||
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/fergalm/.nuget/packages/</NuGetPackageRoot>
|
||||||
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/fergalm/.nuget/packages/</NuGetPackageFolders>
|
||||||
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">5.8.0</NuGetToolVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
|
<SourceRoot Include="$([MSBuild]::EnsureTrailingSlash($(NuGetPackageFolders)))" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
6
working/dns-test/obj/dns-test.csproj.nuget.g.targets
Normal file
6
working/dns-test/obj/dns-test.csproj.nuget.g.targets
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||||
|
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
106
working/dns-test/obj/project.assets.json
Normal file
106
working/dns-test/obj/project.assets.json
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"targets": {
|
||||||
|
"net5.0": {
|
||||||
|
"DnsClient/1.3.2": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/netstandard2.1/DnsClient.dll": {}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.1/DnsClient.dll": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"DnsClient/1.3.2": {
|
||||||
|
"sha512": "+3pku+O8VzuAirIezOhOa0rz0bK5SDtDgYUzVDbKxzFj9/zsMjvUAqS6kkxnUyX4d3L5d5MRR7gF2wLudODBYg==",
|
||||||
|
"type": "package",
|
||||||
|
"path": "dnsclient/1.3.2",
|
||||||
|
"files": [
|
||||||
|
".nupkg.metadata",
|
||||||
|
".signature.p7s",
|
||||||
|
"dnsclient.1.3.2.nupkg.sha512",
|
||||||
|
"dnsclient.nuspec",
|
||||||
|
"icon.png",
|
||||||
|
"lib/net45/DnsClient.dll",
|
||||||
|
"lib/net45/DnsClient.xml",
|
||||||
|
"lib/net471/DnsClient.dll",
|
||||||
|
"lib/net471/DnsClient.xml",
|
||||||
|
"lib/netstandard1.3/DnsClient.dll",
|
||||||
|
"lib/netstandard1.3/DnsClient.xml",
|
||||||
|
"lib/netstandard2.0/DnsClient.dll",
|
||||||
|
"lib/netstandard2.0/DnsClient.xml",
|
||||||
|
"lib/netstandard2.1/DnsClient.dll",
|
||||||
|
"lib/netstandard2.1/DnsClient.xml"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"projectFileDependencyGroups": {
|
||||||
|
"net5.0": [
|
||||||
|
"DnsClient >= 1.3.2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"packageFolders": {
|
||||||
|
"/home/fergalm/.nuget/packages/": {}
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"restore": {
|
||||||
|
"projectUniqueName": "/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj",
|
||||||
|
"projectName": "dns-test",
|
||||||
|
"projectPath": "/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj",
|
||||||
|
"packagesPath": "/home/fergalm/.nuget/packages/",
|
||||||
|
"outputPath": "/home/fergalm/dev/BitchMin/working/dns-test/obj/",
|
||||||
|
"projectStyle": "PackageReference",
|
||||||
|
"configFilePaths": [
|
||||||
|
"/home/fergalm/.nuget/NuGet/NuGet.Config"
|
||||||
|
],
|
||||||
|
"originalTargetFrameworks": [
|
||||||
|
"net5.0"
|
||||||
|
],
|
||||||
|
"sources": {
|
||||||
|
"https://api.nuget.org/v3/index.json": {}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net5.0": {
|
||||||
|
"targetAlias": "net5.0",
|
||||||
|
"projectReferences": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warningProperties": {
|
||||||
|
"warnAsError": [
|
||||||
|
"NU1605"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net5.0": {
|
||||||
|
"targetAlias": "net5.0",
|
||||||
|
"dependencies": {
|
||||||
|
"DnsClient": {
|
||||||
|
"target": "Package",
|
||||||
|
"version": "[1.3.2, )"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"imports": [
|
||||||
|
"net461",
|
||||||
|
"net462",
|
||||||
|
"net47",
|
||||||
|
"net471",
|
||||||
|
"net472",
|
||||||
|
"net48"
|
||||||
|
],
|
||||||
|
"assetTargetFallback": true,
|
||||||
|
"warn": true,
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtimeIdentifierGraphPath": "/home/fergalm/dotnet/sdk/5.0.100/RuntimeIdentifierGraph.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
working/dns-test/obj/project.nuget.cache
Normal file
10
working/dns-test/obj/project.nuget.cache
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"dgSpecHash": "eyFn1mF0Ec0RODelM//pl87ne40rmd2/fm30g+WxWQ97TpqhUsZ79YryHC9MGUYH+wDk/epuUARQ5ofTUycO6w==",
|
||||||
|
"success": true,
|
||||||
|
"projectFilePath": "/home/fergalm/dev/BitchMin/working/dns-test/dns-test.csproj",
|
||||||
|
"expectedPackageFiles": [
|
||||||
|
"/home/fergalm/.nuget/packages/dnsclient/1.3.2/dnsclient.1.3.2.nupkg.sha512"
|
||||||
|
],
|
||||||
|
"logs": []
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user