mirror of https://github.com/jumpserver/jumpserver
Modify asset create
parent
acfe8950b8
commit
d323c9df88
|
@ -1,7 +1,7 @@
|
||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser
|
from .models import IDC, Asset, AssetGroup, AdminUser, SystemUser, Tag
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,13 +23,35 @@ from django.utils.translation import gettext_lazy as _
|
||||||
#
|
#
|
||||||
|
|
||||||
class AssetCreateForm(forms.ModelForm):
|
class AssetCreateForm(forms.ModelForm):
|
||||||
|
tags = forms.CharField(label=_('Tags'), widget=forms.TextInput(attrs={'id': 'tags'}),
|
||||||
|
help_text='Use `,` split')
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
instance = kwargs.get('instance')
|
||||||
|
|
||||||
|
if instance:
|
||||||
|
initial = kwargs.get('initial', {})
|
||||||
|
tags = Tag.objects.filter(asset=instance)
|
||||||
|
tags_value = ','.join([tag.value for tag in tags])
|
||||||
|
initial['tags'] = tags_value
|
||||||
|
super(AssetCreateForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _save_m2m(self):
|
||||||
|
tags = self.cleaned_data['tags']
|
||||||
|
|
||||||
|
if tags:
|
||||||
|
value_list = tags.split(',')
|
||||||
|
self.instance.tags.all().delete()
|
||||||
|
Tag.objects.bulk_create(
|
||||||
|
[Tag(value=value) for value in value_list]
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
|
|
||||||
fields = [
|
fields = [
|
||||||
'hostname', 'ip', 'port', 'type', 'zone', 'comment', 'admin_user', 'system_users', 'idc', 'groups'
|
'hostname', 'ip', 'port', 'type', 'comment', 'admin_user', 'system_users', 'idc', 'groups'
|
||||||
]
|
]
|
||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
'groups': forms.SelectMultiple(attrs={'class': 'select2',
|
'groups': forms.SelectMultiple(attrs={'class': 'select2',
|
||||||
'data-placeholder': _('Select asset groups')}),
|
'data-placeholder': _('Select asset groups')}),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
from __future__ import unicode_literals, absolute_import
|
from __future__ import unicode_literals, absolute_import
|
||||||
|
|
||||||
|
import functools
|
||||||
from django.db import models
|
from django.db import models
|
||||||
import logging
|
import logging
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
@ -25,6 +26,10 @@ class IDC(models.Model):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def initial(cls):
|
||||||
|
return cls.objects.get_or_create(name=_('Default'), created_by=_('System'), comment=_('Default IDC'))[0]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'idc'
|
db_table = 'idc'
|
||||||
|
|
||||||
|
@ -77,13 +82,12 @@ class AssetExtend(models.Model):
|
||||||
(_('env'), _('Production')),
|
(_('env'), _('Production')),
|
||||||
(_('env'), _('Development')),
|
(_('env'), _('Development')),
|
||||||
(_('env'), _('Testing')),
|
(_('env'), _('Testing')),
|
||||||
(_('zone'), _('Default')),
|
|
||||||
):
|
):
|
||||||
cls.objects.create(key=k, value=v, created_by='System')
|
cls.objects.create(key=k, value=v, created_by='System')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'asset_extend'
|
db_table = 'asset_extend'
|
||||||
index_together = ('key', 'value')
|
unique_together = ('key', 'value')
|
||||||
|
|
||||||
|
|
||||||
class AdminUser(models.Model):
|
class AdminUser(models.Model):
|
||||||
|
@ -272,12 +276,16 @@ class AssetGroup(models.Model):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
class Asset(models.Model):
|
def get_default_extend(key, value):
|
||||||
STATUS_DEFAULT = AssetExtend.objects.get_or_create(key='status', value=_('In use'))
|
return AssetExtend.objects.get_or_create(key=key, value=value)[0]
|
||||||
TYPE_DEFAULT = AssetExtend.objects.get_or_create(key='type', value=_('Server'))
|
|
||||||
ZONE_DEFAULT = AssetExtend.objects.get_or_create(key='zone', value=_('Default'))
|
|
||||||
|
|
||||||
ip = models.CharField(max_length=32, verbose_name=_('IP'))
|
|
||||||
|
def get_default_idc():
|
||||||
|
return IDC.initial()
|
||||||
|
|
||||||
|
|
||||||
|
class Asset(models.Model):
|
||||||
|
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'))
|
||||||
other_ip = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('Other IP'))
|
other_ip = models.CharField(max_length=255, null=True, blank=True, verbose_name=_('Other IP'))
|
||||||
remote_card_ip = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('Remote card IP'))
|
remote_card_ip = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('Remote card IP'))
|
||||||
hostname = models.CharField(max_length=128, blank=True, verbose_name=_('Hostname'))
|
hostname = models.CharField(max_length=128, blank=True, verbose_name=_('Hostname'))
|
||||||
|
@ -286,7 +294,9 @@ class Asset(models.Model):
|
||||||
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets',
|
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets',
|
||||||
on_delete=models.SET_NULL, verbose_name=_("Admin user"))
|
on_delete=models.SET_NULL, verbose_name=_("Admin user"))
|
||||||
system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User"))
|
system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User"))
|
||||||
idc = models.ForeignKey(IDC, null=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('IDC'))
|
idc = models.ForeignKey(IDC, null=True, related_name='assets',
|
||||||
|
on_delete=models.SET_NULL, verbose_name=_('IDC'),
|
||||||
|
default=get_default_idc)
|
||||||
mac_address = models.CharField(max_length=20, null=True, blank=True, verbose_name=_("Mac address"))
|
mac_address = models.CharField(max_length=20, null=True, blank=True, verbose_name=_("Mac address"))
|
||||||
brand = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Brand'))
|
brand = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Brand'))
|
||||||
cpu = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('CPU'))
|
cpu = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('CPU'))
|
||||||
|
@ -296,14 +306,15 @@ class Asset(models.Model):
|
||||||
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
|
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
|
||||||
cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position'))
|
cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position'))
|
||||||
number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number'))
|
number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number'))
|
||||||
status = models.ForeignKey(AssetExtend, null=True, blank=True, related_name="status_asset",
|
status = models.ForeignKey(AssetExtend, null=True, blank=True,
|
||||||
default=STATUS_DEFAULT, verbose_name=_('Asset status'))
|
related_name="status_asset", verbose_name=_('Asset status'),
|
||||||
|
default=functools.partial(get_default_extend, 'status', 'In use'))
|
||||||
type = models.ForeignKey(AssetExtend, null=True, limit_choices_to={'key': 'type'},
|
type = models.ForeignKey(AssetExtend, null=True, limit_choices_to={'key': 'type'},
|
||||||
default=TYPE_DEFAULT, related_name="type_asset", verbose_name=_('Asset type'))
|
related_name="type_asset", verbose_name=_('Asset type'),
|
||||||
|
default=functools.partial(get_default_extend, 'type','Server'))
|
||||||
env = models.ForeignKey(AssetExtend, null=True, limit_choices_to={'key': 'env'},
|
env = models.ForeignKey(AssetExtend, null=True, limit_choices_to={'key': 'env'},
|
||||||
related_name="env_asset", verbose_name=_('Asset environment'))
|
related_name="env_asset", verbose_name=_('Asset environment'),
|
||||||
zone = models.ForeignKey(AssetExtend, null=True, limit_choices_to={'key': 'zone'}, default=ZONE_DEFAULT,
|
default=functools.partial(get_default_extend, 'env', 'Production'))
|
||||||
related_name="zone_asset", verbose_name=_('Asset zone'))
|
|
||||||
sn = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Serial number'))
|
sn = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Serial number'))
|
||||||
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
|
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
|
||||||
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
||||||
|
@ -318,7 +329,7 @@ class Asset(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'asset'
|
db_table = 'asset'
|
||||||
index_together = ('ip', 'port')
|
unique_together = ('ip', 'port')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_fake(cls, count=100):
|
def generate_fake(cls, count=100):
|
||||||
|
@ -345,17 +356,15 @@ class Asset(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class Tag(models.Model):
|
class Tag(models.Model):
|
||||||
key = models.CharField(max_length=64, blank=True, verbose_name=_('KEY'))
|
|
||||||
value = models.CharField(max_length=64, verbose_name=_('VALUE'))
|
value = models.CharField(max_length=64, verbose_name=_('VALUE'))
|
||||||
asset = models.ForeignKey(Asset, null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_('Asset'))
|
asset = models.ForeignKey(Asset, related_name='tags', on_delete=models.CASCADE, verbose_name=_('Asset'))
|
||||||
created_by = models.CharField(max_length=32, blank=True, verbose_name=_("Created by"))
|
|
||||||
date_created = models.DateTimeField(auto_now=True, null=True)
|
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.key
|
return self.value
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'label'
|
db_table = 'tag'
|
||||||
|
unique_together = ('value', 'asset')
|
||||||
|
|
||||||
|
|
||||||
def initial():
|
def initial():
|
||||||
|
@ -366,3 +375,8 @@ def initial():
|
||||||
def generate_fake():
|
def generate_fake():
|
||||||
for cls in (AssetGroup, IDC, AdminUser, SystemUser, Asset):
|
for cls in (AssetGroup, IDC, AdminUser, SystemUser, Asset):
|
||||||
cls.generate_fake()
|
cls.generate_fake()
|
||||||
|
|
||||||
|
|
||||||
|
def flush_all():
|
||||||
|
for cls in (AssetGroup, AssetExtend, IDC, AdminUser, SystemUser, Asset):
|
||||||
|
cls.objects.all().delete()
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
{{ form.ip|bootstrap_horizontal }}
|
{{ form.ip|bootstrap_horizontal }}
|
||||||
{{ form.port|bootstrap_horizontal }}
|
{{ form.port|bootstrap_horizontal }}
|
||||||
{{ form.type|bootstrap_horizontal }}
|
{{ form.type|bootstrap_horizontal }}
|
||||||
{{ form.zone|bootstrap_horizontal }}
|
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<h3>{% trans 'Group' %}</h3>
|
<h3>{% trans 'Group' %}</h3>
|
||||||
|
@ -30,13 +29,14 @@
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<h3>{% trans 'Other' %}</h3>
|
<h3>{% trans 'Other' %}</h3>
|
||||||
<div class="form-group">
|
{# <div class="form-group">#}
|
||||||
<label for="tags" class="col-sm-2 control-label">Tags</label>
|
{# <label for="tags" class="col-sm-2 control-label">Tags</label>#}
|
||||||
<div class="col-sm-9 col-lg-9 " style="background-color: #fff">
|
{# <div class="col-sm-9 col-lg-9 " style="background-color: #fff">#}
|
||||||
<input id="tags" name="tags" type="text" class="form-control">
|
{# <input id="tags" name="tags" type="text" class="form-control">#}
|
||||||
<p class="help-block" >{% trans 'Tips: Use `,` split' %}</p>
|
{# <p class="help-block" >{% trans 'Tips: Use `,` split' %}</p>#}
|
||||||
</div>
|
{# </div>#}
|
||||||
</div>
|
{# </div>#}
|
||||||
|
{{ form.tags|bootstrap_horizontal }}
|
||||||
{{ form.comment|bootstrap_horizontal }}
|
{{ form.comment|bootstrap_horizontal }}
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{% url 'assets:asset-update' pk=user.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>
|
<a href="{% url 'assets:asset-update' pk=asset.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>
|
||||||
<a href="{% url 'assets:asset-delete' pk=user.id %}" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>-
|
<a href="{% url 'assets:asset-delete' pk=asset.id %}" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>-
|
||||||
{# <a href="{% url '' %}">{% trans 'Delete' %}</a>#}
|
{# <a href="{% url '' %}">{% trans 'Delete' %}</a>#}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -10,6 +10,8 @@ from django.urls import reverse_lazy
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.views.generic.detail import DetailView, SingleObjectMixin
|
from django.views.generic.detail import DetailView, SingleObjectMixin
|
||||||
|
|
||||||
|
|
||||||
|
from common.utils import int_seq
|
||||||
from .models import Asset, AssetGroup, IDC, AssetExtend, AdminUser, SystemUser, Tag
|
from .models import Asset, AssetGroup, IDC, AssetExtend, AdminUser, SystemUser, Tag
|
||||||
from .forms import AssetCreateForm, AssetGroupForm, IDCForm, AdminUserForm, SystemUserForm
|
from .forms import AssetCreateForm, AssetGroupForm, IDCForm, AdminUserForm, SystemUserForm
|
||||||
from .hands import AdminUserRequiredMixin
|
from .hands import AdminUserRequiredMixin
|
||||||
|
@ -21,6 +23,11 @@ class AssetListView(ListView):
|
||||||
context_object_name = 'asset_list'
|
context_object_name = 'asset_list'
|
||||||
template_name = 'assets/asset_list.html'
|
template_name = 'assets/asset_list.html'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super(AssetListView, self).get_queryset()
|
||||||
|
queryset = sorted(queryset, key=lambda asset: int_seq(asset.ip.split('.')))
|
||||||
|
return queryset
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
'app': 'Assets',
|
'app': 'Assets',
|
||||||
|
@ -36,12 +43,10 @@ class AssetCreateView(AdminUserRequiredMixin, CreateView):
|
||||||
template_name = 'assets/asset_create_update.html'
|
template_name = 'assets/asset_create_update.html'
|
||||||
success_url = reverse_lazy('assets:asset-list')
|
success_url = reverse_lazy('assets:asset-list')
|
||||||
|
|
||||||
def form_valid(self, form):
|
# def form_valid(self, form):
|
||||||
asset = form.save(commit=False)
|
# asset = form.save()
|
||||||
key = self.request.POST.get('key', '')
|
# print(self.request.POST.get('tags'))
|
||||||
value = self.request.POST.get('value', '')
|
# return super(AssetCreateView, self).form_valid(form)
|
||||||
asset.save()
|
|
||||||
return super(AssetCreateView, self).form_valid(form)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
|
@ -58,6 +63,7 @@ class AssetUpdateView(UpdateView):
|
||||||
|
|
||||||
class AssetDeleteView(DeleteView):
|
class AssetDeleteView(DeleteView):
|
||||||
model = Asset
|
model = Asset
|
||||||
|
template_name = 'assets/delete_confirm.html'
|
||||||
success_url = reverse_lazy('assets:asset-list')
|
success_url = reverse_lazy('assets:asset-list')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -100,3 +100,10 @@ def search_object_attr(obj, value='', attr_list=None, ignore_case=False):
|
||||||
|
|
||||||
def get_logger(name=None):
|
def get_logger(name=None):
|
||||||
return logging.getLogger('jumpserver.%s' % name)
|
return logging.getLogger('jumpserver.%s' % name)
|
||||||
|
|
||||||
|
|
||||||
|
def int_seq(seq):
|
||||||
|
try:
|
||||||
|
return map(int, seq)
|
||||||
|
except ValueError:
|
||||||
|
return seq
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue