add order panel to regular and admin dashboards
This commit is contained in:
parent
9c2cd37e5d
commit
a094ccc081
8 changed files with 75 additions and 53 deletions
|
@ -7,45 +7,45 @@ from ..models import User
|
||||||
|
|
||||||
|
|
||||||
class LoginForm(FlaskForm):
|
class LoginForm(FlaskForm):
|
||||||
email = EmailField('Електронна Поща', [validators.DataRequired(), validators.Length(1,64), validators.Email()])
|
email = EmailField('E-Mail', [validators.DataRequired(), validators.Length(1,64), validators.Email()])
|
||||||
password = PasswordField('Парола', [validators.DataRequired(), validators.Length(1,128)])
|
password = PasswordField('Password', [validators.DataRequired(), validators.Length(1,128)])
|
||||||
remember_me = BooleanField('Запомни ме')
|
remember_me = BooleanField('Remember me ?')
|
||||||
#recaptcha = RecaptchaField()
|
#recaptcha = RecaptchaField()
|
||||||
submit = SubmitField('Вход')
|
submit = SubmitField('Login')
|
||||||
|
|
||||||
class TwoFAForm(FlaskForm):
|
class TwoFAForm(FlaskForm):
|
||||||
token = StringField('Token', [validators.DataRequired(), validators.Length(6, 6)])
|
token = StringField('Token', [validators.DataRequired(), validators.Length(6, 6)])
|
||||||
submit = SubmitField('Потвърди кода')
|
submit = SubmitField('Confirm')
|
||||||
|
|
||||||
class RegistrationForm(FlaskForm):
|
class RegistrationForm(FlaskForm):
|
||||||
email = StringField('Електронна Поща', [validators.DataRequired(), validators.Length(6,35), validators.Email()])
|
email = StringField('E-Mail', [validators.DataRequired(), validators.Length(6,35), validators.Email()])
|
||||||
def validate_email(self, field):
|
def validate_email(self, field):
|
||||||
if User.query.filter_by(email=field.data).first():
|
if User.query.filter_by(email=field.data).first():
|
||||||
raise ValidationError('Грешка. Опитайте пак с друг email адрес.')
|
raise ValidationError('Error. Please try again.')
|
||||||
password = PasswordField('Парола', [validators.DataRequired(), validators.EqualTo('confirm', message='Паролите трябва да съвпадат')])
|
password = PasswordField('Password', [validators.DataRequired(), validators.EqualTo('confirm', message='Both passwords must be equal')])
|
||||||
confirm = PasswordField('Повторете паролата', [validators.DataRequired()])
|
confirm = PasswordField('Your password again', [validators.DataRequired()])
|
||||||
accept_tos = BooleanField('Приемам <a href="/terms">Условията за Използване</a> на услугата', [validators.DataRequired()])
|
accept_tos = BooleanField('I accept the <a href="/terms">Terms of Service</a>', [validators.DataRequired()])
|
||||||
recaptcha = RecaptchaField()
|
recaptcha = RecaptchaField()
|
||||||
submit = SubmitField('Регистрация')
|
submit = SubmitField('REGISTER')
|
||||||
|
|
||||||
class ChangePasswordForm(FlaskForm):
|
class ChangePasswordForm(FlaskForm):
|
||||||
old_password = PasswordField('Стара парола', [validators.DataRequired()])
|
old_password = PasswordField('Old Password', [validators.DataRequired()])
|
||||||
password = PasswordField('Нова Парола', [validators.DataRequired(), validators.EqualTo('confirm', message='Паролите трябва да съвпадат')])
|
password = PasswordField('New Password', [validators.DataRequired(), validators.EqualTo('confirm', message='Both passwords must be equal')])
|
||||||
confirm = PasswordField('Повторете паролата')
|
confirm = PasswordField('Your password again')
|
||||||
submit = SubmitField('Обнови паролата')
|
submit = SubmitField('Renew Password')
|
||||||
|
|
||||||
class PasswordResetRequestForm(FlaskForm):
|
class PasswordResetRequestForm(FlaskForm):
|
||||||
email = EmailField('Електронна Поща', [validators.DataRequired(), validators.Length(1,64), validators.Email()])
|
email = EmailField('E-Mail', [validators.DataRequired(), validators.Length(1,64), validators.Email()])
|
||||||
recaptcha = RecaptchaField()
|
recaptcha = RecaptchaField()
|
||||||
submit = SubmitField('Възстановяване на парола', [validators.DataRequired()])
|
submit = SubmitField('Reset password', [validators.DataRequired()])
|
||||||
|
|
||||||
class PasswordResetForm(FlaskForm):
|
class PasswordResetForm(FlaskForm):
|
||||||
email = EmailField('Електронна Поща', [validators.DataRequired(), validators.Length(1,64), validators.Email()])
|
email = EmailField('E-Mail', [validators.DataRequired(), validators.Length(1,64), validators.Email()])
|
||||||
password = PasswordField('Парола', [validators.DataRequired(), validators.EqualTo('confirm', message='Паролите трябва да съвпадат')])
|
password = PasswordField('Password', [validators.DataRequired(), validators.EqualTo('confirm', message='Both password fields must be equal')])
|
||||||
confirm = PasswordField('Повторете паролата', [validators.DataRequired()])
|
confirm = PasswordField('Your password again', [validators.DataRequired()])
|
||||||
submit = SubmitField('Промяна на паролата')
|
submit = SubmitField('Change password')
|
||||||
|
|
||||||
def validate_email(self, field):
|
def validate_email(self, field):
|
||||||
if User.query.filter_by(email=field.data).first() is None:
|
if User.query.filter_by(email=field.data).first() is None:
|
||||||
raise ValidationError('Грешка. Опитайте пак с друг email адрес.')
|
raise ValidationError('Error. Please try again.')
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ from wtforms.fields.html5 import EmailField, DecimalRangeField
|
||||||
from .. import db
|
from .. import db
|
||||||
|
|
||||||
class OrderForm(FlaskForm):
|
class OrderForm(FlaskForm):
|
||||||
|
alias = StringField('Machine Alias:', [validators.Regexp(message='ex.: myservice1.com, myservice2.local', regex='^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$'), validators.Length(6,64)])
|
||||||
cpu = DecimalRangeField('Processor Cores', default=2)
|
cpu = DecimalRangeField('Processor Cores', default=2)
|
||||||
memory = DecimalRangeField('Memory', default=512)
|
memory = DecimalRangeField('Memory', default=512)
|
||||||
storage = DecimalRangeField('Storage', default=20)
|
storage = DecimalRangeField('Storage', default=10)
|
||||||
alias = StringField('Machine Alias:', [validators.Regexp(message='ex.: myservice1.com, myservice2.local', regex='^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$'), validators.Length(6,64)])
|
|
||||||
submit = SubmitField('Create')
|
submit = SubmitField('Create')
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,13 @@ def after_request(response):
|
||||||
current_app.logger.warning('Slow query: %s\nParameters: %s\nDuration: %fs\nContext: %s\n' % (query.statement, query.parameters, query.duration, query.context))
|
current_app.logger.warning('Slow query: %s\nParameters: %s\nDuration: %fs\nContext: %s\n' % (query.statement, query.parameters, query.duration, query.context))
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@panel.route("/submitorder", methods=['POST'])
|
@panel.route("/ordervm", methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def order():
|
def order():
|
||||||
|
form = OrderForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
pass
|
pass
|
||||||
return redirect('main.index')
|
return redirect('main.dashboard')
|
||||||
|
|
||||||
#DASHBOARD
|
#DASHBOARD
|
||||||
@panel.route("/dashboard", methods=['GET', 'POST'])
|
@panel.route("/dashboard", methods=['GET', 'POST'])
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
{% block page_content %}
|
|
||||||
<form method="POST" action="{{ url_for('panel.order') }}">
|
|
||||||
{{ form.cpu.label }} {{ form.cpu(min=2, max=16, step=2) }}<br />
|
|
||||||
{{ form.memory.label }} {{ form.memory(min=512, max=16384, step=512) }}<br />
|
|
||||||
{{ form.storage.label }} {{ form.storage(min=10, max=100, step=10) }}<br />
|
|
||||||
<p>
|
|
||||||
{{ form.csrf_token() }}
|
|
||||||
{{ form.submit }}
|
|
||||||
</p>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
41
app/templates/panel/order_vm.html
Normal file
41
app/templates/panel/order_vm.html
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}Request new Server{% endblock %}
|
||||||
|
|
||||||
|
{% block page_content %}
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Request new Server</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="POST" action="{{ url_for('panel.ordervm') }}">
|
||||||
|
<p>
|
||||||
|
{{ form.cpu.label }}<br /> {{ form.cpu(min=2, max=16, step=2) }}<br />
|
||||||
|
{% for error in form.cpu.errors %}
|
||||||
|
{{ error }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ form.memory.label }}<br /> {{ form.memory(min=512, max=16384, step=512) }}<br />
|
||||||
|
{% for error in form.memory.errors %}
|
||||||
|
{{ error }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ form.storage.label }}<br /> {{ form.storage(min=10, max=100, step=10) }}<br />
|
||||||
|
{% for error in form.storage.errors %}
|
||||||
|
{{ error }}<br />
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{{ form.csrf_token() }}
|
||||||
|
{{ form.submit }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -100,6 +100,6 @@
|
||||||
{% if inv_deployments != [] %}
|
{% if inv_deployments != [] %}
|
||||||
<!-- TODO: Create new deployment within this pool! -->
|
<!-- TODO: Create new deployment within this pool! -->
|
||||||
{% else %}
|
{% else %}
|
||||||
<button class="btn btn-default btn-lg btn-block" onclick="window.open('{{ url_for('vmanager.createvm') }}','_self')"><img class="icon icons8-Cloud-Storage" width="48" height="48" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAEEklEQVRYhe3Xy0/bBhwHcA6btEMP0077A3boYYdK23EHLiQ0hQBtVC1S9zjs0L069TCkSUWNpgZCshDYItZOI+tKH7Cibgw6Wu2RAXWMYyc8mpAoUAIEp6VuTR5OwAnJd5dBEbYJKDSA1J/0PfjgXz6y5W/ssrKDNm9dYl4+aqYeq00kSpnK5pGUusX1WkGgxux+/ePLvmQ4lkcp88nPfkHV6DpcEFhpGnnH2D8XKzXwQv98UtXoqioIVDeRH/1IcKlSAzsIbqXSTJ0tCKy2uNt/uy+slhrYez8JrY25XhCotdKDgzNiSXHhWB5DYRFaK+0tfAWt9Pzow9WSA8cereKYheILAo/bGDHE72z5n8E46rsC0LXR0LXRqO8K4O5kbEc7pvg8TrQxuXKD8xVFnLrJ9canVyYTO1k84FvCe+1eXCcWwPLLYPlldJMsPrg4ipsMtyPkmasBQWUk3twKWGm8PRff7kImsoxT7V5MLwrYPPNP0tDbPfh3KrltoGkgIqgaXbVbAT9zuLi00oIHfA6O4ShOOyZQZaFQZ3Pjbx8nwa3NcPAp1CYSersH529NwcuubAn8iXya0VjcXykCtVa6o9cn5JVwZzr9OHcziNBDAWI2hzCXwmourwgEAF7IgEuI6CJZ6FppMJFlRWCfX0BNq6dLEVjdQlODYfmK6RiK4twvwS0xheYasYCGnpAi8N6sCK2V8SsCq76hFsce5WRPPu2YQIBNFgXkEiL0do8icGIxB42Fisviyg3Ol463MtkpmYoZj4qoslAQs7migACgNpFo7Hsge6unl/I4+Z0nW25wHpIAVY2uw593BiQVMx4V8eGlMVwZjhSNA4B4OgtL/zROfsvIIs/eCAoVRuKIHLC26Y+IBGjqn0GHc25XcBvnh39mcaF3WgK03F1IqZoJnQR41EzVO1xPVjaf8P73o2D55V0HTi8K0LXREmAnxWe1VtogrZgW+sbvPkFygt7uAZcQdx2o9MDcnkyh1sb8KgNkvEMyFXP+1hS6SXbXgd0kK1s5rrkMalqYSQlQY6HichXjZVdwqt2LHioKXsgUDeMSIrpJFnU2N9xzacnv+R7noDFTwuaKOXSizSPKVcwasqEnhDqbu+iPI73dg4aekCwuHMtjZikPvd2TLTc4X10HVhiJI19cDe7oLeZ55suukFDRfO/tZxXTTOhMdxZK/iWnFNtf0bTKRLy7DjxmcX99meLFvYat5RodW61uYZo2PsH9fX5pxexV7gTTqGn1DGzswODwbGbPYWsZiWSgtTGhZxVjpoTxRfm3mL2In8tBY6ZS60C1icRFJrevojaReAF8bkAykkcqAxDz+W0dFxOlXVsCU///5aYy2NZxMVHadbCv4H7IC+CuA/djyg7C/AeJ36h1J+7ehgAAAABJRU5ErkJggg=="> Create</button>
|
<button class="btn btn-default btn-lg btn-block" onclick="window.open('{{ url_for('vmanager.vmcreate') }}','_self')"><img class="icon icons8-Cloud-Storage" width="48" height="48" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAEEklEQVRYhe3Xy0/bBhwHcA6btEMP0077A3boYYdK23EHLiQ0hQBtVC1S9zjs0L069TCkSUWNpgZCshDYItZOI+tKH7Cibgw6Wu2RAXWMYyc8mpAoUAIEp6VuTR5OwAnJd5dBEbYJKDSA1J/0PfjgXz6y5W/ssrKDNm9dYl4+aqYeq00kSpnK5pGUusX1WkGgxux+/ePLvmQ4lkcp88nPfkHV6DpcEFhpGnnH2D8XKzXwQv98UtXoqioIVDeRH/1IcKlSAzsIbqXSTJ0tCKy2uNt/uy+slhrYez8JrY25XhCotdKDgzNiSXHhWB5DYRFaK+0tfAWt9Pzow9WSA8cereKYheILAo/bGDHE72z5n8E46rsC0LXR0LXRqO8K4O5kbEc7pvg8TrQxuXKD8xVFnLrJ9canVyYTO1k84FvCe+1eXCcWwPLLYPlldJMsPrg4ipsMtyPkmasBQWUk3twKWGm8PRff7kImsoxT7V5MLwrYPPNP0tDbPfh3KrltoGkgIqgaXbVbAT9zuLi00oIHfA6O4ShOOyZQZaFQZ3Pjbx8nwa3NcPAp1CYSersH529NwcuubAn8iXya0VjcXykCtVa6o9cn5JVwZzr9OHcziNBDAWI2hzCXwmourwgEAF7IgEuI6CJZ6FppMJFlRWCfX0BNq6dLEVjdQlODYfmK6RiK4twvwS0xheYasYCGnpAi8N6sCK2V8SsCq76hFsce5WRPPu2YQIBNFgXkEiL0do8icGIxB42Fisviyg3Ol463MtkpmYoZj4qoslAQs7migACgNpFo7Hsge6unl/I4+Z0nW25wHpIAVY2uw593BiQVMx4V8eGlMVwZjhSNA4B4OgtL/zROfsvIIs/eCAoVRuKIHLC26Y+IBGjqn0GHc25XcBvnh39mcaF3WgK03F1IqZoJnQR41EzVO1xPVjaf8P73o2D55V0HTi8K0LXREmAnxWe1VtogrZgW+sbvPkFygt7uAZcQdx2o9MDcnkyh1sb8KgNkvEMyFXP+1hS6SXbXgd0kK1s5rrkMalqYSQlQY6HichXjZVdwqt2LHioKXsgUDeMSIrpJFnU2N9xzacnv+R7noDFTwuaKOXSizSPKVcwasqEnhDqbu+iPI73dg4aekCwuHMtjZikPvd2TLTc4X10HVhiJI19cDe7oLeZ55suukFDRfO/tZxXTTOhMdxZK/iWnFNtf0bTKRLy7DjxmcX99meLFvYat5RodW61uYZo2PsH9fX5pxexV7gTTqGn1DGzswODwbGbPYWsZiWSgtTGhZxVjpoTxRfm3mL2In8tBY6ZS60C1icRFJrevojaReAF8bkAykkcqAxDz+W0dFxOlXVsCU///5aYy2NZxMVHadbCv4H7IC+CuA/djyg7C/AeJ36h1J+7ehgAAAABJRU5ErkJggg=="> Create</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<div class="panel-heading">Create Deployment</div>
|
<div class="panel-heading">Create Deployment</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
|
||||||
<form method="POST" action="{{ url_for('vmanager.createvm') }}">
|
<form method="POST" action="{{ url_for('vmanager.vmcreate') }}">
|
||||||
<p>
|
<p>
|
||||||
{{ form.servername.label }}<br />{{ form.servername(size=42) }}<br />
|
{{ form.servername.label }}<br />{{ form.servername(size=42) }}<br />
|
||||||
{% for error in form.servername.errors %}
|
{% for error in form.servername.errors %}
|
||||||
|
|
|
@ -49,18 +49,10 @@ def slavetables():
|
||||||
addrlist['status'] = 'tables_gen_error'
|
addrlist['status'] = 'tables_gen_error'
|
||||||
return jsonify(addrlist)
|
return jsonify(addrlist)
|
||||||
|
|
||||||
@vmanager.route('/createvm', methods=['GET', 'POST'])
|
@vmanager.route('/vmcreate', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def createvm():
|
@admin_required
|
||||||
if current_user.name is None:
|
def vmcreate():
|
||||||
flash('Please update profile info for this operation.')
|
|
||||||
return redirect(url_for('settings.profile'))
|
|
||||||
|
|
||||||
deployment_seeds = current_user.inv_deployments.filter_by(deleted=False).filter_by(protected=False).all()
|
|
||||||
if deployment_seeds != []:
|
|
||||||
flash('Offline deployments still exist.')
|
|
||||||
return redirect(url_for('panel.dashboard'))
|
|
||||||
|
|
||||||
form = CreateForm()
|
form = CreateForm()
|
||||||
if current_user.confirmed and form.validate_on_submit():
|
if current_user.confirmed and form.validate_on_submit():
|
||||||
#selects the chosen region
|
#selects the chosen region
|
||||||
|
@ -85,7 +77,7 @@ def createvm():
|
||||||
|
|
||||||
if query['status'] == 'kvm_created':
|
if query['status'] == 'kvm_created':
|
||||||
selected_slave = Server.query.filter_by(name=query['slave']).first()
|
selected_slave = Server.query.filter_by(name=query['slave']).first()
|
||||||
deployment = Deployment(user_id=int(current_user.pid), machine_alias=str(form.servername.data), machine_id=query['unit_id'], machine_cpu=data['cpu'], machine_mem=data['mem'], machine_hdd=data['hdd'], enabled=True, protected=False, daysleft=15, warning=True, discount=0, server_id=int(selected_slave.pid))
|
deployment = Deployment(user_id=int(current_user.pid), machine_alias=str(form.servername.data), period=1, machine_id=query['unit_id'], machine_cpu=data['cpu'], machine_mem=data['mem'], machine_hdd=data['hdd'], enabled=True, protected=False, daysleft=15, warning=True, discount=0, server_id=int(selected_slave.pid))
|
||||||
db.session.add(deployment)
|
db.session.add(deployment)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
new_vlan = PubVLAN(deploy_id=int(deployment.pid), vlan_id=int(query['vlanid']))
|
new_vlan = PubVLAN(deploy_id=int(deployment.pid), vlan_id=int(query['vlanid']))
|
||||||
|
@ -97,8 +89,6 @@ def createvm():
|
||||||
else:
|
else:
|
||||||
flash('Deployment could not be created! Please try again later...')
|
flash('Deployment could not be created! Please try again later...')
|
||||||
|
|
||||||
#TODO: cleanup bridge if the machine is new and we were not be able to create it
|
|
||||||
|
|
||||||
return redirect(url_for('panel.dashboard'))
|
return redirect(url_for('panel.dashboard'))
|
||||||
return render_template('vmanager/create.html', form=form)
|
return render_template('vmanager/create.html', form=form)
|
||||||
|
|
||||||
|
@ -175,6 +165,7 @@ def activate(itemid=0):
|
||||||
|
|
||||||
@vmanager.route('/vmremove/<int:unit_id>', methods=['GET', 'POST'])
|
@vmanager.route('/vmremove/<int:unit_id>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
|
@admin_required
|
||||||
def remove(unit_id=0):
|
def remove(unit_id=0):
|
||||||
data = { 'unit_id': int(unit_id),
|
data = { 'unit_id': int(unit_id),
|
||||||
'type': 'kvm' }
|
'type': 'kvm' }
|
||||||
|
|
Loading…
Reference in a new issue