diff --git a/app/models.py b/app/models.py index 82f3eb4..a8b01fa 100644 --- a/app/models.py +++ b/app/models.py @@ -8,6 +8,7 @@ from . import db, lm import os import random +import uuid import base64 import hashlib import json @@ -65,6 +66,7 @@ class User(db.Model, UserMixin): twofactor = db.Column(db.Boolean, default=False) #optional 2factor auth otp_secret = db.Column(db.String) avatar_hash = db.Column(db.String) + uuid = db.Column(db.String) name = db.Column(db.Unicode) address = db.Column(db.Unicode) @@ -83,6 +85,7 @@ class User(db.Model, UserMixin): wallet = db.Column(db.Float) currency = db.Column(db.String, default='BGN') + inv_routers = db.relationship('Router', backref='owner', lazy='dynamic') inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic') inv_services = db.relationship('Service', backref='owner', lazy='dynamic') inv_domains = db.relationship('Domain', backref='owner', lazy='dynamic') @@ -100,13 +103,17 @@ class User(db.Model, UserMixin): #if role is stil not set, create default user role self.role = Role.query.filter_by(default=True).first() - if self.email is not None and self.avatar_hash is None: + if self.avatar_hash is None and self.email is not None: self.avatar_hash = hashlib.md5(self.email.encode('utf-8')).hexdigest() if self.otp_secret is None: # generate a random secret self.otp_secret = base64.b32encode(os.urandom(10)).decode('utf-8') + if self.uuid is None: + # generate uuid + self.uuid = uuid.uuid4() + @property def password(self): raise AttributeError('password is not a readable attribute') @@ -222,6 +229,14 @@ def contact_proxmaster(data, method, cubeid=0): except: return None +class Router(db.Model): + __tablename__ = 'routers' + pid = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK + date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) + cancelled = db.Column(db.Boolean, default=False) + + class Deployment(db.Model): __tablename__ = 'deployments' pid = db.Column(db.Integer, primary_key=True) diff --git a/app/vmanager/routes.py b/app/vmanager/routes.py index aae41cd..de40f82 100644 --- a/app/vmanager/routes.py +++ b/app/vmanager/routes.py @@ -46,9 +46,29 @@ def createvm(): #flash('Region: {}'.format(str(selected_region.description))) #return redirect(url_for('main.dashboard')) + router = current_user.inv_routers.filter_by(cancelled=False).all() + if router == []: + #no router. creating... + data = { 'clientid': str(current_user.pid), + 'clientemail': str(current_user.email), + 'hostname': 'c' + str(current_user.pid) + 'router', + 'region': str(selected_region.name), + 'type': 'kvm', + 'cpu': '1', + 'mem': '128', + 'hdd': '1' + } + try: + query = contact_procmaster(data, 'vmcreate') + except: + flash('Region unreachable! Cannot create router. Please try again later...') + return redirect(url_for('main.dashboard')) + #exit 0 + return redirect(url_for('main.dashboard')) + data = { 'clientid': str(current_user.pid), 'clientemail': str(current_user.email), - 'hostname': str(form.servername.data), + 'hostname': 'c' + str(current_user.pid) + str(form.servername.data), 'region': str(selected_region.name), 'type': 'kvm', 'cpu': '1', @@ -58,7 +78,7 @@ def createvm(): try: query = contact_proxmaster(data, 'vmcreate') except: - flash('Region unreachable! Please try again later...') + flash('Region unreachable! Cannot create deployment. Please try again later...') return redirect(url_for('main.dashboard')) if query is not None: @@ -82,6 +102,8 @@ def remove(itemid=0): query = contact_proxmaster(data, 'vmremove', int(itemid)) flash('Machine {} terminated'.format(itemid)) deploy.cancelled = True + deploy.enabled = False + deploy.warning = False db.session.commit() except: flash('Cannot delete machine {}'.format(itemid)) diff --git a/LICENSE b/docs/LICENSE similarity index 100% rename from LICENSE rename to docs/LICENSE diff --git a/docs/TODO b/docs/TODO new file mode 100644 index 0000000..78f439a --- /dev/null +++ b/docs/TODO @@ -0,0 +1,3 @@ +1. remote router app pyqt/kivi +2. open ssh keyfile with decrypt dialog +3. open remote console button, make backup button (with possible schedule timer with checkbox?), route trafic through client machine button on/off diff --git a/example.com-le-ssl.conf b/docs/apache-example.com-le-ssl.conf similarity index 100% rename from example.com-le-ssl.conf rename to docs/apache-example.com-le-ssl.conf diff --git a/example.com.conf b/docs/apache-example.com.conf similarity index 100% rename from example.com.conf rename to docs/apache-example.com.conf diff --git a/config.py.dist b/docs/config.py.dist similarity index 100% rename from config.py.dist rename to docs/config.py.dist diff --git a/docs/posts.txt b/docs/posts.txt new file mode 100644 index 0000000..c3f4242 --- /dev/null +++ b/docs/posts.txt @@ -0,0 +1,9 @@ +templates/settings/profile.html:
+templates/dmanager/activate.html: +templates/vmanager/create.html: +templates/vmanager/activate.html: +templates/vmanager/recipe.html: +templates/admin/addr2pool.html: +templates/admin/charge.html: +templates/uinvoice/invoice.html: +templates/smanager/activate.html: diff --git a/requirements.txt b/requirements.txt index 3b834d9..3c8463c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +uuid alembic==0.9.2 appdirs==1.4.3 Babel==2.4.0