cmdb merge model and url

pull/530/head
wangyong 2016-09-04 19:15:31 +08:00
commit 69349368bf
9 changed files with 206 additions and 59 deletions

View File

@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _
class AssetGroup(models.Model): class AssetGroup(models.Model):
name = models.CharField(max_length=64, unique=True, null=True, blank=True, verbose_name=_('Name')) name = models.CharField(max_length=64, unique=True, null=True, blank=True, verbose_name=_('Name'))
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'))
comment = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Comment')) comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
return self.name return self.name
@ -27,7 +27,7 @@ class IDC(models.Model):
date_added = models.DateField(auto_now=True, null=True, verbose_name=_('Date added')) date_added = models.DateField(auto_now=True, null=True, verbose_name=_('Date added'))
operator = models.CharField(max_length=32, blank=True, verbose_name=_('Operator')) operator = models.CharField(max_length=32, blank=True, verbose_name=_('Operator'))
created_by = models.CharField(max_length=32, blank=True, verbose_name=_('Created by')) created_by = models.CharField(max_length=32, blank=True, verbose_name=_('Created by'))
comment = models.CharField(max_length=128, blank=True, verbose_name=_('Comment')) comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
return self.name return self.name
@ -37,11 +37,11 @@ class IDC(models.Model):
class AssetExtend(models.Model): class AssetExtend(models.Model):
key = models.CharField(max_length=64, null=True, blank=True, verbose_name=u'key') key = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('KEY'))
value = models.CharField(max_length=64, null=True, blank=True, verbose_name=u'value') value = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('VALUE'))
created_by = models.CharField(max_length=32, blank=True, verbose_name=u"Created by") created_by = models.CharField(max_length=32, blank=True, verbose_name=_("Created by"))
date_added = models.DateTimeField(auto_now=True, null=True, blank=True) date_added = models.DateTimeField(auto_now=True, null=True, blank=True)
comment = models.CharField(max_length=128, blank=True, verbose_name=u"Comment") comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
return self.name return self.name
@ -51,15 +51,15 @@ class AssetExtend(models.Model):
class AdminUser(models.Model): class AdminUser(models.Model):
name = models.CharField(max_length=128, unique=True, null=True, blank=True, verbose_name=u"用户名称") name = models.CharField(max_length=128, unique=True, null=True, blank=True, verbose_name=_('Name'))
username = models.CharField(max_length=16, null=True, blank=True, verbose_name=u"用户名") username = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('Username'))
password = models.CharField(max_length=256, null=True, blank=True, verbose_name=u"密码") password = models.CharField(max_length=256, null=True, blank=True, verbose_name=_('Password'))
private_key = models.CharField(max_length=4096, null=True, blank=True, verbose_name=u"私钥") private_key = models.CharField(max_length=4096, null=True, blank=True, verbose_name=_('SSH private key'))
is_default = models.BooleanField(default=True, verbose_name=u"是否默认") is_default = models.BooleanField(default=True, verbose_name=_('As default'))
auto_update = models.BooleanField(default=True, verbose_name=u"自动更新") auto_update = models.BooleanField(default=True, verbose_name=_('Auto update pass/key'))
date_added = models.DateTimeField(auto_now=True, null=True, blank=True) date_added = models.DateTimeField(auto_now=True, null=True, blank=True)
create_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=u"创建者") create_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
comment = models.CharField(max_length=128, blank=True, verbose_name=u"备注") comment = models.TextField(blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
return self.name return self.name
@ -69,22 +69,26 @@ class AdminUser(models.Model):
class SysUser(models.Model): class SysUser(models.Model):
name = models.CharField(max_length=128, unique=True, null=True, blank=True, verbose_name=u"用户名称") PROTOCOL_CHOICES = (
username = models.CharField(max_length=16, null=True, blank=True, verbose_name=u"用户名") ('ssh', 'ssh'),
password = models.CharField(max_length=256, null=True, blank=True, verbose_name=u"密码") ('telnet', 'telnet'),
protocol = models.CharField(max_length=16, null=True, blank=True, verbose_name=u"协议") )
private_key = models.CharField(max_length=4096, null=True, blank=True, verbose_name=u"私钥") name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
public_key = models.CharField(max_length=4096, null=True, blank=True, verbose_name=u"公钥") username = models.CharField(max_length=16, blank=True, verbose_name=_('Username'))
is_default = models.BooleanField(default=True, verbose_name=u"是否显示") password = models.CharField(max_length=256, blank=True, verbose_name=_('Password'))
auto_push = models.BooleanField(default=True, verbose_name=u"自动推送") protocol = models.CharField(max_length=16, default='ssh', verbose_name=_('Protocol'))
auto_update = models.BooleanField(default=True, verbose_name=u"自动更新") private_key = models.CharField(max_length=4096, blank=True, verbose_name=_('SSH private key'))
sudo = models.CharField(max_length=4096, null=True, blank=True, verbose_name=u"私钥") public_key = models.CharField(max_length=4096, blank=True, verbose_name=_('SSH public key'))
shell = models.CharField(max_length=64, null=True, blank=True, verbose_name=u"shell环境") is_default = models.BooleanField(default=True, verbose_name=_('As default'))
home = models.CharField(max_length=64, null=True, blank=True, verbose_name=u"home目录") auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
uid = models.IntegerField(null=True, blank=True, verbose_name=u"uid") auto_update = models.BooleanField(default=True, verbose_name=_('Auto update pass/key'))
date_added = models.DateTimeField(auto_now=True, null=True, blank=True) sudo = models.TextField(max_length=4096, blank=True, verbose_name=_('Sudo'))
create_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=u"创建者") shell = models.CharField(max_length=64, blank=True, verbose_name=_('Shell'))
comment = models.CharField(max_length=128, blank=True, verbose_name=u"备注") home = models.CharField(max_length=64, blank=True, verbose_name=_('Home'))
uid = models.IntegerField(blank=True, verbose_name=_('Uid'))
date_added = models.DateTimeField(auto_now=True, null=True)
create_by = models.CharField(max_length=32, blank=True, verbose_name=_('Created by'))
comment = models.CharField(max_length=128, blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
return self.name return self.name
@ -114,12 +118,9 @@ 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, unique=True, verbose_name=_('Asset number')) number = models.CharField(max_length=32, null=True, blank=True, unique=True, verbose_name=_('Asset number'))
status = models.ForeignKey(AssetExtend, related_name="asset_extend_status", null=True, status = models.ManyToManyField(AssetExtend, related_name="asset_status_extend", verbose_name=_('Asset status'))
blank=True, verbose_name=_('Asset status')) type = models.ManyToManyField(AssetExtend, related_name="asset_type_extend", verbose_name=_('Asset type'))
type = models.ForeignKey(AssetExtend, related_name="asset_extend_type", null=True, env = models.ManyToManyField(AssetExtend, related_name="asset_env_extend", verbose_name=_('Asset environment'))
blank=True, verbose_name=_('Asset type'))
env = models.ForeignKey(AssetExtend, related_name="asset_extend_env", null=True,
blank=True, verbose_name=_('Asset environment'))
sn = models.CharField(max_length=128, null=True, blank=True, unique=True, verbose_name=_('Serial number')) sn = models.CharField(max_length=128, null=True, blank=True, unique=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'))
@ -134,11 +135,11 @@ class Asset(models.Model):
class Label(models.Model): class Label(models.Model):
key = models.CharField(max_length=64, null=True, blank=True, verbose_name=u'key') key = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('KEY'))
value = models.CharField(max_length=64, null=True, blank=True, verbose_name=u'value') value = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('VALUE'))
asset = models.ForeignKey(Asset, null=True, blank=True, on_delete=models.SET_NULL, verbose_name=u'label') asset = models.ForeignKey(Asset, null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_('Asset'))
created_by = models.CharField(max_length=32, blank=True, verbose_name=_("Created by")) created_by = models.CharField(max_length=32, blank=True, verbose_name=_("Created by"))
date_added = models.DateTimeField(auto_now=True, null=True, blank=True) date_added = models.DateTimeField(auto_now=True, null=True)
comment = models.CharField(max_length=128, blank=True, verbose_name=_('Comment')) comment = models.CharField(max_length=128, blank=True, verbose_name=_('Comment'))
def __unicode__(self): def __unicode__(self):
@ -147,4 +148,3 @@ class Label(models.Model):
class Meta: class Meta:
db_table = 'label' db_table = 'label'

View File

@ -0,0 +1,66 @@
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>{% trans 'Create asset group' %}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form method="post" id="userForm" class="form-horizontal" action="" >
{% csrf_token %}
{{ form.name|bootstrap_horizontal }}
<div class="form-group">
<label for="users" class="col-sm-2 control-label">{% trans 'Asset' %}</label>
<div class="col-sm-9">
<select name="assets" id="assets" data-placeholder="{% trans 'Select asset' %}" class="select2 form-control m-b" multiple tabindex="2">
{% for asset in assets %}
<option value="{{ asset.id }}">{{ asset.hostname }}</option>
{% endfor %}
</select>
</div>
</div>
{{ form.comment|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
$('.select2').select2();
})
</script>
{% endblock %}

View File

@ -0,0 +1,59 @@
{% extends '_list_base.html' %}
{% load i18n %}
{% load common_tags %}
{% block content_left_head %}
<a href="{% url 'assets:assetgroup-add' %}" class="btn btn-sm btn-primary "> {% trans "Create asset group" %} </a>
{% endblock %}
{% block table_head %}
<th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th>
<th class="text-center"><a href="{% url 'assets:assetgroup-list' %}?sort=name">{% trans 'Name' %}</a></th>
<th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center"><a href="{% url 'assets:assetgroup-list' %}?sort=date_expired">{% trans 'Comment' %}</a></th>
<th class="text-center"></th>
{% endblock %}
{% block table_body %}
{% for assetgroup in assetgroups %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="checked" value="{{ user.id }}">
</td>
<td class="text-center">
<a href="{% url 'assets:assetgroup-detail' pk=user.id %}">
{{ assetgroup.name }}
</a>
</td>
<td class="text-center">{{ assetgroup.comment }}</td>
<td class="text-center">{{ assetgroup.comment }}</td>
<td class="text-center">
<a href="{% url 'users:user-edit' pk=user.id %}" class="btn btn-xs btn-info">{% trans 'Edit' %}</a>
<a href="{% url 'users:user-delete' pk=user.id %}" class="btn btn-xs btn-danger del {% if user.id == request.user.id or user.username == 'admin' %} disabled {% endif %}">{% trans 'Delete' %}</a>
</td>
</tr>
{% endfor %}
{% endblock %}
{% block content_bottom_left %}
<form id="" method="get" action="" class=" mail-search">
<div class="input-group">
<select class="form-control m-b" style="width: auto">
<option>{% trans 'Delete selected' %}</option>
<option>{% trans 'Update selected' %}</option>
<option>{% trans 'Deactive selected' %}</option>
<option>{% trans 'Export selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Commit' %}
</button>
</div>
</div>
</form>
{% endblock %}

View File

@ -1,9 +1,9 @@
# coding:utf-8 # coding:utf-8
from django.conf.urls import url, include from django.conf.urls import url, include
import views
# from .api import ( # from .api import (
# AssetGroupViewSet, AssetViewSet, IDCViewSet # AssetGroupViewSet, AssetViewSet, IDCViewSet
# ) # )
import views
# from rest_framework import routers # from rest_framework import routers
# router = routers.DefaultRouter() # router = routers.DefaultRouter()
# router.register(r'assetgroup', AssetGroupViewSet) # router.register(r'assetgroup', AssetGroupViewSet)
@ -12,16 +12,16 @@ import views
app_name = 'assets' app_name = 'assets'
urlpatterns = [ urlpatterns = [
# url(r'^$', views.AssetListView.as_view(), name='asset-index'), url(r'^$', views.AssetListView.as_view(), name='asset-index'),
# url(r'^asset', views.AssetListView.as_view(), name='asset-list'), url(r'^asset$', views.AssetListView.as_view(), name='asset-list'),
url(r'^asset/add$', views.AssetAddView.as_view(), name='asset-add'), url(r'^asset/add$', views.AssetAddView.as_view(), name='asset-add'),
url(r'^asset/(?P<pk>[0-9]+)$', views.AssetDetailView.as_view(), name='asset-detail'), url(r'^asset/(?P<pk>[0-9]+)$', views.AssetDetailView.as_view(), name='asset-detail'),
url(r'^asset/(?P<pk>[0-9]+)$/edit', views.AssetEditView.as_view(), name='asset-edit'), url(r'^asset/(?P<pk>[0-9]+)$/edit', views.AssetEditView.as_view(), name='asset-edit'),
url(r'^asset/(?P<pk>[0-9]+)/delete$', views.AssetDeleteView.as_view(), name='asset-delete'), url(r'^asset/(?P<pk>[0-9]+)/delete$', views.AssetDeleteView.as_view(), name='asset-delete'),
url(r'^asset-group', views.AssetGroupListView.as_view(), name='asset-group-list'), url(r'^assetgroup$', views.AssetGroupListView.as_view(), name='assetgroup-list'),
url(r'^asset-group/add$', views.AssetGroupAddView.as_view(), name='asset-group-add'), url(r'^assetgroup/add$', views.AssetGroupAddView.as_view(), name='assetgroup-add'),
url(r'^asset-group/(?P<pk>[0-9]+)$', views.AssetDetailView.as_view(), name='asset-group-detail'), url(r'^assetgroup/(?P<pk>[0-9]+)$', views.AssetGroupDetailView.as_view(), name='assetgroup-detail'),
url(r'^asset-group/(?P<pk>[0-9]+)$/edit', views.AssetEditView.as_view(), name='asset-group-edit'), url(r'^assetgroup/(?P<pk>[0-9]+)$/edit', views.AssetGroupEditView.as_view(), name='assetgroup-edit'),
url(r'^asset-group/(?P<pk>[0-9]+)/delete$', views.AssetDeleteView.as_view(), name='asset-group-delete'), url(r'^assetgroup/(?P<pk>[0-9]+)/delete$', views.AssetGroupDeleteView.as_view(), name='assetgroup-delete'),
# url(r'^api/v1.0/', include(router.urls)), # url(r'^api/v1.0/', include(router.urls)),
] ]

View File

@ -1,6 +1,7 @@
# coding:utf-8 # coding:utf-8
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView, ListView from django.views.generic import TemplateView, ListView
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
@ -10,7 +11,7 @@ from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateVi
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from .models import Asset, AssetGroup, IDC, AssetExtend from .models import Asset, AssetGroup, IDC, AssetExtend
from .forms import AssetForm from .forms import AssetForm, AssetGroupForm
from .utils import AdminUserRequiredMixin from .utils import AdminUserRequiredMixin
@ -48,11 +49,32 @@ class AssetDetailView(DetailView):
class AssetGroupAddView(CreateView): class AssetGroupAddView(CreateView):
pass model = AssetGroup
form_class = AssetGroupForm
template_name = 'assets/assetgroup_add.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Create asset group'),
'assets': Asset.objects.all(),
}
kwargs.update(context)
return super(AssetGroupAddView, self).get_context_data(**kwargs)
class AssetGroupListView(ListView): class AssetGroupListView(ListView):
pass model = AssetGroup
context_object_name = 'assetgroups'
template_name = 'assets/assetgroup_list.html'
def get_context_data(self, **kwargs):
context = {
'app': _('Assets'),
'action': _('Asset group list')
}
kwargs.update(context)
return super(AssetGroupListView, self).get_context_data(**kwargs)
class AssetGroupDetailView(DetailView): class AssetGroupDetailView(DetailView):

View File

@ -215,7 +215,7 @@ LOGGING = {
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/1.10/topics/i18n/ # https://docs.djangoproject.com/en/1.10/topics/i18n/
LANGUAGE_CODE = 'zh_CN' LANGUAGE_CODE = 'en_US'
TIME_ZONE = 'Asia/Shanghai' TIME_ZONE = 'Asia/Shanghai'

View File

@ -18,8 +18,8 @@
<i class="fa fa-inbox"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span> <i class="fa fa-inbox"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class=""><a href="">{% trans 'Asset' %}</a></li> <li class="{% url 'assets:asset-list' %}"><a href="">{% trans 'Asset' %}</a></li>
<li class=""><a href="">{% trans 'Assetgroup' %}</a></li> <li class=""><a href="{% url 'assets:assetgroup-list' %}">{% trans 'Assetgroup' %}</a></li>
<li class=""><a href="">{% trans 'IDC' %}</a></li> <li class=""><a href="">{% trans 'IDC' %}</a></li>
<li class=""><a href="">{% trans 'Assetadmin' %}</a></li> <li class=""><a href="">{% trans 'Assetadmin' %}</a></li>
<li class=""><a href="">{% trans 'Assetuser' %}</a></li> <li class=""><a href="">{% trans 'Assetuser' %}</a></li>

View File

@ -168,10 +168,10 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
context_object_name = "user" context_object_name = "user"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserDetailView, self).get_context_data(**kwargs)
groups = [group for group in UserGroup.objects.iterator() if group not in self.object.groups.iterator()] groups = [group for group in UserGroup.objects.iterator() if group not in self.object.groups.iterator()]
context.update({'app': _('Users'), 'action': _('User detail'), 'groups': groups}) context = {'app': _('Users'), 'action': _('User detail'), 'groups': groups}
return context kwargs.update(context)
return super(UserDetailView, self).get_context_data(**kwargs)
class UserGroupListView(AdminUserRequiredMixin, ListView): class UserGroupListView(AdminUserRequiredMixin, ListView):

View File

@ -19,7 +19,7 @@ apps_dir = os.path.join(BASE_DIR, 'apps')
def start_django(): def start_django():
http_host = CONFIG.HTTP_LISTEN_HOST or 'locahost' http_host = CONFIG.HTTP_LISTEN_HOST or '127.0.0.1'
http_port = CONFIG.HTTP_LISTEN_PORT or '8080' http_port = CONFIG.HTTP_LISTEN_PORT or '8080'
os.chdir(apps_dir) os.chdir(apps_dir)
print('start django') print('start django')