jumpserver/apps/assets/forms.py

432 lines
16 KiB
Python
Raw Normal View History

2016-08-14 14:10:10 +00:00
# coding:utf-8
from django import forms
2016-11-06 16:39:26 +00:00
from django.utils.translation import gettext_lazy as _
2016-08-14 14:10:10 +00:00
2018-01-23 11:37:22 +00:00
from .models import Cluster, Asset, AssetGroup, AdminUser, SystemUser, Label
2017-03-09 06:55:33 +00:00
from common.utils import validate_ssh_private_key, ssh_pubkey_gen, ssh_key_gen, get_logger
logger = get_logger(__file__)
2016-08-14 14:10:10 +00:00
2016-09-17 15:43:41 +00:00
class AssetCreateForm(forms.ModelForm):
2016-08-14 14:10:10 +00:00
class Meta:
model = Asset
fields = [
2017-04-12 03:50:15 +00:00
'hostname', 'ip', 'public_ip', 'port', 'type', 'comment',
2017-12-12 04:19:45 +00:00
'cluster', 'groups', 'status', 'env', 'is_active',
2018-01-23 11:37:22 +00:00
'admin_user', 'labels'
2017-03-15 16:19:47 +00:00
]
widgets = {
2018-01-26 06:47:10 +00:00
'groups': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Select asset groups')
}),
'cluster': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Select cluster')
}),
'admin_user': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Select admin user')
}),
'labels': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Select labels')
}),
2018-01-23 11:37:22 +00:00
'port': forms.TextInput(),
2017-03-15 16:19:47 +00:00
}
help_texts = {
'hostname': '* required',
'ip': '* required',
2017-12-12 04:19:45 +00:00
'port': '* required',
'cluster': '* required',
'admin_user': _('Host level admin user, If not set using cluster admin user default')
2017-03-15 16:19:47 +00:00
}
2017-12-29 15:53:45 +00:00
def clean_admin_user(self):
cluster = self.cleaned_data.get('cluster')
admin_user = self.cleaned_data.get('admin_user')
if not admin_user and (cluster and not cluster.admin_user):
2017-12-29 15:53:45 +00:00
raise forms.ValidationError(_("You need set a admin user if cluster not have"))
return self.cleaned_data['admin_user']
2018-01-26 06:47:10 +00:00
def is_valid(self):
print(self.data)
result = super().is_valid()
if not result:
print(self.errors)
print(self.cleaned_data)
return result
2018-01-23 11:37:22 +00:00
2017-03-15 16:19:47 +00:00
2017-04-11 09:29:53 +00:00
class AssetUpdateForm(forms.ModelForm):
2017-03-15 16:19:47 +00:00
class Meta:
model = Asset
fields = [
'hostname', 'ip', 'port', 'groups', "cluster", 'is_active',
2017-03-15 16:19:47 +00:00
'type', 'env', 'status', 'public_ip', 'remote_card_ip', 'cabinet_no',
2018-01-23 11:37:22 +00:00
'cabinet_pos', 'number', 'comment', 'admin_user', 'labels'
2016-08-14 14:10:10 +00:00
]
2016-09-04 11:12:31 +00:00
widgets = {
2018-01-26 06:47:10 +00:00
'groups': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Select asset groups')
}),
'cluster': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Select cluster')
}),
'admin_user': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Select admin user')
}),
'labels': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Select labels')
}),
'port': forms.TextInput(),
2016-09-17 15:43:41 +00:00
}
help_texts = {
'hostname': '* required',
'ip': '* required',
2017-12-12 04:19:45 +00:00
'port': '* required',
'cluster': '* required',
'admin_user': _('Host level admin user, If not set using cluster admin user default')
2016-09-04 11:12:31 +00:00
}
2017-12-29 15:53:45 +00:00
def clean_admin_user(self):
cluster = self.cleaned_data.get('cluster')
admin_user = self.cleaned_data.get('admin_user')
if not admin_user and (cluster and not cluster.admin_user):
2017-12-29 15:53:45 +00:00
raise forms.ValidationError(_("You need set a admin user if cluster not have"))
return self.cleaned_data['admin_user']
2018-01-26 06:47:10 +00:00
def is_valid(self):
print(self.data)
return super().is_valid()
2018-01-23 11:37:22 +00:00
2016-08-14 14:10:10 +00:00
2017-04-11 09:29:53 +00:00
class AssetBulkUpdateForm(forms.ModelForm):
2017-12-21 03:31:13 +00:00
assets = forms.ModelMultipleChoiceField(
2018-01-23 11:37:22 +00:00
required=True, help_text='* required',
label=_('Select assets'), queryset=Asset.objects.all(),
2017-04-12 03:50:15 +00:00
widget=forms.SelectMultiple(
attrs={
'class': 'select2',
'data-placeholder': _('Select assets')
}
)
)
port = forms.IntegerField(
2018-01-23 11:37:22 +00:00
label=_('Port'), required=False, min_value=1, max_value=65535,
)
2017-04-12 03:50:15 +00:00
2017-04-11 09:29:53 +00:00
class Meta:
model = Asset
fields = [
'assets', 'port', 'groups', "cluster",
'type', 'env',
2017-04-11 09:29:53 +00:00
]
widgets = {
2018-01-23 11:37:22 +00:00
'groups': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select asset groups')}
),
2017-04-11 09:29:53 +00:00
}
2017-04-12 03:50:15 +00:00
def save(self, commit=True):
changed_fields = []
for field in self._meta.fields:
if self.data.get(field) is not None:
changed_fields.append(field)
cleaned_data = {k: v for k, v in self.cleaned_data.items()
if k in changed_fields}
2017-12-21 03:31:13 +00:00
assets = cleaned_data.pop('assets')
groups = cleaned_data.pop('groups', [])
2017-12-21 03:31:13 +00:00
assets = Asset.objects.filter(id__in=[asset.id for asset in assets])
2017-04-12 03:50:15 +00:00
assets.update(**cleaned_data)
if groups:
for asset in assets:
asset.groups.set(groups)
return assets
2017-04-11 09:29:53 +00:00
2016-08-14 14:10:10 +00:00
class AssetGroupForm(forms.ModelForm):
2016-09-08 14:54:05 +00:00
# See AdminUserForm comment same it
2017-03-24 06:48:18 +00:00
assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(),
label=_('Asset'),
required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')}
2017-03-24 06:48:18 +00:00
)
)
2016-09-05 16:49:42 +00:00
def __init__(self, **kwargs):
instance = kwargs.get('instance')
if instance:
2016-09-05 16:49:42 +00:00
initial = kwargs.get('initial', {})
initial.update({
'assets': instance.assets.all(),
})
kwargs['initial'] = initial
super().__init__(**kwargs)
def save(self, commit=True):
group = super().save(commit=commit)
2018-01-23 11:37:22 +00:00
assets = self.cleaned_data['assets']
group.assets.set(assets)
return group
2016-09-05 16:49:42 +00:00
2016-08-14 14:10:10 +00:00
class Meta:
model = AssetGroup
fields = [
2017-04-07 08:59:09 +00:00
"name", "comment",
2016-08-14 14:10:10 +00:00
]
2016-09-07 12:05:42 +00:00
help_texts = {
'name': '* required',
}
2016-08-14 14:10:10 +00:00
2017-12-07 08:25:50 +00:00
class ClusterForm(forms.ModelForm):
2018-01-05 09:57:02 +00:00
system_users = forms.ModelMultipleChoiceField(
queryset=SystemUser.objects.all(),
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select system users')}
),
label=_('System users'),
required=False,
help_text=_("Selected system users will be create at cluster assets"),
)
2016-09-07 12:51:33 +00:00
2016-08-14 14:10:10 +00:00
class Meta:
2017-12-07 08:25:50 +00:00
model = Cluster
2018-01-05 09:57:02 +00:00
fields = ['name', "bandwidth", "operator", 'contact', 'admin_user', 'system_users',
2017-03-06 13:05:00 +00:00
'phone', 'address', 'intranet', 'extranet', 'comment']
2016-08-14 14:10:10 +00:00
widgets = {
2016-09-07 12:51:33 +00:00
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'intranet': forms.Textarea(attrs={'placeholder': 'IP段之间用逗号隔开192.168.1.0/24,192.168.1.0/24'}),
'extranet': forms.Textarea(attrs={'placeholder': 'IP段之间用逗号隔开201.1.32.1/24,202.2.32.1/24'})
2016-08-14 14:10:10 +00:00
}
2017-03-04 08:38:26 +00:00
help_texts = {
'name': '* required',
2018-01-05 09:57:02 +00:00
'admin_user': _("Cluster level admin user"),
2017-03-04 08:38:26 +00:00
}
2016-09-07 16:59:00 +00:00
2018-01-05 09:57:02 +00:00
def __init__(self, *args, **kwargs):
if kwargs.get('instance', None):
initial = kwargs.get('initial', {})
initial['system_users'] = kwargs['instance'].systemuser_set.all()
super().__init__(*args, **kwargs)
def save(self, commit=True):
instance = super().save(commit=commit)
system_users = self.cleaned_data['system_users']
instance.systemuser_set.set(system_users)
return instance
2016-09-07 16:59:00 +00:00
2016-09-08 10:12:53 +00:00
class AdminUserForm(forms.ModelForm):
2016-09-08 14:54:05 +00:00
# Form field name can not start with `_`, so redefine it,
2017-01-20 12:13:22 +00:00
password = forms.CharField(
2017-12-13 09:21:08 +00:00
widget=forms.PasswordInput, max_length=128,
2017-07-19 23:55:24 +00:00
strip=True, required=False,
2018-01-01 07:08:33 +00:00
help_text=_('Password or private key password'),
label=_("Password"),
2017-01-20 12:13:22 +00:00
)
2016-09-08 14:54:05 +00:00
# Need use upload private key file except paste private key content
private_key_file = forms.FileField(required=False, label=_("Private key"))
2016-09-07 16:59:00 +00:00
2016-09-08 10:12:53 +00:00
def save(self, commit=True):
2016-09-08 14:54:05 +00:00
# Because we define custom field, so we need rewrite :method: `save`
admin_user = super().save(commit=commit)
2016-09-08 10:12:53 +00:00
password = self.cleaned_data['password']
2016-11-06 16:39:26 +00:00
private_key = self.cleaned_data['private_key_file']
public_key = None
if not password:
password = None
2016-09-08 10:12:53 +00:00
2016-11-06 16:39:26 +00:00
if private_key:
2017-12-21 03:31:13 +00:00
public_key = ssh_pubkey_gen(private_key, password=password)
admin_user.set_auth(password=password, public_key=public_key, private_key=private_key)
2016-11-06 16:39:26 +00:00
return admin_user
def clean_private_key_file(self):
private_key_file = self.cleaned_data['private_key_file']
2017-12-21 03:31:13 +00:00
password = self.cleaned_data['password']
2016-11-06 16:39:26 +00:00
if private_key_file:
private_key = private_key_file.read()
2017-12-21 03:31:13 +00:00
if not validate_ssh_private_key(private_key, password):
2016-11-06 16:39:26 +00:00
raise forms.ValidationError(_('Invalid private key'))
return private_key
return private_key_file
def clean(self):
super().clean()
2016-11-06 16:39:26 +00:00
password = self.cleaned_data['password']
private_key_file = self.cleaned_data.get('private_key_file', '')
if not password and not private_key_file:
raise forms.ValidationError(_(
'Password and private key file must be input one'
))
2016-09-08 10:12:53 +00:00
2016-09-07 16:59:00 +00:00
class Meta:
2016-09-08 10:12:53 +00:00
model = AdminUser
2017-03-06 13:05:00 +00:00
fields = ['name', 'username', 'password',
'private_key_file', 'comment']
2016-09-07 16:59:00 +00:00
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
2016-09-08 10:12:53 +00:00
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
}
help_texts = {
'name': '* required',
'username': '* required',
}
2016-09-08 16:09:49 +00:00
class SystemUserForm(forms.ModelForm):
# Admin user assets define, let user select, save it in form not in view
2017-01-10 15:41:14 +00:00
auto_generate_key = forms.BooleanField(initial=True, required=False)
2016-09-08 16:09:49 +00:00
# Form field name can not start with `_`, so redefine it,
2018-01-09 15:14:25 +00:00
password = forms.CharField(widget=forms.PasswordInput, required=False,
max_length=128, strip=True, label=_("Password"))
2016-09-08 16:09:49 +00:00
# Need use upload private key file except paste private key content
2018-01-09 15:14:25 +00:00
private_key_file = forms.FileField(required=False, label=_("Private key"))
2016-09-08 16:09:49 +00:00
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
2017-12-13 09:21:08 +00:00
system_user = super().save()
password = self.cleaned_data.get('password', None)
2017-03-09 06:55:33 +00:00
private_key_file = self.cleaned_data.get('private_key_file')
2017-12-13 09:21:08 +00:00
auto_generate_key = self.cleaned_data.get('auto_generate_key')
2017-12-26 16:14:46 +00:00
private_key = None
public_key = None
2016-09-08 16:09:49 +00:00
2017-12-13 09:21:08 +00:00
if auto_generate_key:
logger.info('Auto set system user auth')
system_user.auto_gen_auth()
else:
2017-12-26 16:14:46 +00:00
if private_key_file:
private_key = private_key_file.read().strip().decode('utf-8')
public_key = ssh_pubkey_gen(private_key=private_key)
2017-12-13 09:21:08 +00:00
system_user.set_auth(password=password, private_key=private_key, public_key=public_key)
return system_user
2016-09-08 16:09:49 +00:00
2017-03-09 06:55:33 +00:00
def clean_private_key_file(self):
2017-12-13 09:21:08 +00:00
if self.cleaned_data.get('private_key_file'):
key_string = self.cleaned_data['private_key_file'].read()
self.cleaned_data['private_key_file'].seek(0)
if not validate_ssh_private_key(key_string):
raise forms.ValidationError(_('Invalid private key'))
2017-03-09 06:55:33 +00:00
return self.cleaned_data['private_key_file']
def clean_password(self):
2017-12-13 09:21:08 +00:00
if not self.cleaned_data.get('password') and \
not self.cleaned_data.get('private_key_file') and \
not self.cleaned_data.get('auto_generate_key'):
raise forms.ValidationError(_('Auth info required, private_key or password'))
2017-03-09 06:55:33 +00:00
return self.cleaned_data['password']
2017-01-10 15:41:14 +00:00
2016-09-08 16:09:49 +00:00
class Meta:
model = SystemUser
fields = [
2017-12-13 09:21:08 +00:00
'name', 'username', 'protocol', 'auto_generate_key',
'password', 'private_key_file', 'auto_push', 'sudo',
'comment', 'shell', 'cluster', 'priority',
2016-09-08 16:09:49 +00:00
]
widgets = {
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
'cluster': forms.SelectMultiple(
2018-01-09 15:14:25 +00:00
attrs={
'class': 'select2',
'data-placeholder': _(' Select clusters')
}
),
2016-09-08 16:09:49 +00:00
}
help_texts = {
'name': '* required',
'username': '* required',
'cluster': _('If auto push checked, system user will be create at cluster assets'),
'auto_push': _('Auto push system user to asset'),
'priority': _('High level will be using login asset as default, if user was granted more than 2 system user'),
2016-10-08 10:33:00 +00:00
}
2016-10-31 11:31:56 +00:00
2017-12-19 04:41:00 +00:00
class SystemUserUpdateForm(SystemUserForm):
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
password = self.cleaned_data.get('password', None)
private_key_file = self.cleaned_data.get('private_key_file')
system_user = super(forms.ModelForm, self).save()
if private_key_file:
private_key = private_key_file.read().strip().decode('utf-8')
public_key = ssh_pubkey_gen(private_key=private_key)
else:
private_key = public_key = None
system_user.set_auth(password=password, private_key=private_key, public_key=public_key)
return system_user
def clean_password(self):
return self.cleaned_data['password']
2017-07-24 14:42:01 +00:00
2017-12-13 09:21:08 +00:00
class SystemUserAuthForm(forms.Form):
password = forms.CharField(widget=forms.PasswordInput, required=False, max_length=128, strip=True)
private_key_file = forms.FileField(required=False)
def clean_private_key_file(self):
if self.cleaned_data.get('private_key_file'):
key_string = self.cleaned_data['private_key_file'].read()
self.cleaned_data['private_key_file'].seek(0)
if not validate_ssh_private_key(key_string):
raise forms.ValidationError(_('Invalid private key'))
return self.cleaned_data['private_key_file']
def clean_password(self):
if not self.cleaned_data.get('password') and \
not self.cleaned_data.get('private_key_file'):
msg = _('Auth info required, private_key or password')
raise forms.ValidationError(msg)
return self.cleaned_data['password']
def update(self, system_user):
password = self.cleaned_data.get('password')
private_key_file = self.cleaned_data.get('private_key_file')
if private_key_file:
private_key = private_key_file.read().strip()
public_key = ssh_pubkey_gen(private_key=private_key)
else:
private_key = None
public_key = None
system_user.set_auth(password=password, private_key=private_key, public_key=public_key)
return system_user
2016-11-27 06:37:50 +00:00
class FileForm(forms.Form):
file = forms.FileField()
2018-01-23 11:37:22 +00:00
class LabelForm(forms.ModelForm):
assets = forms.ModelMultipleChoiceField(
queryset=Asset.objects.all(), label=_('Asset'), required=False,
widget=forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('Select assets')}
)
)
class Meta:
model = Label
fields = ['name', 'value', 'assets']
2018-01-26 07:32:23 +00:00
def __init__(self, *args, **kwargs):
if kwargs.get('instance', None):
initial = kwargs.get('initial', {})
initial['assets'] = kwargs['instance'].assets.all()
super().__init__(*args, **kwargs)
2018-01-23 11:37:22 +00:00
def save(self, commit=True):
label = super().save(commit=commit)
assets = self.cleaned_data['assets']
label.assets.set(assets)
return label