add order panel to regular and admin dashboards

This commit is contained in:
deflax 2018-02-20 12:17:28 +02:00
parent 9c2cd37e5d
commit a094ccc081
8 changed files with 75 additions and 53 deletions

View file

@ -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.')

View file

@ -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')

View file

@ -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'])

View file

@ -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 %}

View 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 %}

View file

@ -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 %}

View file

@ -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 %}

View file

@ -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' }