mirror of
https://github.com/RobbieHan/sandboxMP.git
synced 2026-04-04 19:19:08 +08:00
modify cmdb models
This commit is contained in:
@@ -52,8 +52,6 @@ class DeviceCreateForm(forms.ModelForm):
|
||||
exclude = ['dev_connection']
|
||||
error_messages = {
|
||||
'hostname': {'required': '请填写设备地址'},
|
||||
'buyDate': {'required': '请填写购买日期'},
|
||||
'warrantyDate': {'required': '请填写到保日期'}
|
||||
}
|
||||
|
||||
def clean(self):
|
||||
|
||||
@@ -92,12 +92,12 @@ class DeviceInfo(AbstractMode, DeviceAbstract, TimeAbstract):
|
||||
hostname = models.CharField(max_length=50, verbose_name='设备地址(IP或域名)')
|
||||
network_type = models.IntegerField(blank=True, null=True, verbose_name='网络类型')
|
||||
service_type = models.IntegerField(blank=True, null=True, verbose_name='服务类型')
|
||||
operation_type = models.IntegerField(blank=True, null=True, verbose_name='业务类型')
|
||||
leader = models.IntegerField(blank=True, null=True, verbose_name='责任人')
|
||||
operation_type = models.IntegerField(blank=True, null=True, verbose_name='所属项目')
|
||||
config = models.CharField(max_length=80, blank=True, default='', verbose_name='配置信息')
|
||||
dev_cabinet = models.IntegerField(blank=True, null=True, verbose_name='机柜信息')
|
||||
dev_connection = models.IntegerField(blank=True, null=True, verbose_name='连接信息')
|
||||
buyDate = models.DateField(default=datetime.now, verbose_name="购买日期")
|
||||
warrantyDate = models.DateField(default=datetime.now, verbose_name="到保日期")
|
||||
buyDate = models.DateField(default=datetime.now, blank=True, null=True, verbose_name="购买日期")
|
||||
warrantyDate = models.DateField(default=datetime.now, blank=True, null=True, verbose_name="到保日期")
|
||||
desc = models.TextField(blank=True, default='', verbose_name='备注信息')
|
||||
changed_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
|
||||
history = HistoricalRecords(excluded_fields=['add_time', 'modify_time', 'parent'])
|
||||
@@ -120,3 +120,59 @@ class DeviceFile(TimeAbstract):
|
||||
file_content = models.FileField(upload_to="asset_file/%Y/%m", null=True, blank=True, verbose_name="资产文件")
|
||||
upload_user = models.CharField(max_length=20, verbose_name="上传人")
|
||||
|
||||
|
||||
class Supplier(models.Model):
|
||||
firm = models.CharField(max_length=200, verbose_name='供应商')
|
||||
contact_details = models.CharField(max_length=200, verbose_name='联系信息')
|
||||
desc = models.CharField(max_length=200, blank=True, default='', verbose_name='备注信息')
|
||||
|
||||
class Meta:
|
||||
verbose_name = '供应商管理'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
class NetworkAsset(models.Model):
|
||||
name = models.CharField(max_length=100, verbose_name='资产名称')
|
||||
ip_address = models.CharField(max_length=100, blank=True, default='', verbose_name='IP地址')
|
||||
management = models.CharField(max_length=100, blank=True, default='', verbose_name='管理地址')
|
||||
show_on_top = models.BooleanField(default=False, verbose_name='首页展示')
|
||||
provider = models.ForeignKey('Supplier', blank=True, null=True, on_delete=models.SET_NULL, verbose_name='服务商')
|
||||
desc = models.TextField(blank=True, default='', verbose_name='备注信息')
|
||||
|
||||
class Meta:
|
||||
verbose_name = '网络资产'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
class DomainName(AbstractMode):
|
||||
dn_type_choices = (('1', '主域名'),('2', '二级域名'))
|
||||
domain = models.CharField(max_length=200, verbose_name='域名')
|
||||
dn_type = models.CharField(max_length=20, choices=dn_type_choices, default='1')
|
||||
addr_resolution = models.ForeignKey('NatRule', blank=True, null=True,
|
||||
on_delete=models.SET_NULL, verbose_name='解析地址')
|
||||
resolution_server = models.ForeignKey('Supplier', related_name='res_server',
|
||||
blank=True, null=True, on_delete=models.SET_NULL, verbose_name='解析服务')
|
||||
domain_provider = models.ForeignKey('Supplier', related_name='do_provider',
|
||||
blank=True, null=True, on_delete=models.SET_NULL, verbose_name='解析服务')
|
||||
state = models.BooleanField(default=True, verbose_name='状态')
|
||||
ssl = models.FileField(upload_to="ssl_file/%Y/%m", null=True, blank=True, verbose_name="SSL证书")
|
||||
buyDate = models.DateField(default=datetime.now, blank=True, null=True, verbose_name='购买日期')
|
||||
warrantyDate = models.DateField(default=datetime.now, blank=True, null=True, verbose_name='到保日期')
|
||||
desc = models.TextField(blank=True, default='', verbose_name='备注信息')
|
||||
|
||||
class Meta:
|
||||
verbose_name = '域名管理'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
|
||||
class NatRule(models.Model):
|
||||
internet_ip = models.CharField(max_length=80, blank=True, default='', verbose_name='互联网IP')
|
||||
src_port = models.IntegerField(blank=True, default='', verbose_name='源端口')
|
||||
lan_ip = models.CharField(max_length=80, blank=True, default='', verbose_name='内网IP')
|
||||
dest_port = models.IntegerField(blank=True, default='', verbose_name='目的端口')
|
||||
state = models.BooleanField(default=True, verbose_name='状态')
|
||||
desc = models.TextField(blank=True, default='', verbose_name='备注信息')
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'NAT规则'
|
||||
verbose_name_plural = verbose_name
|
||||
@@ -27,8 +27,6 @@ def get_change_compare(changes):
|
||||
log = replace_log(key, value, Code, 'value')
|
||||
elif key == 'dev_cabinet':
|
||||
log = replace_log(key, value, Cabinet, 'number')
|
||||
elif key == 'leader':
|
||||
log = replace_log(key, value, User, 'name')
|
||||
else:
|
||||
log = '字段:"%(field)s",由:"%(old)s",变更为:"%(new)s"。' % {
|
||||
'field': key,
|
||||
|
||||
@@ -38,4 +38,10 @@ urlpatterns = [
|
||||
path('eam/device/file_delete/', views_eam.DeviceFileDeleteView.as_view(), name='eam-device-file_delete'),
|
||||
path('eam/device/auto_update_device_info/', views_eam.AutoUpdateDeviceInfo.as_view(),
|
||||
name='eam-device-auto_update_device_info'),
|
||||
|
||||
path('eam/supplier/', views_eam.SupplierView.as_view(), name='eam-supplier'),
|
||||
path('eam/supplier/create/', views_eam.SupplierCreateView.as_view(), name='eam-supplier-create'),
|
||||
path('eam/supplier/update/', views_eam.SupplierUpdateView.as_view(), name='eam-supplier-update'),
|
||||
path('eam/supplier/list/', views_eam.SupplierListView.as_view(), name='eam-supplier-list'),
|
||||
path('eam/supplier/delete/', views_eam.SupplierDeleteView.as_view(), name='eam-supplier-delete'),
|
||||
]
|
||||
|
||||
@@ -10,7 +10,8 @@ from django.forms.models import model_to_dict
|
||||
from system.mixin import LoginRequiredMixin
|
||||
from custom import (BreadcrumbMixin, SandboxDeleteView,
|
||||
SandboxListView, SandboxUpdateView, SandboxCreateView)
|
||||
from .models import Cabinet, DeviceInfo, Code, ConnectionInfo, DeviceFile
|
||||
from .models import (Cabinet, DeviceInfo, Code, ConnectionInfo, DeviceFile,
|
||||
Supplier)
|
||||
from .forms import DeviceCreateForm, DeviceUpdateForm, ConnectionInfoForm, DeviceFileUploadForm
|
||||
from utils.db_utils import MongodbDriver
|
||||
from utils.sandbox_utils import LoginExecution
|
||||
@@ -75,7 +76,7 @@ class DeviceView(LoginRequiredMixin, BreadcrumbMixin, TemplateView):
|
||||
|
||||
class DeviceListView(SandboxListView):
|
||||
model = DeviceInfo
|
||||
fields = ['id', 'sys_hostname', 'sn_number', 'os_type', 'device_type', 'hostname', 'mac_address', 'leader']
|
||||
fields = ['id', 'sys_hostname', 'hostname', 'service_type', 'operation_type', 'config', 'dev_cabinet', 'network_type']
|
||||
|
||||
def get_filters(self):
|
||||
data = self.request.GET
|
||||
@@ -90,18 +91,23 @@ class DeviceListView(SandboxListView):
|
||||
filters['service_type'] = data['service_type']
|
||||
if 'operation_type' in data and data['operation_type']:
|
||||
filters['operation_type'] = data['operation_type']
|
||||
if 'dev_cabinet' in data and data['dev_cabinet']:
|
||||
filters['dev_cabinet'] = data['dev_cabinet']
|
||||
return filters
|
||||
|
||||
def get_datatables_paginator(self, request):
|
||||
context_data = super().get_datatables_paginator(request)
|
||||
data = context_data['data']
|
||||
for device in data:
|
||||
user_id = device['leader']
|
||||
device['leader'] = get_object_or_404(
|
||||
User, pk=int(user_id)).name if user_id else ''
|
||||
service_type = device['service_type']
|
||||
operation_type = device['operation_type']
|
||||
dev_cabinet = device['dev_cabinet']
|
||||
network_type = device['network_type']
|
||||
device['operation_type'] = get_object_or_404(Code, pk=int(operation_type)).value if operation_type else ''
|
||||
device['network_type'] = get_object_or_404(Code, pk=int(network_type)).value if network_type else ''
|
||||
device['service_type'] = get_object_or_404(Code, pk=int(service_type)).value if service_type else ''
|
||||
device['dev_cabinet'] = get_object_or_404(Cabinet, pk=int(dev_cabinet)).number if dev_cabinet else ''
|
||||
return context_data
|
||||
|
||||
|
||||
class DeviceCreateView(SandboxCreateView):
|
||||
model = DeviceInfo
|
||||
form_class = DeviceCreateForm
|
||||
@@ -233,3 +239,35 @@ class AutoUpdateDeviceInfo(LoginRequiredMixin, View):
|
||||
else:
|
||||
res['status'] = 'con_empty'
|
||||
return JsonResponse(res)
|
||||
|
||||
|
||||
class SupplierView(LoginRequiredMixin, BreadcrumbMixin, TemplateView):
|
||||
template_name = 'cmdb/supplier.html'
|
||||
|
||||
|
||||
class SupplierCreateView(SandboxCreateView):
|
||||
model = Supplier
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class SupplierUpdateView(SandboxUpdateView):
|
||||
model = Supplier
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class SupplierListView(SandboxListView):
|
||||
model = Supplier
|
||||
fields = '__all__'
|
||||
|
||||
def get_filters(self):
|
||||
data = self.request.GET
|
||||
filters = {}
|
||||
if 'number' in data and data['number']:
|
||||
filters['number__icontains'] = data['number']
|
||||
if 'position' in data and data['position']:
|
||||
filters['position__icontains'] = data['position']
|
||||
return filters
|
||||
|
||||
|
||||
class SupplierDeleteView(SandboxDeleteView):
|
||||
model = Supplier
|
||||
@@ -25,7 +25,8 @@ User = get_user_model()
|
||||
class IndexView(LoginRequiredMixin, View):
|
||||
|
||||
def get(self, request):
|
||||
return render(request, 'index.html')
|
||||
#return render(request, 'index.html')
|
||||
return HttpResponseRedirect('/cmdb/')
|
||||
|
||||
|
||||
class LoginView(View):
|
||||
@@ -34,10 +35,10 @@ class LoginView(View):
|
||||
if not request.user.is_authenticated:
|
||||
return render(request, 'system/users/login.html')
|
||||
else:
|
||||
return HttpResponseRedirect('/')
|
||||
return HttpResponseRedirect('/cmdb/')
|
||||
|
||||
def post(self, request):
|
||||
redirect_to = request.GET.get('next', '/')
|
||||
redirect_to = request.GET.get('next', '/cmdb/')
|
||||
login_form = LoginForm(request.POST)
|
||||
ret = dict(login_form=login_form)
|
||||
print(request.META.get('REMOTE_ADDR'))
|
||||
|
||||
@@ -5,10 +5,10 @@ ipython==7.1.1
|
||||
pyyaml==4.2b1
|
||||
ruamel.yaml==0.15.80
|
||||
python-nmap==0.6.1
|
||||
redis==3.0.1
|
||||
redis==3.2.1
|
||||
pymongo==3.7.1
|
||||
paramiko==2.4.2
|
||||
django-simple-history==2.6.0
|
||||
celery==4.2.1
|
||||
celery-once==2.0.0
|
||||
flower==0.9.2
|
||||
flower
|
||||
|
||||
@@ -8,7 +8,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>SandBoxMP</title>
|
||||
<title>cmdb</title>
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.min.css' %}">
|
||||
@@ -50,9 +50,9 @@ scratch. This page gets rid of all links and provides the needed markup only.
|
||||
<i class="menu-icon fa fa-birthday-cake bg-red"></i>
|
||||
|
||||
<div class="menu-info">
|
||||
<h4 class="control-sidebar-subheading">SandBox</h4>
|
||||
<h4 class="control-sidebar-subheading">CMDB</h4>
|
||||
|
||||
<p>沙盒运维管理平台</p>
|
||||
<p>内部资产管理系统</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
@@ -76,7 +76,7 @@ scratch. This page gets rid of all links and provides the needed markup only.
|
||||
<!-- Settings tab content -->
|
||||
<div class="tab-pane" id="control-sidebar-settings-tab">
|
||||
<form method="post">
|
||||
<h3 class="control-sidebar-heading">江苏沙盒科技</h3>
|
||||
<h3 class="control-sidebar-heading"></h3>
|
||||
|
||||
<div class="form-group">
|
||||
<p>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group searchArea margin-r-5 margin-top-5">
|
||||
<label>业务类型:</label>
|
||||
<label>所属项目:</label>
|
||||
<select class="form-control inputText select2" name="operation_type" , id="operation_type">
|
||||
<option></option>
|
||||
{% for code in all_code %}
|
||||
@@ -76,6 +76,17 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group searchArea margin-r-5 margin-top-5">
|
||||
<label>机柜信息:</label>
|
||||
<select class="form-control inputText select2" name="dev_cabinet" , id="dev_cabinet">
|
||||
<option></option>
|
||||
{% for cabinet in all_cabinet %}
|
||||
|
||||
<option value="{{ cabinet.id }}">{{ cabinet.number }}</option>
|
||||
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<button type="button" id="btnSearch" class="btn btn-default">
|
||||
<i class="glyphicon glyphicon-search"></i>查询
|
||||
</button>
|
||||
@@ -89,12 +100,12 @@
|
||||
<th><input type="checkbox" id="checkAll"></th>
|
||||
<th>ID</th>
|
||||
<th>主机名</th>
|
||||
<th>SN编号</th>
|
||||
<th>系统类型</th>
|
||||
<th>设备类型</th>
|
||||
<th>设备地址</th>
|
||||
<th>MAC地址</th>
|
||||
<th>责任人</th>
|
||||
<th>IP地址</th>
|
||||
<th>服务类型</th>
|
||||
<th>所属项目</th>
|
||||
<th>配置信息</th>
|
||||
<th>机柜信息</th>
|
||||
<th>网络类型</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -146,6 +157,7 @@
|
||||
d.network_type = $("#network_type").val();
|
||||
d.service_type = $("#service_type").val();
|
||||
d.operation_type = $("#operation_type").val();
|
||||
d.dev_cabinet = $("#dev_cabinet").val();
|
||||
}
|
||||
},
|
||||
columns: [
|
||||
@@ -157,23 +169,23 @@
|
||||
{
|
||||
data: "sys_hostname",
|
||||
},
|
||||
{
|
||||
data: "sn_number",
|
||||
},
|
||||
{
|
||||
data: "os_type",
|
||||
},
|
||||
{
|
||||
data: "device_type",
|
||||
},
|
||||
{
|
||||
data: "hostname",
|
||||
},
|
||||
{
|
||||
data: "mac_address",
|
||||
data: "service_type",
|
||||
},
|
||||
{
|
||||
data: "leader",
|
||||
data: "operation_type",
|
||||
},
|
||||
{
|
||||
data: "config",
|
||||
},
|
||||
{
|
||||
data: "dev_cabinet",
|
||||
},
|
||||
{
|
||||
data: "network_type",
|
||||
},
|
||||
{
|
||||
data: "id",
|
||||
|
||||
@@ -82,8 +82,8 @@
|
||||
{{ device.parent.sys_hostname }}({{ device.parent.hostname }})
|
||||
{% endif %}
|
||||
</td>
|
||||
<td><strong>责任人</strong></td>
|
||||
<td>{% get_con all_user device.leader 'name' %}</td>
|
||||
<td><strong>配置信息</strong></td>
|
||||
<td>{{ device.config }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>入库时间</strong></td>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group has-feedback">
|
||||
<label class="col-sm-2 control-label">业务类型</label>
|
||||
<label class="col-sm-2 control-label">所属项目</label>
|
||||
<div class="col-sm-3">
|
||||
<select class="form-control select2" style="width:100%;" name="operation_type">
|
||||
<option {% ifequal deviceinfo.operation_type '' %}selected="selected"{% endifequal %}></option>
|
||||
@@ -121,15 +121,9 @@
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<label class="col-sm-2 control-label">责任人</label>
|
||||
<div class="col-sm-3">
|
||||
<select class="form-control select2" style="width:100%;" name="leader">
|
||||
<option {% ifequal deviceinfo.leader '' %}selected="selected"{% endifequal %}></option>
|
||||
{% for u in all_user %}
|
||||
<option value="{{ u.id }}" {% ifequal deviceinfo.leader u.id %}selected="selected"{% endifequal %}>
|
||||
{{ u.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label class="col-sm-2 control-label">配置信息</label>
|
||||
<div class="col-sm-3">
|
||||
<input class="form-control" name="config" type="text" value="{{ deviceinfo.config }}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group has-feedback">
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<!-- Logo -->
|
||||
<a href="#" class="logo">
|
||||
<!-- mini logo for sidebar mini 50x50 pixels -->
|
||||
<span class="logo-mini"><b>SMP</b></span>
|
||||
<span class="logo-mini"><b>CMDB</b></span>
|
||||
<!-- logo for regular state and mobile devices -->
|
||||
<span class="logo-lg"><b>SandboxMP</b></span>
|
||||
<span class="logo-lg"><b>CMDB</b></span>
|
||||
</a>
|
||||
|
||||
<!-- Header Navbar -->
|
||||
@@ -109,10 +109,10 @@
|
||||
<footer class="main-footer text-center">
|
||||
<strong>
|
||||
|
||||
Copyright © 2016-2017 沙盒科技
|
||||
Copyright © 2016-2017
|
||||
|
||||
</strong>
|
||||
技术支持:<a href="https://zhuanlan.zhihu.com/sandbox" target="_blank">RobbieHan</a>
|
||||
技术支持:<a href="#" target="_blank">RobbieHan</a>
|
||||
</footer>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>{% if system_setup.HeadTitle %}{{ system_setup.HeadTitle }}{% else %}SandBox{% endif %}</title>
|
||||
<title>{% if system_setup.HeadTitle %}{{ system_setup.HeadTitle }}{% else %}cmdb{% endif %}</title>
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<!-- Bootstrap 3.3.6 -->
|
||||
@@ -27,7 +27,7 @@
|
||||
<body class="hold-transition login-page">
|
||||
<div class="login-box">
|
||||
<div class="login-logo">
|
||||
{% if system_setup.loginTitle %}{{ system_setup.loginTitle }}{% else %}沙盒协同办公平台{% endif %}
|
||||
{% if system_setup.loginTitle %}{{ system_setup.loginTitle }}{% else %}内部资产管理系统{% endif %}
|
||||
</div>
|
||||
{% block user-content %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user