mirror of
https://github.com/retspen/webvirtcloud
synced 2026-03-22 02:24:56 +00:00
Reworked some computes forms and views
This commit is contained in:
parent
9efbf732af
commit
c07bb3cccf
9 changed files with 154 additions and 384 deletions
|
|
@ -2,131 +2,55 @@ import re
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from computes.models import Compute
|
from computes.models import Compute
|
||||||
|
from vrtManager.connection import CONN_TCP, CONN_SSH, CONN_TLS, CONN_SOCKET
|
||||||
|
from .validators import validate_hostname
|
||||||
|
|
||||||
|
|
||||||
class ComputeAddTcpForm(forms.Form):
|
class TcpComputeForm(forms.ModelForm):
|
||||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
hostname = forms.CharField(validators=[validate_hostname])
|
||||||
max_length=64)
|
type = forms.IntegerField(widget=forms.HiddenInput, initial=CONN_TCP)
|
||||||
hostname = forms.CharField(error_messages={'required': _('No IP / Domain name has been entered')},
|
|
||||||
max_length=100)
|
|
||||||
login = forms.CharField(error_messages={'required': _('No login has been entered')},
|
|
||||||
max_length=100)
|
|
||||||
password = forms.CharField(error_messages={'required': _('No password has been entered')},
|
|
||||||
max_length=100)
|
|
||||||
details = forms.CharField(max_length=50, required=False)
|
|
||||||
|
|
||||||
def clean_name(self):
|
class Meta:
|
||||||
name = self.cleaned_data['name']
|
model = Compute
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
fields = '__all__'
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('The host name must not contain any special characters'))
|
|
||||||
elif len(name) > 20:
|
|
||||||
raise forms.ValidationError(_('The host name must not exceed 20 characters'))
|
|
||||||
try:
|
|
||||||
Compute.objects.get(name=name)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return name
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
||||||
def clean_hostname(self):
|
|
||||||
hostname = self.cleaned_data['hostname']
|
|
||||||
have_symbol = re.match('[^a-z0-9.-]+', hostname)
|
|
||||||
wrong_ip = re.match('^0.|^255.', hostname)
|
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('Hostname must contain only numbers, or the domain name separated by "."'))
|
|
||||||
elif wrong_ip:
|
|
||||||
raise forms.ValidationError(_('Wrong IP address'))
|
|
||||||
try:
|
|
||||||
Compute.objects.get(hostname=hostname)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return hostname
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
||||||
|
|
||||||
class ComputeAddSshForm(forms.Form):
|
class SshComputeForm(forms.ModelForm):
|
||||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
hostname = forms.CharField(
|
||||||
max_length=64)
|
validators=[validate_hostname], label=_("FQDN/IP"))
|
||||||
hostname = forms.CharField(error_messages={'required': _('No IP / Domain name has been entered')},
|
type = forms.IntegerField(widget=forms.HiddenInput, initial=CONN_SSH)
|
||||||
max_length=100)
|
|
||||||
login = forms.CharField(error_messages={'required': _('No login has been entered')},
|
|
||||||
max_length=20)
|
|
||||||
details = forms.CharField(max_length=50, required=False)
|
|
||||||
|
|
||||||
def clean_name(self):
|
class Meta:
|
||||||
name = self.cleaned_data['name']
|
model = Compute
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
exclude = ['password']
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('The name of the host must not contain any special characters'))
|
|
||||||
elif len(name) > 20:
|
|
||||||
raise forms.ValidationError(_('The name of the host must not exceed 20 characters'))
|
|
||||||
try:
|
|
||||||
Compute.objects.get(name=name)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return name
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
||||||
def clean_hostname(self):
|
|
||||||
hostname = self.cleaned_data['hostname']
|
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', hostname)
|
|
||||||
wrong_ip = re.match('^0.|^255.', hostname)
|
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('Hostname must contain only numbers, or the domain name separated by "."'))
|
|
||||||
elif wrong_ip:
|
|
||||||
raise forms.ValidationError(_('Wrong IP address'))
|
|
||||||
try:
|
|
||||||
Compute.objects.get(hostname=hostname)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return hostname
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
||||||
|
|
||||||
class ComputeAddTlsForm(forms.Form):
|
class TlsComputeForm(forms.ModelForm):
|
||||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
hostname = forms.CharField(validators=[validate_hostname])
|
||||||
max_length=64)
|
type = forms.IntegerField(widget=forms.HiddenInput, initial=CONN_TLS)
|
||||||
hostname = forms.CharField(error_messages={'required': _('No IP / Domain name has been entered')},
|
|
||||||
max_length=100)
|
|
||||||
login = forms.CharField(error_messages={'required': _('No login has been entered')},
|
|
||||||
max_length=100)
|
|
||||||
password = forms.CharField(error_messages={'required': _('No password has been entered')},
|
|
||||||
max_length=100)
|
|
||||||
details = forms.CharField(max_length=50, required=False)
|
|
||||||
|
|
||||||
def clean_name(self):
|
class Meta:
|
||||||
name = self.cleaned_data['name']
|
model = Compute
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
fields = '__all__'
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('The host name must not contain any special characters'))
|
|
||||||
elif len(name) > 20:
|
|
||||||
raise forms.ValidationError(_('The host name must not exceed 20 characters'))
|
|
||||||
try:
|
|
||||||
Compute.objects.get(name=name)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return name
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
||||||
def clean_hostname(self):
|
|
||||||
hostname = self.cleaned_data['hostname']
|
class SocketComputeForm(forms.ModelForm):
|
||||||
have_symbol = re.match('[^a-z0-9.-]+', hostname)
|
hostname = forms.CharField(widget=forms.HiddenInput, initial='localhost')
|
||||||
wrong_ip = re.match('^0.|^255.', hostname)
|
type = forms.IntegerField(widget=forms.HiddenInput, initial=CONN_SOCKET)
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('Hostname must contain only numbers, or the domain name separated by "."'))
|
class Meta:
|
||||||
elif wrong_ip:
|
model = Compute
|
||||||
raise forms.ValidationError(_('Wrong IP address'))
|
fields = ['name', 'details', 'hostname', 'type']
|
||||||
try:
|
|
||||||
Compute.objects.get(hostname=hostname)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return hostname
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
||||||
|
|
||||||
class ComputeEditHostForm(forms.Form):
|
class ComputeEditHostForm(forms.Form):
|
||||||
host_id = forms.CharField()
|
host_id = forms.CharField()
|
||||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
name = forms.CharField(error_messages={'required': _(
|
||||||
max_length=64)
|
'No hostname has been entered')}, max_length=64)
|
||||||
hostname = forms.CharField(error_messages={'required': _('No IP / Domain name has been entered')},
|
hostname = forms.CharField(error_messages={'required': _(
|
||||||
max_length=100)
|
'No IP / Domain name has been entered')}, max_length=100)
|
||||||
login = forms.CharField(error_messages={'required': _('No login has been entered')},
|
login = forms.CharField(error_messages={'required': _(
|
||||||
max_length=100)
|
'No login has been entered')}, max_length=100)
|
||||||
password = forms.CharField(max_length=100)
|
password = forms.CharField(max_length=100)
|
||||||
details = forms.CharField(max_length=50, required=False)
|
details = forms.CharField(max_length=50, required=False)
|
||||||
|
|
||||||
|
|
@ -134,9 +58,11 @@ class ComputeEditHostForm(forms.Form):
|
||||||
name = self.cleaned_data['name']
|
name = self.cleaned_data['name']
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
||||||
if have_symbol:
|
if have_symbol:
|
||||||
raise forms.ValidationError(_('The name of the host must not contain any special characters'))
|
raise forms.ValidationError(
|
||||||
|
_('The name of the host must not contain any special characters'))
|
||||||
elif len(name) > 20:
|
elif len(name) > 20:
|
||||||
raise forms.ValidationError(_('The name of the host must not exceed 20 characters'))
|
raise forms.ValidationError(
|
||||||
|
_('The name of the host must not exceed 20 characters'))
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def clean_hostname(self):
|
def clean_hostname(self):
|
||||||
|
|
@ -144,25 +70,8 @@ class ComputeEditHostForm(forms.Form):
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', hostname)
|
have_symbol = re.match('[^a-zA-Z0-9._-]+', hostname)
|
||||||
wrong_ip = re.match('^0.|^255.', hostname)
|
wrong_ip = re.match('^0.|^255.', hostname)
|
||||||
if have_symbol:
|
if have_symbol:
|
||||||
raise forms.ValidationError(_('Hostname must contain only numbers, or the domain name separated by "."'))
|
raise forms.ValidationError(
|
||||||
|
_('Hostname must contain only numbers, or the domain name separated by "."'))
|
||||||
elif wrong_ip:
|
elif wrong_ip:
|
||||||
raise forms.ValidationError(_('Wrong IP address'))
|
raise forms.ValidationError(_('Wrong IP address'))
|
||||||
return hostname
|
return hostname
|
||||||
|
|
||||||
|
|
||||||
class ComputeAddSocketForm(forms.Form):
|
|
||||||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')}, max_length=64)
|
|
||||||
details = forms.CharField(error_messages={'required': _('No details has been entered')}, max_length=50)
|
|
||||||
|
|
||||||
def clean_name(self):
|
|
||||||
name = self.cleaned_data['name']
|
|
||||||
have_symbol = re.match('[^a-zA-Z0-9._-]+', name)
|
|
||||||
if have_symbol:
|
|
||||||
raise forms.ValidationError(_('The host name must not contain any special characters'))
|
|
||||||
elif len(name) > 20:
|
|
||||||
raise forms.ValidationError(_('The host name must not exceed 20 characters'))
|
|
||||||
try:
|
|
||||||
Compute.objects.get(name=name)
|
|
||||||
except Compute.DoesNotExist:
|
|
||||||
return name
|
|
||||||
raise forms.ValidationError(_('This host is already connected'))
|
|
||||||
|
|
|
||||||
18
computes/migrations/0002_auto_20200529_1320.py
Normal file
18
computes/migrations/0002_auto_20200529_1320.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.12 on 2020-05-29 13:20
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('computes', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='compute',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64, unique=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -2,7 +2,7 @@ from django.db.models import Model, CharField, IntegerField
|
||||||
|
|
||||||
|
|
||||||
class Compute(Model):
|
class Compute(Model):
|
||||||
name = CharField(max_length=64)
|
name = CharField(max_length=64, unique=True)
|
||||||
hostname = CharField(max_length=64)
|
hostname = CharField(max_length=64)
|
||||||
login = CharField(max_length=20)
|
login = CharField(max_length=20)
|
||||||
password = CharField(max_length=14, blank=True, null=True)
|
password = CharField(max_length=14, blank=True, null=True)
|
||||||
|
|
|
||||||
29
computes/templates/computes/form.html
Normal file
29
computes/templates/computes/form.html
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load bootstrap4 %}
|
||||||
|
{% load font_awesome %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Add Compute" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h2 class="page-header">{% trans "Create Compute" %}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% bootstrap_messages %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="thumbnail col-sm-10 offset-1">
|
||||||
|
<form id="create-update" action="" method="post" class="form-horizontal">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form layout='horizontal' %}
|
||||||
|
</form>
|
||||||
|
<div class="form-group float-right">
|
||||||
|
<a class="btn btn-primary" href="javascript:history.back()">{% icon 'times' %} {% trans "Cancel" %}</a>
|
||||||
|
<button type="submit" form="create-update" class="btn btn-success">
|
||||||
|
{% icon 'check' %} {% trans "Save" %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
|
|
@ -1,183 +1,10 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% if request.user.is_superuser %}
|
{% load font_awesome %}
|
||||||
<a href="#addHost" type="button" class="btn btn-success btn-header float-right" data-toggle="modal">
|
{% load bootstrap4 %}
|
||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<div class="btn-group float-right" role="group" aria-label="Add host button group">
|
||||||
</a>
|
<a href="{% url 'add_tcp_host' %}" class="btn btn-success">{% trans "TCP" %}</a>
|
||||||
|
<a href="{% url 'add_ssh_host' %}" class="btn btn-success">{% trans "SSH" %}</a>
|
||||||
<!-- Modal -->
|
<a href="{% url 'add_tls_host' %}" class="btn btn-success">{% trans "TLS" %}</a>
|
||||||
<div class="modal fade" id="addHost" tabindex="-1" role="dialog" aria-labelledby="addHostLabel" aria-hidden="true">
|
<a href="{% url 'add_socket_host' %}" class="btn btn-success">{% trans "Local" %}</a>
|
||||||
<div class="modal-dialog">
|
<a href="#" class="btn btn-success disabled" title="{% trans "Add new host" %}">{% icon "plus" %}</a>
|
||||||
<div class="modal-content">
|
</div>
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">{% trans "Add Connection" %}</h5>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul class="nav nav-pills nav-justified" role="tablist" aria-label="Host connection types">
|
|
||||||
<li class="nav-item"><a class="nav-link active" href="#tcp_con" data-toggle="tab">{% trans "TCP Connection" %}</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#ssh_con" data-toggle="tab">{% trans "SSH Connection" %}</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#tls_con" data-toggle="tab">{% trans "TLS Connection" %}</a></li>
|
|
||||||
<li class="nav-item"><a class="nav-link" href="#local_con" data-toggle="tab">{% trans "Local Socket Connection" %}</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<div class="tab-content">
|
|
||||||
<div class="tab-pane fade show active" id="tcp_con">
|
|
||||||
<div class="modal-body">
|
|
||||||
<form method="post" role="form" aria-label="Add host with tcp connection form">{% csrf_token %}
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="name" class="form-control" placeholder="Label Name" maxlength="20" required pattern="[a-z0-9\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "FQDN / IP" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="hostname" class="form-control" placeholder="{% trans "FQDN or IP Address" %}" required pattern="[a-z0-9\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Username" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="login" class="form-control" placeholder="{% trans "Username" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Password" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="password" name="password" class="form-control" placeholder="{% trans "Password" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
|
||||||
{% trans "Close" %}
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="btn btn-primary" name="host_tcp_add">
|
|
||||||
{% trans "Add" %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane" id="ssh_con">
|
|
||||||
<div class="modal-body">
|
|
||||||
<form method="post" role="form" aria-label="Add host with ssh connection form">{% csrf_token %}
|
|
||||||
<p class="modal-body">{% trans "You must create ssh <a href='https://github.com/retspen/webvirtmgr/wiki/Setup-SSH-Authorization'>authorization key</a>. If you have another SSH port on your server, you can add IP:PORT like '192.168.1.1:2222'." %}</p>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="name" class="form-control" placeholder="Label Name" maxlength="20" required pattern="[a-z0-9\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "FQDN / IP" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="hostname" class="form-control" placeholder="{% trans "FQDN or IP Address" %}" required pattern="[a-z0-9\:\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Username" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="login" class="form-control" placeholder="{% trans "Username" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
|
||||||
{% trans "Close" %}
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="btn btn-primary" name="host_ssh_add">
|
|
||||||
{% trans "Add" %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane" id="tls_con">
|
|
||||||
<div class="modal-body">
|
|
||||||
<form method="post" role="form" aria-label="Add host with TLS connection form">{% csrf_token %}
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="name" class="form-control" placeholder="Label Name" maxlength="20" required pattern="[a-z0-9\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "FQDN / IP" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="hostname" class="form-control" placeholder="{% trans "FQDN or IP Address" %}" required pattern="[a-z0-9\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Username" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="login" class="form-control" placeholder="{% trans "Username" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Password" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="password" name="password" class="form-control" placeholder="{% trans "Password" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
|
||||||
{% trans "Close" %}
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="btn btn-primary" name="host_tls_add">
|
|
||||||
{% trans "Add" %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane" id="local_con">
|
|
||||||
<div class="modal-body">
|
|
||||||
<form method="post" role="form" aria-label="Add host with local socket form">{% csrf_token %}
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="name" class="form-control" placeholder="Label Name" maxlength="20" required pattern="[a-z0-9\.\-_]+">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">
|
|
||||||
{% trans "Close" %}
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="btn btn-primary" name="host_socket_add">
|
|
||||||
{% trans "Add" %}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div> <!-- /.tab-content -->
|
|
||||||
</div> <!-- /.modal-content -->
|
|
||||||
</div> <!-- /.modal-dialog -->
|
|
||||||
</div><!-- /.modal -->
|
|
||||||
{% endif %}
|
|
||||||
|
|
@ -8,9 +8,18 @@ from networks.views import network, networks
|
||||||
from nwfilters.views import nwfilter, nwfilters
|
from nwfilters.views import nwfilter, nwfilters
|
||||||
from secrets.views import secrets
|
from secrets.views import secrets
|
||||||
from storages.views import get_volumes, storage, storages
|
from storages.views import get_volumes, storage, storages
|
||||||
|
from . import forms
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.computes, name='computes'),
|
path('', views.computes, name='computes'),
|
||||||
|
path('add_tcp_host/', views.add_host,
|
||||||
|
{'FormClass': forms.TcpComputeForm}, name='add_tcp_host'),
|
||||||
|
path('add_ssh_host/', views.add_host,
|
||||||
|
{'FormClass': forms.SshComputeForm}, name='add_ssh_host'),
|
||||||
|
path('add_tls_host/', views.add_host,
|
||||||
|
{'FormClass': forms.TlsComputeForm}, name='add_tls_host'),
|
||||||
|
path('add_socket_host/', views.add_host,
|
||||||
|
{'FormClass': forms.SocketComputeForm}, name='add_socket_host'),
|
||||||
path('<int:compute_id>/', include([
|
path('<int:compute_id>/', include([
|
||||||
path('', views.overview, name='overview'),
|
path('', views.overview, name='overview'),
|
||||||
path('statistics', views.compute_graph, name='compute_graph'),
|
path('statistics', views.compute_graph, name='compute_graph'),
|
||||||
|
|
@ -19,7 +28,7 @@ urlpatterns = [
|
||||||
path('storage/<str:pool>/volumes', get_volumes, name='volumes'),
|
path('storage/<str:pool>/volumes', get_volumes, name='volumes'),
|
||||||
path('storage/<str:pool>/', storage, name='storage'),
|
path('storage/<str:pool>/', storage, name='storage'),
|
||||||
path('networks/', networks, name='networks'),
|
path('networks/', networks, name='networks'),
|
||||||
path('network/<pool>/', network, name='network'),
|
path('network/<str:pool>/', network, name='network'),
|
||||||
path('interfaces/', interfaces, name='interfaces'),
|
path('interfaces/', interfaces, name='interfaces'),
|
||||||
path('interface/<str:iface>/', interface, name='interface'),
|
path('interface/<str:iface>/', interface, name='interface'),
|
||||||
path('nwfilters/', nwfilters, name='nwfilters'),
|
path('nwfilters/', nwfilters, name='nwfilters'),
|
||||||
|
|
|
||||||
24
computes/validators.py
Normal file
24
computes/validators.py
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
import re
|
||||||
|
|
||||||
|
have_symbol = re.compile('[^a-zA-Z0-9._-]+')
|
||||||
|
wrong_ip = re.compile('^0.|^255.')
|
||||||
|
wrong_name = re.compile('[^a-zA-Z0-9._-]+')
|
||||||
|
|
||||||
|
|
||||||
|
def validate_hostname(value):
|
||||||
|
sym = have_symbol.match(value)
|
||||||
|
wip = wrong_ip.match(value)
|
||||||
|
|
||||||
|
if sym:
|
||||||
|
raise ValidationError(_('Hostname must contain only numbers, or the domain name separated by "."'))
|
||||||
|
elif wip:
|
||||||
|
raise ValidationError(_('Wrong IP address'))
|
||||||
|
|
||||||
|
|
||||||
|
def validate_name(value):
|
||||||
|
have_symbol = wrong_name.match('[^a-zA-Z0-9._-]+')
|
||||||
|
if have_symbol:
|
||||||
|
raise ValidationError(_('The host name must not contain any special characters'))
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
import json
|
import json
|
||||||
from django.utils import timezone
|
|
||||||
|
from django.contrib import messages
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
|
from django.shortcuts import get_object_or_404, redirect, render, reverse
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.shortcuts import render, get_object_or_404
|
from django.utils import timezone
|
||||||
from libvirt import libvirtError
|
from libvirt import libvirtError
|
||||||
from instances.models import Instance
|
|
||||||
from accounts.models import UserInstance
|
from accounts.models import UserInstance
|
||||||
from computes.models import Compute
|
|
||||||
from computes.forms import ComputeAddTcpForm, ComputeAddSshForm, ComputeEditHostForm, ComputeAddTlsForm, ComputeAddSocketForm
|
|
||||||
from vrtManager.hostdetails import wvmHostDetails
|
|
||||||
from vrtManager.connection import CONN_SSH, CONN_TCP, CONN_TLS, CONN_SOCKET, connection_manager, wvmConnect
|
|
||||||
from admin.decorators import superuser_only
|
from admin.decorators import superuser_only
|
||||||
|
from computes.forms import (ComputeEditHostForm, SocketComputeForm, SshComputeForm, TcpComputeForm, TlsComputeForm)
|
||||||
|
from computes.models import Compute
|
||||||
|
from instances.models import Instance
|
||||||
|
from vrtManager.connection import (CONN_SOCKET, CONN_SSH, CONN_TCP, CONN_TLS, connection_manager, wvmConnect)
|
||||||
|
from vrtManager.hostdetails import wvmHostDetails
|
||||||
|
|
||||||
|
|
||||||
@superuser_only
|
@superuser_only
|
||||||
|
|
@ -55,65 +58,6 @@ def computes(request):
|
||||||
del_host = Compute.objects.get(id=compute_id)
|
del_host = Compute.objects.get(id=compute_id)
|
||||||
del_host.delete()
|
del_host.delete()
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
return HttpResponseRedirect(request.get_full_path())
|
||||||
if 'host_tcp_add' in request.POST:
|
|
||||||
form = ComputeAddTcpForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
data = form.cleaned_data
|
|
||||||
new_tcp_host = Compute(name=data['name'],
|
|
||||||
hostname=data['hostname'],
|
|
||||||
type=CONN_TCP,
|
|
||||||
login=data['login'],
|
|
||||||
password=data['password'],
|
|
||||||
details=data['details'])
|
|
||||||
new_tcp_host.save()
|
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
|
||||||
else:
|
|
||||||
for msg_err in form.errors.values():
|
|
||||||
error_messages.append(msg_err.as_text())
|
|
||||||
if 'host_ssh_add' in request.POST:
|
|
||||||
form = ComputeAddSshForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
data = form.cleaned_data
|
|
||||||
new_ssh_host = Compute(name=data['name'],
|
|
||||||
hostname=data['hostname'],
|
|
||||||
type=CONN_SSH,
|
|
||||||
login=data['login'],
|
|
||||||
details=data['details'])
|
|
||||||
new_ssh_host.save()
|
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
|
||||||
else:
|
|
||||||
for msg_err in form.errors.values():
|
|
||||||
error_messages.append(msg_err.as_text())
|
|
||||||
if 'host_tls_add' in request.POST:
|
|
||||||
form = ComputeAddTlsForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
data = form.cleaned_data
|
|
||||||
new_tls_host = Compute(name=data['name'],
|
|
||||||
hostname=data['hostname'],
|
|
||||||
type=CONN_TLS,
|
|
||||||
login=data['login'],
|
|
||||||
password=data['password'],
|
|
||||||
details=data['details'])
|
|
||||||
new_tls_host.save()
|
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
|
||||||
else:
|
|
||||||
for msg_err in form.errors.values():
|
|
||||||
error_messages.append(msg_err.as_text())
|
|
||||||
if 'host_socket_add' in request.POST:
|
|
||||||
form = ComputeAddSocketForm(request.POST)
|
|
||||||
if form.is_valid():
|
|
||||||
data = form.cleaned_data
|
|
||||||
new_socket_host = Compute(name=data['name'],
|
|
||||||
details=data['details'],
|
|
||||||
hostname='localhost',
|
|
||||||
type=CONN_SOCKET,
|
|
||||||
login='',
|
|
||||||
password='')
|
|
||||||
new_socket_host.save()
|
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
|
||||||
else:
|
|
||||||
for msg_err in form.errors.values():
|
|
||||||
error_messages.append(msg_err.as_text())
|
|
||||||
if 'host_edit' in request.POST:
|
if 'host_edit' in request.POST:
|
||||||
form = ComputeEditHostForm(request.POST)
|
form = ComputeEditHostForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
|
@ -304,3 +248,13 @@ def get_dom_capabilities(request, compute_id, arch, machine):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return HttpResponse(json.dumps(data))
|
return HttpResponse(json.dumps(data))
|
||||||
|
|
||||||
|
|
||||||
|
@superuser_only
|
||||||
|
def add_host(request, FormClass):
|
||||||
|
form = FormClass(request.POST or None)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return redirect(reverse('computes'))
|
||||||
|
|
||||||
|
return render(request, 'computes/form.html', {'form': form})
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@ from django.urls import include, path
|
||||||
from instances.views import index
|
from instances.views import index
|
||||||
from console.views import console
|
from console.views import console
|
||||||
from appsettings.views import appsettings
|
from appsettings.views import appsettings
|
||||||
# from django.contrib import admin
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', index, name='index'),
|
path('', index, name='index'),
|
||||||
path('admin/', include(('admin.urls', 'admin'), namespace='admin')),
|
path('admin/', include(('admin.urls', 'admin'), namespace='admin')),
|
||||||
path('appsettings/', appsettings, name='appsettings'),
|
path('appsettings/', appsettings, name='appsettings'),
|
||||||
path('accounts/', include('accounts.urls')),
|
path('accounts/', include('accounts.urls')),
|
||||||
path('computes/', include('computes.urls')),
|
path('computes/', include('computes.urls')),
|
||||||
path('console/', console, name='console'),
|
path('console/', console, name='console'),
|
||||||
path('datasource/', include('datasource.urls')),
|
path('datasource/', include('datasource.urls')),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue