mirror of https://github.com/jumpserver/jumpserver
merge cmdb
commit
bc232c4f77
|
@ -6,7 +6,6 @@ from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class AssetForm(forms.ModelForm):
|
class AssetForm(forms.ModelForm):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
|
|
||||||
|
@ -22,6 +21,25 @@ class AssetForm(forms.ModelForm):
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupForm(forms.ModelForm):
|
class AssetGroupForm(forms.ModelForm):
|
||||||
|
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
||||||
|
label=_('Asset'),
|
||||||
|
required=False,
|
||||||
|
widget=forms.SelectMultiple(
|
||||||
|
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if kwargs.get('instance'):
|
||||||
|
initial = kwargs.get('initial', {})
|
||||||
|
initial['assets'] = kwargs['instance'].assets.all()
|
||||||
|
super(AssetGroupForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def _save_m2m(self):
|
||||||
|
super(AssetGroupForm, self)._save_m2m()
|
||||||
|
assets = self.cleaned_data['assets']
|
||||||
|
self.instance.assets.clear()
|
||||||
|
self.instance.assets.add(*tuple(assets))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssetGroup
|
model = AssetGroup
|
||||||
fields = [
|
fields = [
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10 on 2016-09-04 11:52
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AdminUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=128, unique=True, verbose_name='Name')),
|
||||||
|
('username', models.CharField(max_length=16, verbose_name='Username')),
|
||||||
|
('password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')),
|
||||||
|
('private_key', models.CharField(blank=True, max_length=4096, null=True, verbose_name='SSH private key')),
|
||||||
|
('is_default', models.BooleanField(default=False, verbose_name='As default')),
|
||||||
|
('auto_update', models.BooleanField(default=True, verbose_name='Auto update pass/key')),
|
||||||
|
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
|
||||||
|
('create_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
|
||||||
|
('comment', models.TextField(blank=True, verbose_name='Comment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'adminuser',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Asset',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('ip', models.CharField(max_length=32, verbose_name='IP')),
|
||||||
|
('other_ip', models.CharField(blank=True, max_length=255, verbose_name='Other IP')),
|
||||||
|
('remote_card_ip', models.CharField(blank=True, max_length=16, verbose_name='Remote card IP')),
|
||||||
|
('hostname', models.CharField(blank=True, max_length=128, unique=True, verbose_name='Hostname')),
|
||||||
|
('port', models.IntegerField(default=22, verbose_name='Port')),
|
||||||
|
('username', models.CharField(blank=True, max_length=16, verbose_name='Admin user')),
|
||||||
|
('password', models.CharField(blank=True, max_length=256, verbose_name='Admin password')),
|
||||||
|
('mac_addr', models.CharField(blank=True, max_length=20, verbose_name='Mac address')),
|
||||||
|
('brand', models.CharField(blank=True, max_length=64, verbose_name='Brand')),
|
||||||
|
('cpu', models.CharField(blank=True, max_length=64, verbose_name='CPU')),
|
||||||
|
('memory', models.CharField(blank=True, max_length=128, verbose_name='Memory')),
|
||||||
|
('disk', models.CharField(blank=True, max_length=1024, verbose_name='Disk')),
|
||||||
|
('os', models.CharField(blank=True, max_length=128, verbose_name='OS')),
|
||||||
|
('cabinet_no', models.CharField(blank=True, max_length=32, verbose_name='Cabinet number')),
|
||||||
|
('cabinet_pos', models.IntegerField(blank=True, verbose_name='Cabinet position')),
|
||||||
|
('number', models.CharField(blank=True, max_length=32, unique=True, verbose_name='Asset number')),
|
||||||
|
('sn', models.CharField(blank=True, max_length=128, unique=True, verbose_name='Serial number')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
|
||||||
|
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
|
||||||
|
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
|
||||||
|
('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
|
||||||
|
('admin_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.AdminUser', verbose_name='Admin User')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'asset',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AssetExtend',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('key', models.CharField(max_length=64, verbose_name='KEY')),
|
||||||
|
('value', models.CharField(max_length=64, verbose_name='VALUE')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
|
||||||
|
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
|
||||||
|
('comment', models.TextField(blank=True, verbose_name='Comment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'assetextend',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AssetGroup',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=64, unique=True, verbose_name='Name')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
|
||||||
|
('comment', models.TextField(blank=True, null=True, verbose_name='Comment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'assetgroup',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='IDC',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=32, verbose_name='Name')),
|
||||||
|
('bandwidth', models.CharField(blank=True, max_length=32, verbose_name='Bandwidth')),
|
||||||
|
('contact', models.CharField(blank=True, max_length=16, verbose_name='Contact')),
|
||||||
|
('phone', models.CharField(blank=True, max_length=32, verbose_name='Phone')),
|
||||||
|
('address', models.CharField(blank=True, max_length=128, verbose_name='Address')),
|
||||||
|
('network', models.TextField(blank=True, verbose_name='Network')),
|
||||||
|
('date_added', models.DateField(auto_now=True, null=True, verbose_name='Date added')),
|
||||||
|
('operator', models.CharField(blank=True, max_length=32, verbose_name='Operator')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
|
||||||
|
('comment', models.TextField(blank=True, verbose_name='Comment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'idc',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Label',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('key', models.CharField(max_length=64, verbose_name='KEY')),
|
||||||
|
('value', models.CharField(max_length=64, verbose_name='VALUE')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
|
||||||
|
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
|
||||||
|
('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
|
||||||
|
('asset', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.Asset', verbose_name='Asset')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'label',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SysUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=128, verbose_name='Name')),
|
||||||
|
('username', models.CharField(max_length=16, verbose_name='Username')),
|
||||||
|
('password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')),
|
||||||
|
('protocol', models.CharField(default='ssh', max_length=16, verbose_name='Protocol')),
|
||||||
|
('private_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH private key')),
|
||||||
|
('public_key', models.CharField(blank=True, max_length=4096, verbose_name='SSH public key')),
|
||||||
|
('is_default', models.BooleanField(default=False, verbose_name='As default')),
|
||||||
|
('auto_push', models.BooleanField(default=True, verbose_name='Auto push')),
|
||||||
|
('auto_update', models.BooleanField(default=True, verbose_name='Auto update pass/key')),
|
||||||
|
('sudo', models.TextField(blank=True, max_length=4096, verbose_name='Sudo')),
|
||||||
|
('shell', models.CharField(blank=True, max_length=64, verbose_name='Shell')),
|
||||||
|
('home', models.CharField(blank=True, max_length=64, verbose_name='Home')),
|
||||||
|
('uid', models.IntegerField(blank=True, verbose_name='Uid')),
|
||||||
|
('date_added', models.DateTimeField(auto_now=True, null=True, verbose_name='Date added')),
|
||||||
|
('create_by', models.CharField(blank=True, max_length=32, verbose_name='Created by')),
|
||||||
|
('comment', models.CharField(blank=True, max_length=128, verbose_name='Comment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'sysuser',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='env',
|
||||||
|
field=models.ManyToManyField(related_name='asset_env_extend', to='assets.AssetExtend', verbose_name='Asset environment'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='groups',
|
||||||
|
field=models.ManyToManyField(to='assets.AssetGroup', verbose_name='Asset groups'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='idc',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.IDC', verbose_name='IDC'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='status',
|
||||||
|
field=models.ManyToManyField(related_name='asset_status_extend', to='assets.AssetExtend', verbose_name='Asset status'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='sys_user',
|
||||||
|
field=models.ManyToManyField(to='assets.SysUser', verbose_name='Sys User'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='type',
|
||||||
|
field=models.ManyToManyField(related_name='asset_type_extend', to='assets.AssetExtend', verbose_name='Asset type'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -14,7 +14,7 @@ class AssetGroup(models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'assetgroup'
|
db_table = 'asset_group'
|
||||||
|
|
||||||
|
|
||||||
class IDC(models.Model):
|
class IDC(models.Model):
|
||||||
|
@ -128,10 +128,14 @@ class Asset(models.Model):
|
||||||
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):
|
||||||
return self.ip
|
return '%(ip)s:%(port)d' % {'ip': self.ip, 'port': self.port}
|
||||||
|
|
||||||
|
def initial(self):
|
||||||
|
pass
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'asset'
|
db_table = 'asset'
|
||||||
|
index_together = ('ip', 'port')
|
||||||
|
|
||||||
|
|
||||||
class Label(models.Model):
|
class Label(models.Model):
|
||||||
|
|
|
@ -40,24 +40,9 @@
|
||||||
|
|
||||||
{{ form.port|bootstrap_horizontal }}
|
{{ form.port|bootstrap_horizontal }}
|
||||||
|
|
||||||
{# <div class="form-group" id="id_port">#}
|
|
||||||
{# <label class="col-sm-2 control-label">端口</label>#}
|
|
||||||
{# <div class="col-sm-9">#}
|
|
||||||
{# <input type="text" placeholder="" name="port" class="form-control">#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
|
|
||||||
{# <div class="form-group" id="id_type">#}
|
|
||||||
{# <label class="col-sm-2 control-label">资产类型</label>#}
|
|
||||||
{# <div class="col-sm-9">#}
|
|
||||||
{# <input type="text" placeholder="" name="type" class="form-control">#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
|
|
||||||
{{ form.type|bootstrap_horizontal }}
|
{{ form.type|bootstrap_horizontal }}
|
||||||
|
|
||||||
{{ form.comment|bootstrap_horizontal }}
|
{{ form.comment|bootstrap_horizontal }}
|
||||||
|
|
||||||
<div class="hr-line-dashed"></div>
|
<div class="hr-line-dashed"></div>
|
||||||
<h3>关联资产用户</h3>
|
<h3>关联资产用户</h3>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
|
@ -30,24 +30,25 @@
|
||||||
<form method="post" id="userForm" class="form-horizontal" action="" >
|
<form method="post" id="userForm" class="form-horizontal" action="" >
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.name|bootstrap_horizontal }}
|
{{ form.name|bootstrap_horizontal }}
|
||||||
|
{{ form.assets|bootstrap_horizontal }}
|
||||||
|
|
||||||
<div class="form-group">
|
{# <div class="form-group">#}
|
||||||
<label for="users" class="col-sm-2 control-label">{% trans 'Asset' %}</label>
|
{# <label for="users" class="col-sm-2 control-label">{% trans 'Asset' %}</label>#}
|
||||||
<div class="col-sm-9">
|
{# <div class="col-sm-9">#}
|
||||||
<select name="assets" id="assets" data-placeholder="{% trans 'Select asset' %}" class="select2 form-control m-b" multiple tabindex="2">
|
{# <select name="assets" id="assets" data-placeholder="{% trans 'Select asset' %}" class="select2 form-control m-b" multiple tabindex="2">#}
|
||||||
{% for asset in assets %}
|
{# {% for asset in assets %}#}
|
||||||
<option value="{{ asset.id }}">{{ asset.hostname }}</option>
|
{# <option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>#}
|
||||||
{% endfor %}
|
{# {% endfor %}#}
|
||||||
</select>
|
{# </select>#}
|
||||||
</div>
|
{# </div>#}
|
||||||
</div>
|
{# </div>#}
|
||||||
|
|
||||||
{{ form.comment|bootstrap_horizontal }}
|
{{ form.comment|bootstrap_horizontal }}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
<div class="col-sm-4 col-sm-offset-2">
|
||||||
<button class="btn btn-white" type="reset">取消</button>
|
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
||||||
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button>
|
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
|
@ -2,35 +2,35 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load common_tags %}
|
{% load common_tags %}
|
||||||
{% block content_left_head %}
|
{% block content_left_head %}
|
||||||
<a href="{% url 'assets:assetgroup-add' %}" class="btn btn-sm btn-primary "> {% trans "Create asset group" %} </a>
|
<a href="{% url 'assets:asset-group-create' %}" class="btn btn-sm btn-primary "> {% trans "Create asset group" %} </a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_head %}
|
{% block table_head %}
|
||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
|
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center"><a href="{% url 'assets:assetgroup-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
<th class="text-center"><a href="{% url 'assets:asset-group-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
||||||
<th class="text-center">{% trans 'Asset num' %}</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"><a href="{% url 'assets:asset-group-list' %}?sort=date_expired">{% trans 'Comment' %}</a></th>
|
||||||
<th class="text-center"></th>
|
<th class="text-center"></th>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_body %}
|
{% block table_body %}
|
||||||
{% for assetgroup in assetgroups %}
|
{% for asset_group in asset_group_list %}
|
||||||
<tr class="gradeX">
|
<tr class="gradeX">
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<input type="checkbox" name="checked" value="{{ user.id }}">
|
<input type="checkbox" name="checked" value="{{ asset_group.id }}">
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{% url 'assets:assetgroup-detail' pk=user.id %}">
|
<a href="{% url 'assets:asset-group-detail' pk=asset_group.id %}">
|
||||||
{{ assetgroup.name }}
|
{{ asset_group.name }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">{{ assetgroup.comment }}</td>
|
<td class="text-center">{{ asset_group.assets.count }}</td>
|
||||||
<td class="text-center">{{ assetgroup.comment }}</td>
|
<td class="text-center">{{ asset_group.comment }}</td>
|
||||||
<td class="text-center">
|
<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 'assets:asset-group-update' pk=asset_group.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>
|
<a href="{% url 'assets:asset-group-delete' pk=asset_group.id %}" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -48,12 +48,10 @@
|
||||||
|
|
||||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
<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">
|
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
|
||||||
{% trans 'Commit' %}
|
{% trans 'Submit' %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<form id="asset_form">
|
<form id="asset_form">
|
||||||
<div class="col-sm-1" style="padding-left: 0">
|
<div class="col-sm-1" style="padding-left: 0">
|
||||||
<a href="{% url 'assets:asset-add' %}" class="btn btn-sm btn-primary "> 添加资产 </a>
|
<a href="{% url 'assets:asset-create' %}" class="btn btn-sm btn-primary "> {% trans 'Create asset' %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-7" style="padding-left: 0px">
|
<div class="col-sm-7" style="padding-left: 0px">
|
||||||
|
|
|
@ -14,14 +14,14 @@ 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/create$', views.AssetCreateView.as_view(), name='asset-create'),
|
||||||
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]+)$/update', views.AssetUpdateView.as_view(), name='asset-update'),
|
||||||
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'^assetgroup$', views.AssetGroupListView.as_view(), name='assetgroup-list'),
|
url(r'^asset-group$', views.AssetGroupListView.as_view(), name='asset-group-list'),
|
||||||
url(r'^assetgroup/add$', views.AssetGroupAddView.as_view(), name='assetgroup-add'),
|
url(r'^asset-group/create$', views.AssetGroupCreateView.as_view(), name='asset-group-create'),
|
||||||
url(r'^assetgroup/(?P<pk>[0-9]+)$', views.AssetGroupDetailView.as_view(), name='assetgroup-detail'),
|
url(r'^asset-group/(?P<pk>[0-9]+)$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'),
|
||||||
url(r'^assetgroup/(?P<pk>[0-9]+)$/edit', views.AssetGroupEditView.as_view(), name='assetgroup-edit'),
|
url(r'^asset-group/(?P<pk>[0-9]+)/update$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'),
|
||||||
url(r'^assetgroup/(?P<pk>[0-9]+)/delete$', views.AssetGroupDeleteView.as_view(), name='assetgroup-delete'),
|
url(r'^asset-group/(?P<pk>[0-9]+)/delete$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'),
|
||||||
# url(r'^api/v1.0/', include(router.urls)),
|
# url(r'^api/v1.0/', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,32 +2,32 @@
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
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
|
||||||
|
|
||||||
from django.views.generic import TemplateView, ListView
|
from django.views.generic import TemplateView, ListView
|
||||||
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
||||||
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, AssetGroupForm
|
from .forms import AssetForm, AssetGroupForm
|
||||||
|
|
||||||
from .utils import AdminUserRequiredMixin
|
from .utils import AdminUserRequiredMixin
|
||||||
|
|
||||||
|
|
||||||
class AssetAddView(CreateView):
|
class AssetCreateView(CreateView):
|
||||||
model = Asset
|
model = Asset
|
||||||
form_class = AssetForm
|
form_class = AssetForm
|
||||||
template_name = 'assets/asset_add.html'
|
template_name = 'assets/asset_create.html'
|
||||||
success_url = reverse_lazy('assets:asset-list')
|
success_url = reverse_lazy('assets:asset-list')
|
||||||
|
|
||||||
def form_invalid(self, form):
|
def form_invalid(self, form):
|
||||||
print(form.errors)
|
print(form.errors)
|
||||||
return super(AssetAddView, self).form_invalid(form)
|
return super(AssetCreateView, self).form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
class AssetEditView(UpdateView):
|
class AssetUpdateView(UpdateView):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,10 +48,11 @@ class AssetDetailView(DetailView):
|
||||||
template_name = 'assets/asset_detail.html'
|
template_name = 'assets/asset_detail.html'
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupAddView(CreateView):
|
class AssetGroupCreateView(CreateView):
|
||||||
model = AssetGroup
|
model = AssetGroup
|
||||||
form_class = AssetGroupForm
|
form_class = AssetGroupForm
|
||||||
template_name = 'assets/assetgroup_add.html'
|
template_name = 'assets/asset_group_create.html'
|
||||||
|
success_url = reverse_lazy('assets:asset-group-list')
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
|
@ -60,13 +61,17 @@ class AssetGroupAddView(CreateView):
|
||||||
'assets': Asset.objects.all(),
|
'assets': Asset.objects.all(),
|
||||||
}
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
return super(AssetGroupAddView, self).get_context_data(**kwargs)
|
return super(AssetGroupCreateView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
print(form.data)
|
||||||
|
return super(AssetGroupCreateView, self).form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupListView(ListView):
|
class AssetGroupListView(ListView):
|
||||||
model = AssetGroup
|
model = AssetGroup
|
||||||
context_object_name = 'assetgroups'
|
context_object_name = 'asset_group_list'
|
||||||
template_name = 'assets/assetgroup_list.html'
|
template_name = 'assets/asset_group_list.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
|
@ -81,8 +86,20 @@ class AssetGroupDetailView(DetailView):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupEditView(UpdateView):
|
class AssetGroupUpdateView(UpdateView):
|
||||||
pass
|
model = AssetGroup
|
||||||
|
form_class = AssetGroupForm
|
||||||
|
template_name = 'assets/asset_group_create.html'
|
||||||
|
success_url = reverse_lazy('assets:asset-group-list')
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = {
|
||||||
|
'app': _('Assets'),
|
||||||
|
'action': _('Create asset group'),
|
||||||
|
'assets': Asset.objects.all(),
|
||||||
|
}
|
||||||
|
kwargs.update(context)
|
||||||
|
return super(AssetGroupUpdateView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupDeleteView(DeleteView):
|
class AssetGroupDeleteView(DeleteView):
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
||||||
[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-02T14:32:32Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$QU8p6Y6ep8VP$Zhrgn0Issfc8ozrNSdSGmyb3X7lRAbc3EEWdc2RTj/M=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-02T14:32:32Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-16T14:32:32Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
|
[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
|
|
@ -1 +1 @@
|
||||||
[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-08-24T08:24:34.436Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$MC3vobX7pa0C$l9qIj4UwHqODnj1hMvVy9DjLxbBumZaioQWIFrWQR7c=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-08-24T08:24:34.438Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "date_expired": "2086-08-07T08:24:34.438Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
|
[{"model": "users.usergroup", "pk": 1, "fields": {"name": "Default", "comment": "Default user group for all user", "date_added": "2016-09-05T11:39:25.770Z", "created_by": "System"}}, {"model": "users.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$30000$5ReHkQOQA2Hk$DIW0b5U/uK+U0xqjA3QpYvBcODNhm2MPCm7YWbQys3I=", "last_login": null, "first_name": "", "last_name": "", "is_active": true, "date_joined": "2016-09-05T11:39:25.771Z", "username": "admin", "name": "Administrator", "email": "admin@jumpserver.org", "role": "Admin", "avatar": "", "wechat": "", "phone": "", "enable_otp": false, "secret_key_otp": "", "private_key": "", "public_key": "", "comment": "Administrator is the super user of system", "is_first_login": false, "date_expired": "2086-08-19T11:39:25.771Z", "created_by": "System", "user_permissions": [], "groups": [1]}}]
|
File diff suppressed because one or more lines are too long
|
@ -75,12 +75,12 @@ INSTALLED_APPS = [
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'jumpserver.urls'
|
ROOT_URLCONF = 'jumpserver.urls'
|
||||||
|
@ -92,6 +92,7 @@ TEMPLATES = [
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
|
'django.template.context_processors.i18n',
|
||||||
'django.template.context_processors.debug',
|
'django.template.context_processors.debug',
|
||||||
'django.template.context_processors.request',
|
'django.template.context_processors.request',
|
||||||
'django.contrib.auth.context_processors.auth',
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
@ -215,7 +216,7 @@ LOGGING = {
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en_US'
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
TIME_ZONE = 'Asia/Shanghai'
|
TIME_ZONE = 'Asia/Shanghai'
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,704 @@
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Jumpserver 0.3.3\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2016-09-05 20:18+0800\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
|
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
|
||||||
|
"Language: zh_CN\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: assets/forms.py:20
|
||||||
|
msgid "Join assetgroups"
|
||||||
|
msgstr "添加到用户组"
|
||||||
|
|
||||||
|
#: assets/models.py:9 assets/models.py:21 assets/models.py:54
|
||||||
|
#: assets/models.py:76 assets/templates/assets/assetgroup_list.html:12
|
||||||
|
#: users/models.py:60 users/models.py:107
|
||||||
|
#: users/templates/users/user_detail.html:69
|
||||||
|
#: users/templates/users/user_list.html:12
|
||||||
|
msgid "Name"
|
||||||
|
msgstr "名称"
|
||||||
|
|
||||||
|
#: assets/models.py:10 assets/models.py:29 assets/models.py:42
|
||||||
|
#: assets/models.py:61 assets/models.py:90 assets/models.py:125
|
||||||
|
#: assets/models.py:145 users/models.py:122
|
||||||
|
#: users/templates/users/user_detail.html:101
|
||||||
|
msgid "Created by"
|
||||||
|
msgstr "创建者"
|
||||||
|
|
||||||
|
#: assets/models.py:11 assets/models.py:30 assets/models.py:44
|
||||||
|
#: assets/models.py:62 assets/models.py:91 assets/models.py:128
|
||||||
|
#: assets/models.py:147 assets/templates/assets/assetgroup_list.html:14
|
||||||
|
#: users/models.py:61 users/models.py:118
|
||||||
|
#: users/templates/users/user_detail.html:113
|
||||||
|
msgid "Comment"
|
||||||
|
msgstr "备注"
|
||||||
|
|
||||||
|
#: assets/models.py:22
|
||||||
|
msgid "Bandwidth"
|
||||||
|
msgstr "带宽"
|
||||||
|
|
||||||
|
#: assets/models.py:23
|
||||||
|
msgid "Contact"
|
||||||
|
msgstr "联系人"
|
||||||
|
|
||||||
|
#: assets/models.py:24 users/models.py:113
|
||||||
|
#: users/templates/users/user_detail.html:82
|
||||||
|
msgid "Phone"
|
||||||
|
msgstr "手机"
|
||||||
|
|
||||||
|
#: assets/models.py:25
|
||||||
|
msgid "Address"
|
||||||
|
msgstr "地址"
|
||||||
|
|
||||||
|
#: assets/models.py:26
|
||||||
|
msgid "Network"
|
||||||
|
msgstr "网络"
|
||||||
|
|
||||||
|
#: assets/models.py:27 assets/models.py:127
|
||||||
|
msgid "Date added"
|
||||||
|
msgstr "加入日期"
|
||||||
|
|
||||||
|
#: assets/models.py:28
|
||||||
|
msgid "Operator"
|
||||||
|
msgstr "运营商"
|
||||||
|
|
||||||
|
#: assets/models.py:40 assets/models.py:142
|
||||||
|
msgid "KEY"
|
||||||
|
msgstr "KEY"
|
||||||
|
|
||||||
|
#: assets/models.py:41 assets/models.py:143
|
||||||
|
msgid "VALUE"
|
||||||
|
msgstr "VALUE"
|
||||||
|
|
||||||
|
#: assets/models.py:55 assets/models.py:77 users/forms.py:12
|
||||||
|
#: users/models.py:106 users/templates/users/login.html:54
|
||||||
|
#: users/templates/users/user_detail.html:73
|
||||||
|
#: users/templates/users/user_edit.html:5
|
||||||
|
#: users/templates/users/user_list.html:13
|
||||||
|
msgid "Username"
|
||||||
|
msgstr "用户名"
|
||||||
|
|
||||||
|
#: assets/models.py:56 assets/models.py:78 users/forms.py:13
|
||||||
|
#: users/templates/users/login.html:57
|
||||||
|
#: users/templates/users/reset_password.html:52
|
||||||
|
#: users/templates/users/user_add.html:8 users/templates/users/user_add.html:10
|
||||||
|
#: users/templates/users/user_edit.html:12
|
||||||
|
#: users/templates/users/user_edit.html:14
|
||||||
|
msgid "Password"
|
||||||
|
msgstr "密码"
|
||||||
|
|
||||||
|
#: assets/models.py:57 assets/models.py:80
|
||||||
|
msgid "SSH private key"
|
||||||
|
msgstr "ssh密钥"
|
||||||
|
|
||||||
|
#: assets/models.py:58 assets/models.py:82
|
||||||
|
msgid "As default"
|
||||||
|
msgstr "默认使用"
|
||||||
|
|
||||||
|
#: assets/models.py:59 assets/models.py:84
|
||||||
|
msgid "Auto update pass/key"
|
||||||
|
msgstr "自动更新密码/密钥"
|
||||||
|
|
||||||
|
#: assets/models.py:79
|
||||||
|
msgid "Protocol"
|
||||||
|
msgstr "协议"
|
||||||
|
|
||||||
|
#: assets/models.py:81
|
||||||
|
msgid "SSH public key"
|
||||||
|
msgstr "ssh公钥"
|
||||||
|
|
||||||
|
#: assets/models.py:83
|
||||||
|
msgid "Auto push"
|
||||||
|
msgstr "自动推送"
|
||||||
|
|
||||||
|
#: assets/models.py:85
|
||||||
|
msgid "Sudo"
|
||||||
|
msgstr "Sudo"
|
||||||
|
|
||||||
|
#: assets/models.py:86
|
||||||
|
msgid "Shell"
|
||||||
|
msgstr "Shell"
|
||||||
|
|
||||||
|
#: assets/models.py:87 templates/_header_bar.html:35 templates/_nav.html:4
|
||||||
|
msgid "Home"
|
||||||
|
msgstr "仪表盘"
|
||||||
|
|
||||||
|
#: assets/models.py:88
|
||||||
|
msgid "Uid"
|
||||||
|
msgstr "Uid"
|
||||||
|
|
||||||
|
#: assets/models.py:101
|
||||||
|
msgid "IP"
|
||||||
|
msgstr "IP"
|
||||||
|
|
||||||
|
#: assets/models.py:102
|
||||||
|
msgid "Other IP"
|
||||||
|
msgstr "其它IP"
|
||||||
|
|
||||||
|
#: assets/models.py:103
|
||||||
|
msgid "Remote card IP"
|
||||||
|
msgstr "远控卡IP"
|
||||||
|
|
||||||
|
#: assets/models.py:104
|
||||||
|
msgid "Hostname"
|
||||||
|
msgstr "用户名"
|
||||||
|
|
||||||
|
#: assets/models.py:105
|
||||||
|
msgid "Port"
|
||||||
|
msgstr "端口"
|
||||||
|
|
||||||
|
#: assets/models.py:106
|
||||||
|
msgid "Asset groups"
|
||||||
|
msgstr "用户组"
|
||||||
|
|
||||||
|
#: assets/models.py:107 assets/models.py:109 templates/_nav.html:24
|
||||||
|
msgid "Admin user"
|
||||||
|
msgstr "管理用户"
|
||||||
|
|
||||||
|
#: assets/models.py:108
|
||||||
|
msgid "Admin password"
|
||||||
|
msgstr "管理员密码"
|
||||||
|
|
||||||
|
#: assets/models.py:111 templates/_nav.html:23
|
||||||
|
msgid "IDC"
|
||||||
|
msgstr "机房"
|
||||||
|
|
||||||
|
#: assets/models.py:112
|
||||||
|
msgid "Mac address"
|
||||||
|
msgstr "Mac地址"
|
||||||
|
|
||||||
|
#: assets/models.py:113
|
||||||
|
msgid "Brand"
|
||||||
|
msgstr "品牌"
|
||||||
|
|
||||||
|
#: assets/models.py:114
|
||||||
|
msgid "CPU"
|
||||||
|
msgstr "CPU"
|
||||||
|
|
||||||
|
#: assets/models.py:115
|
||||||
|
msgid "Memory"
|
||||||
|
msgstr "内存"
|
||||||
|
|
||||||
|
#: assets/models.py:116
|
||||||
|
msgid "Disk"
|
||||||
|
msgstr "硬盘"
|
||||||
|
|
||||||
|
#: assets/models.py:117
|
||||||
|
msgid "OS"
|
||||||
|
msgstr "操作系统"
|
||||||
|
|
||||||
|
#: assets/models.py:118
|
||||||
|
msgid "Cabinet number"
|
||||||
|
msgstr "机柜编号"
|
||||||
|
|
||||||
|
#: assets/models.py:119
|
||||||
|
msgid "Cabinet position"
|
||||||
|
msgstr "机柜层号"
|
||||||
|
|
||||||
|
#: assets/models.py:120
|
||||||
|
msgid "Asset number"
|
||||||
|
msgstr "资产编号"
|
||||||
|
|
||||||
|
#: assets/models.py:121
|
||||||
|
msgid "Asset status"
|
||||||
|
msgstr "资产状态"
|
||||||
|
|
||||||
|
#: assets/models.py:122
|
||||||
|
msgid "Asset type"
|
||||||
|
msgstr "系统类型"
|
||||||
|
|
||||||
|
#: assets/models.py:123
|
||||||
|
msgid "Asset environment"
|
||||||
|
msgstr "资产环境"
|
||||||
|
|
||||||
|
#: assets/models.py:124
|
||||||
|
msgid "Serial number"
|
||||||
|
msgstr "序列号"
|
||||||
|
|
||||||
|
#: assets/models.py:126
|
||||||
|
msgid "Is active"
|
||||||
|
msgstr "是否激活"
|
||||||
|
|
||||||
|
#: assets/models.py:144 assets/templates/assets/assetgroup_add.html:35
|
||||||
|
#: templates/_nav.html:21
|
||||||
|
msgid "Asset"
|
||||||
|
msgstr "资产"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_add.html:16
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:5 assets/views.py:60
|
||||||
|
msgid "Create asset group"
|
||||||
|
msgstr "创建资产组"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_add.html:37
|
||||||
|
msgid "Select asset"
|
||||||
|
msgstr "选择资产"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_add.html:49
|
||||||
|
#: users/templates/users/_user.html:70
|
||||||
|
#: users/templates/users/user_detail.html:162
|
||||||
|
#: users/templates/users/user_detail.html:170
|
||||||
|
msgid "Reset"
|
||||||
|
msgstr "重置"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_add.html:50
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:51
|
||||||
|
#: users/templates/users/_user.html:71
|
||||||
|
#: users/templates/users/forget_password.html:44
|
||||||
|
#: users/templates/users/user_list.html:63
|
||||||
|
msgid "Submit"
|
||||||
|
msgstr "提交"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:13
|
||||||
|
#: users/templates/users/user_list.html:16
|
||||||
|
msgid "Asset num"
|
||||||
|
msgstr "资产数量"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:32
|
||||||
|
#: users/templates/users/user_list.html:44
|
||||||
|
msgid "Edit"
|
||||||
|
msgstr "编辑"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:33
|
||||||
|
#: users/templates/users/user_list.html:45
|
||||||
|
msgid "Delete"
|
||||||
|
msgstr "删除"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:43
|
||||||
|
#: users/templates/users/user_list.html:55
|
||||||
|
msgid "Delete selected"
|
||||||
|
msgstr "批量删除"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:44
|
||||||
|
#: users/templates/users/user_list.html:56
|
||||||
|
msgid "Update selected"
|
||||||
|
msgstr "批量更新"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:45
|
||||||
|
#: users/templates/users/user_list.html:57
|
||||||
|
msgid "Deactive selected"
|
||||||
|
msgstr "禁用所选"
|
||||||
|
|
||||||
|
#: assets/templates/assets/assetgroup_list.html:46
|
||||||
|
#: users/templates/users/user_list.html:58
|
||||||
|
msgid "Export selected"
|
||||||
|
msgstr "批量导出"
|
||||||
|
|
||||||
|
#: assets/views.py:59 assets/views.py:74 templates/_nav.html:18
|
||||||
|
msgid "Assets"
|
||||||
|
msgstr "资产管理"
|
||||||
|
|
||||||
|
#: assets/views.py:75
|
||||||
|
msgid "Asset group list"
|
||||||
|
msgstr "资产组列表"
|
||||||
|
|
||||||
|
#: templates/_header_bar.html:8 users/templates/users/user_detail.html:29
|
||||||
|
msgid "Search"
|
||||||
|
msgstr "搜索"
|
||||||
|
|
||||||
|
#: templates/_header_bar.html:14
|
||||||
|
msgid "Welcome to use Jumpserver system"
|
||||||
|
msgstr "欢迎使用Jumpserver开源跳板机系统"
|
||||||
|
|
||||||
|
#: templates/_header_bar.html:18
|
||||||
|
msgid "Help"
|
||||||
|
msgstr "帮助"
|
||||||
|
|
||||||
|
#: templates/_nav.html:9 users/views.py:100 users/views.py:113
|
||||||
|
#: users/views.py:153 users/views.py:170 users/views.py:195 users/views.py:208
|
||||||
|
msgid "Users"
|
||||||
|
msgstr "用户管理"
|
||||||
|
|
||||||
|
#: templates/_nav.html:12 users/models.py:103
|
||||||
|
msgid "User"
|
||||||
|
msgstr "用户"
|
||||||
|
|
||||||
|
#: templates/_nav.html:13
|
||||||
|
msgid "User group"
|
||||||
|
msgstr "用户组"
|
||||||
|
|
||||||
|
#: templates/_nav.html:22
|
||||||
|
msgid "Asset group"
|
||||||
|
msgstr "资产组"
|
||||||
|
|
||||||
|
#: templates/_nav.html:25
|
||||||
|
msgid "System user"
|
||||||
|
msgstr "系统"
|
||||||
|
|
||||||
|
#: templates/_nav.html:26
|
||||||
|
msgid "Label"
|
||||||
|
msgstr "标签"
|
||||||
|
|
||||||
|
#: templates/_nav.html:30
|
||||||
|
msgid "Perms"
|
||||||
|
msgstr "权限管理"
|
||||||
|
|
||||||
|
#: templates/_nav.html:33
|
||||||
|
msgid "Perm"
|
||||||
|
msgstr "权限"
|
||||||
|
|
||||||
|
#: templates/_nav.html:36
|
||||||
|
msgid "Create perm"
|
||||||
|
msgstr "创建权限"
|
||||||
|
|
||||||
|
#: templates/_nav.html:42
|
||||||
|
msgid "Audits"
|
||||||
|
msgstr "审计"
|
||||||
|
|
||||||
|
#: templates/_nav.html:47
|
||||||
|
msgid "File"
|
||||||
|
msgstr "文件"
|
||||||
|
|
||||||
|
#: templates/_nav.html:50
|
||||||
|
msgid "File upload"
|
||||||
|
msgstr "文件上传"
|
||||||
|
|
||||||
|
#: templates/_nav.html:51
|
||||||
|
msgid "File download"
|
||||||
|
msgstr "文件下载"
|
||||||
|
|
||||||
|
#: templates/_nav.html:56
|
||||||
|
msgid "Settings"
|
||||||
|
msgstr "设置"
|
||||||
|
|
||||||
|
#: templates/_nav.html:61
|
||||||
|
msgid "Visit us"
|
||||||
|
msgstr "访问官网"
|
||||||
|
|
||||||
|
#: templates/_user_profile.html:19 users/templates/users/_user.html:63
|
||||||
|
msgid "Profile"
|
||||||
|
msgstr "个人信息"
|
||||||
|
|
||||||
|
#: templates/_user_profile.html:21
|
||||||
|
msgid "Logout"
|
||||||
|
msgstr "注销登录"
|
||||||
|
|
||||||
|
#: templates/captcha/image.html:3
|
||||||
|
msgid "Play CAPTCHA as audio file"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/captcha/text_field.html:4
|
||||||
|
msgid "Captcha"
|
||||||
|
msgstr "验证码"
|
||||||
|
|
||||||
|
#: users/forms.py:31 users/forms.py:50
|
||||||
|
msgid "Join user groups"
|
||||||
|
msgstr "添加到用户组"
|
||||||
|
|
||||||
|
#: users/models.py:102 users/models.py:225
|
||||||
|
msgid "Administrator"
|
||||||
|
msgstr "管理员"
|
||||||
|
|
||||||
|
#: users/models.py:108 users/templates/users/user_detail.html:77
|
||||||
|
msgid "Email"
|
||||||
|
msgstr "邮件"
|
||||||
|
|
||||||
|
#: users/models.py:109 users/templates/users/user_detail.html:181
|
||||||
|
#: users/templates/users/user_list.html:15
|
||||||
|
msgid "Usergroup"
|
||||||
|
msgstr "用户组"
|
||||||
|
|
||||||
|
#: users/models.py:110 users/templates/users/user_detail.html:93
|
||||||
|
#: users/templates/users/user_list.html:14
|
||||||
|
msgid "Role"
|
||||||
|
msgstr "角色"
|
||||||
|
|
||||||
|
#: users/models.py:111
|
||||||
|
msgid "Avatar"
|
||||||
|
msgstr "头像"
|
||||||
|
|
||||||
|
#: users/models.py:112 users/templates/users/user_detail.html:88
|
||||||
|
msgid "Wechat"
|
||||||
|
msgstr "微信"
|
||||||
|
|
||||||
|
#: users/models.py:114 users/templates/users/_user.html:57
|
||||||
|
msgid "Enable OTP"
|
||||||
|
msgstr "二次验证"
|
||||||
|
|
||||||
|
#: users/models.py:116
|
||||||
|
msgid "ssh private key"
|
||||||
|
msgstr "ssh密钥"
|
||||||
|
|
||||||
|
#: users/models.py:117
|
||||||
|
msgid "ssh public key"
|
||||||
|
msgstr "ssh公钥"
|
||||||
|
|
||||||
|
#: users/models.py:121 users/templates/users/user_detail.html:97
|
||||||
|
msgid "Date expired"
|
||||||
|
msgstr "失效日期"
|
||||||
|
|
||||||
|
#: users/models.py:228
|
||||||
|
msgid "Administrator is the super user of system"
|
||||||
|
msgstr "Administrator是初始的超级管理员"
|
||||||
|
|
||||||
|
#: users/models.py:229
|
||||||
|
msgid "System"
|
||||||
|
msgstr "系统"
|
||||||
|
|
||||||
|
#: users/templates/users/_user.html:17 users/templates/users/user_list.html:5
|
||||||
|
#: users/views.py:113
|
||||||
|
msgid "Create user"
|
||||||
|
msgstr "创建用户"
|
||||||
|
|
||||||
|
#: users/templates/users/_user.html:33
|
||||||
|
msgid "Account"
|
||||||
|
msgstr "账户"
|
||||||
|
|
||||||
|
#: users/templates/users/_user.html:43
|
||||||
|
msgid "Security and Role"
|
||||||
|
msgstr "角色安全"
|
||||||
|
|
||||||
|
#: users/templates/users/forget_password.html:26
|
||||||
|
msgid "Forget password"
|
||||||
|
msgstr "忘记密码"
|
||||||
|
|
||||||
|
#: users/templates/users/forget_password.html:33
|
||||||
|
msgid "Input your email, that will send a mail to your"
|
||||||
|
msgstr "输入您的邮箱, 将会发一封重置短信邮件到您的邮箱中"
|
||||||
|
|
||||||
|
#: users/templates/users/login.html:42 users/templates/users/login.html:62
|
||||||
|
msgid "Login"
|
||||||
|
msgstr "登录"
|
||||||
|
|
||||||
|
#: users/templates/users/login.html:47
|
||||||
|
msgid "Captcha invalid"
|
||||||
|
msgstr "验证码错误"
|
||||||
|
|
||||||
|
#: users/templates/users/reset_password.html:45
|
||||||
|
#: users/templates/users/user_detail.html:159 users/utils.py:98
|
||||||
|
msgid "Reset password"
|
||||||
|
msgstr "重置密码"
|
||||||
|
|
||||||
|
#: users/templates/users/reset_password.html:55
|
||||||
|
msgid "Password again"
|
||||||
|
msgstr "再次输入密码"
|
||||||
|
|
||||||
|
#: users/templates/users/reset_password.html:57
|
||||||
|
msgid "Setting"
|
||||||
|
msgstr "设置"
|
||||||
|
|
||||||
|
#: users/templates/users/user_add.html:12
|
||||||
|
msgid "Reset link will be generated and sent to the user. "
|
||||||
|
msgstr "生成重置密码连接,通过邮件发送给用户"
|
||||||
|
|
||||||
|
#: users/templates/users/user_delete_confirm.html:6
|
||||||
|
msgid "Confirm delete"
|
||||||
|
msgstr "确认删除"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:18 users/views.py:170
|
||||||
|
msgid "User detail"
|
||||||
|
msgstr "用户详情"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:20
|
||||||
|
msgid "User assets"
|
||||||
|
msgstr "用户资产"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:21
|
||||||
|
msgid "User log"
|
||||||
|
msgstr "登录日志"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:105
|
||||||
|
msgid "Date joined"
|
||||||
|
msgstr "创建日期"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:109
|
||||||
|
msgid "Last login"
|
||||||
|
msgstr "最后登录"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:124
|
||||||
|
msgid "Quick modify"
|
||||||
|
msgstr "快速修改"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:167
|
||||||
|
msgid "Reset ssh key"
|
||||||
|
msgstr "重置密钥"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:189
|
||||||
|
msgid "Select usergroups"
|
||||||
|
msgstr "选择用户组"
|
||||||
|
|
||||||
|
#: users/templates/users/user_detail.html:198
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "添加"
|
||||||
|
|
||||||
|
#: users/templates/users/user_list.html:17
|
||||||
|
msgid "Active"
|
||||||
|
msgstr "激活"
|
||||||
|
|
||||||
|
#: users/utils.py:47
|
||||||
|
msgid "Begin to generate ssh private key ..."
|
||||||
|
msgstr "开始生成ssh密钥"
|
||||||
|
|
||||||
|
#: users/utils.py:59
|
||||||
|
msgid "Finish to generate ssh private key ..."
|
||||||
|
msgstr "生成ssh密钥成功"
|
||||||
|
|
||||||
|
#: users/utils.py:63
|
||||||
|
msgid "These is error when generate ssh key."
|
||||||
|
msgstr "创建密钥失败"
|
||||||
|
|
||||||
|
#: users/utils.py:67
|
||||||
|
msgid "Create account successfully"
|
||||||
|
msgstr "创建账户成功"
|
||||||
|
|
||||||
|
#: users/utils.py:69
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" Hello %(name)s:\n"
|
||||||
|
" </br>\n"
|
||||||
|
" Your account has been created successfully\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">click "
|
||||||
|
"here to set your password</a>\n"
|
||||||
|
" </br>\n"
|
||||||
|
" This link is valid for 1 hour. After it expires, <a href="
|
||||||
|
"\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" ---\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(login_url)s\">Login direct</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" 你好 %(name)s:\n"
|
||||||
|
" </br>\n"
|
||||||
|
" 恭喜您,您的账号已经创建成功 </br>\n"
|
||||||
|
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击这"
|
||||||
|
"里设置密码</a> </br>\n"
|
||||||
|
" 这个链接有效期1小时, 超过时间您可以 <a href=\"%(forget_password_url)s?"
|
||||||
|
"email=%(email)s\">重新申请</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" ---\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(login_url)s\">Login direct</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
#: users/utils.py:100
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"\n"
|
||||||
|
" Hello %(name)s:\n"
|
||||||
|
" </br>\n"
|
||||||
|
" Please click the link below to reset your password, if not your request, "
|
||||||
|
"concern your account security\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
|
||||||
|
"here reset password</a>\n"
|
||||||
|
" </br>\n"
|
||||||
|
" This link is valid for 1 hour. After it expires, <a href="
|
||||||
|
"\"%(forget_password_url)s?email=%(email)s\">request new one<</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" ---\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(login_url)s\">Login direct</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" "
|
||||||
|
msgstr ""
|
||||||
|
"\n"
|
||||||
|
" 您好 %(name)s:\n"
|
||||||
|
" </br>\n"
|
||||||
|
" 请点击下面链接重置密码, 如果不是您申请的,请关注账号安全\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击这"
|
||||||
|
"里设置密码 /a>\n"
|
||||||
|
" </br>\n"
|
||||||
|
" 这个链接有效期1小时, 超过时间您可以<a href=\"%(forget_password_url)s?"
|
||||||
|
"email=%(email)s\">重新申请</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" ---\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" <a href=\"%(login_url)s\">直接登录</a>\n"
|
||||||
|
"\n"
|
||||||
|
" </br>\n"
|
||||||
|
" "
|
||||||
|
|
||||||
|
#: users/views.py:53
|
||||||
|
msgid "Username or password invalid"
|
||||||
|
msgstr "用户名或密码错误"
|
||||||
|
|
||||||
|
#: users/views.py:70
|
||||||
|
msgid "Logout success"
|
||||||
|
msgstr "退出登录成功"
|
||||||
|
|
||||||
|
#: users/views.py:71
|
||||||
|
msgid "Logout success, return login page"
|
||||||
|
msgstr "退出登录成功,返回到登录页面"
|
||||||
|
|
||||||
|
#: users/views.py:100
|
||||||
|
msgid "User list"
|
||||||
|
msgstr "用户列表"
|
||||||
|
|
||||||
|
#: users/views.py:109
|
||||||
|
#, python-format
|
||||||
|
msgid "Create user<a href=\"%s\">%s</a> success."
|
||||||
|
msgstr "创建用户<a href=\"%s\">%s</a> 成功"
|
||||||
|
|
||||||
|
#: users/views.py:153
|
||||||
|
msgid "Edit user"
|
||||||
|
msgstr "编辑用户"
|
||||||
|
|
||||||
|
#: users/views.py:195
|
||||||
|
msgid "Usergroup list"
|
||||||
|
msgstr "用户组列表"
|
||||||
|
|
||||||
|
#: users/views.py:208
|
||||||
|
msgid "Create usergroup"
|
||||||
|
msgstr "创建用户组"
|
||||||
|
|
||||||
|
#: users/views.py:240
|
||||||
|
msgid "Email address invalid, input again"
|
||||||
|
msgstr "邮箱地址错误,重新输入"
|
||||||
|
|
||||||
|
#: users/views.py:251
|
||||||
|
msgid "Send reset password message"
|
||||||
|
msgstr "发送重置密码邮件"
|
||||||
|
|
||||||
|
#: users/views.py:252
|
||||||
|
msgid "Send reset password mail success, login your mail box and follow it "
|
||||||
|
msgstr ""
|
||||||
|
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
|
||||||
|
|
||||||
|
#: users/views.py:264
|
||||||
|
msgid "Reset password success"
|
||||||
|
msgstr "重置密码成功"
|
||||||
|
|
||||||
|
#: users/views.py:265
|
||||||
|
msgid "Reset password success, return to login page"
|
||||||
|
msgstr "重置密码成功,返回到登录页面"
|
||||||
|
|
||||||
|
#: users/views.py:281 users/views.py:294
|
||||||
|
msgid "Token invalid or expired"
|
||||||
|
msgstr "Token错误或失效"
|
||||||
|
|
||||||
|
#: users/views.py:290
|
||||||
|
msgid "Password not same"
|
||||||
|
msgstr "密码不一致"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
#~| msgid "Asset groups"
|
||||||
|
#~ msgid "Assetgroup"
|
||||||
|
#~ msgstr "用户组"
|
Binary file not shown.
|
@ -1,515 +0,0 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2016-09-04 17:31+0800\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"Language: \n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: assets/models.py:9 assets/models.py:21
|
|
||||||
msgid "Name"
|
|
||||||
msgstr "名称"
|
|
||||||
|
|
||||||
#: assets/models.py:10 assets/models.py:29 assets/models.py:71
|
|
||||||
msgid "Created by"
|
|
||||||
msgstr "创建者"
|
|
||||||
|
|
||||||
#: assets/models.py:11 assets/models.py:30 assets/models.py:74
|
|
||||||
msgid "Comment"
|
|
||||||
msgstr "备注"
|
|
||||||
|
|
||||||
#: assets/models.py:22
|
|
||||||
msgid "Bandwidth"
|
|
||||||
msgstr "带宽"
|
|
||||||
|
|
||||||
#: assets/models.py:23
|
|
||||||
msgid "Contact"
|
|
||||||
msgstr "联系人"
|
|
||||||
|
|
||||||
#: assets/models.py:24
|
|
||||||
msgid "Phone"
|
|
||||||
msgstr "手机"
|
|
||||||
|
|
||||||
#: assets/models.py:25
|
|
||||||
msgid "Address"
|
|
||||||
msgstr "地址"
|
|
||||||
|
|
||||||
#: assets/models.py:26
|
|
||||||
msgid "Network"
|
|
||||||
msgstr "网络"
|
|
||||||
|
|
||||||
#: assets/models.py:27 assets/models.py:73
|
|
||||||
msgid "Date added"
|
|
||||||
msgstr "加入日期"
|
|
||||||
|
|
||||||
#: assets/models.py:28
|
|
||||||
msgid "Operator"
|
|
||||||
msgstr "运营商"
|
|
||||||
|
|
||||||
#: assets/models.py:37 assets/models.py:54 templates/_nav.html:23
|
|
||||||
msgid "IDC"
|
|
||||||
msgstr "机房"
|
|
||||||
|
|
||||||
#: assets/models.py:46
|
|
||||||
msgid "IP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: assets/models.py:47
|
|
||||||
msgid "Other IP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: assets/models.py:48
|
|
||||||
msgid "Remote card IP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: assets/models.py:49
|
|
||||||
msgid "Hostname"
|
|
||||||
msgstr "用户名"
|
|
||||||
|
|
||||||
#: assets/models.py:50
|
|
||||||
msgid "Port"
|
|
||||||
msgstr "端口"
|
|
||||||
|
|
||||||
#: assets/models.py:51
|
|
||||||
msgid "Asset groups"
|
|
||||||
msgstr "用户组"
|
|
||||||
|
|
||||||
#: assets/models.py:52
|
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Edit user"
|
|
||||||
msgid "Admin user"
|
|
||||||
msgstr "编辑用户"
|
|
||||||
|
|
||||||
#: assets/models.py:53
|
|
||||||
msgid "Admin password"
|
|
||||||
msgstr "管理员密码"
|
|
||||||
|
|
||||||
#: assets/models.py:55
|
|
||||||
msgid "Mac address"
|
|
||||||
msgstr "Mac地址"
|
|
||||||
|
|
||||||
#: assets/models.py:56
|
|
||||||
msgid "Brand"
|
|
||||||
msgstr "品牌"
|
|
||||||
|
|
||||||
#: assets/models.py:57
|
|
||||||
msgid "CPU"
|
|
||||||
msgstr "CPU"
|
|
||||||
|
|
||||||
#: assets/models.py:58
|
|
||||||
msgid "Memory"
|
|
||||||
msgstr "内存"
|
|
||||||
|
|
||||||
#: assets/models.py:59
|
|
||||||
msgid "Disk"
|
|
||||||
msgstr "硬盘"
|
|
||||||
|
|
||||||
#: assets/models.py:60
|
|
||||||
msgid "OS"
|
|
||||||
msgstr "操作系统"
|
|
||||||
|
|
||||||
#: assets/models.py:61
|
|
||||||
msgid "Cabinet number"
|
|
||||||
msgstr "机柜编号"
|
|
||||||
|
|
||||||
#: assets/models.py:62
|
|
||||||
msgid "Cabinet position"
|
|
||||||
msgstr "机柜层号"
|
|
||||||
|
|
||||||
#: assets/models.py:63
|
|
||||||
msgid "Asset number"
|
|
||||||
msgstr "资产编号"
|
|
||||||
|
|
||||||
#: assets/models.py:65
|
|
||||||
msgid "Asset status"
|
|
||||||
msgstr "资产状态"
|
|
||||||
|
|
||||||
#: assets/models.py:67
|
|
||||||
msgid "Asset type"
|
|
||||||
msgstr "系统类型"
|
|
||||||
|
|
||||||
#: assets/models.py:69
|
|
||||||
msgid "Asset environment"
|
|
||||||
msgstr "资产环境"
|
|
||||||
|
|
||||||
#: assets/models.py:70
|
|
||||||
msgid "Serial number"
|
|
||||||
msgstr "序列号"
|
|
||||||
|
|
||||||
#: assets/models.py:72
|
|
||||||
msgid "Is active"
|
|
||||||
msgstr "是否激活"
|
|
||||||
|
|
||||||
#: templates/_header_bar.html:8
|
|
||||||
msgid "Search"
|
|
||||||
msgstr "搜索"
|
|
||||||
|
|
||||||
#: templates/_header_bar.html:14
|
|
||||||
msgid "Welcome use Jumpserver system"
|
|
||||||
msgstr "欢迎使用Jumpserver开源跳板机系统"
|
|
||||||
|
|
||||||
#: templates/_header_bar.html:18
|
|
||||||
msgid "Help"
|
|
||||||
msgstr "帮助"
|
|
||||||
|
|
||||||
#: templates/_header_bar.html:35 templates/_nav.html:4
|
|
||||||
msgid "Home"
|
|
||||||
msgstr "仪表盘"
|
|
||||||
|
|
||||||
#: templates/_nav.html:9
|
|
||||||
msgid "Users"
|
|
||||||
msgstr "用户管理"
|
|
||||||
|
|
||||||
#: templates/_nav.html:12
|
|
||||||
msgid "User"
|
|
||||||
msgstr "用户"
|
|
||||||
|
|
||||||
#: templates/_nav.html:13
|
|
||||||
msgid "Usergroup"
|
|
||||||
msgstr "用户组"
|
|
||||||
|
|
||||||
#: templates/_nav.html:18
|
|
||||||
msgid "Assets"
|
|
||||||
msgstr "资产管理"
|
|
||||||
|
|
||||||
#: templates/_nav.html:21
|
|
||||||
msgid "Asset"
|
|
||||||
msgstr "资产"
|
|
||||||
|
|
||||||
#: templates/_nav.html:22
|
|
||||||
msgid "Assetgroup"
|
|
||||||
msgstr "用户组"
|
|
||||||
|
|
||||||
#: templates/_nav.html:24
|
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Asset admin"
|
|
||||||
msgid "Assetadmin"
|
|
||||||
msgstr "管理用户"
|
|
||||||
|
|
||||||
#: templates/_nav.html:25
|
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Asset user"
|
|
||||||
msgid "Assetuser"
|
|
||||||
msgstr "系统用户"
|
|
||||||
|
|
||||||
#: templates/_nav.html:26
|
|
||||||
msgid "Label"
|
|
||||||
msgstr "标签"
|
|
||||||
|
|
||||||
#: templates/_nav.html:30
|
|
||||||
msgid "Perms"
|
|
||||||
msgstr "权限管理"
|
|
||||||
|
|
||||||
#: templates/_nav.html:33
|
|
||||||
msgid "Perm"
|
|
||||||
msgstr "权限"
|
|
||||||
|
|
||||||
#: templates/_nav.html:36
|
|
||||||
msgid "Create perm"
|
|
||||||
msgstr "创建权限"
|
|
||||||
|
|
||||||
#: templates/_nav.html:42
|
|
||||||
msgid "Audits"
|
|
||||||
msgstr "审计"
|
|
||||||
|
|
||||||
#: templates/_nav.html:47
|
|
||||||
msgid "File"
|
|
||||||
msgstr "文件"
|
|
||||||
|
|
||||||
#: templates/_nav.html:50
|
|
||||||
msgid "File upload"
|
|
||||||
msgstr "文件上传"
|
|
||||||
|
|
||||||
#: templates/_nav.html:51
|
|
||||||
msgid "File download"
|
|
||||||
msgstr "文件下载"
|
|
||||||
|
|
||||||
#: templates/_nav.html:56
|
|
||||||
msgid "Settings"
|
|
||||||
msgstr "设置"
|
|
||||||
|
|
||||||
#: templates/_nav.html:61
|
|
||||||
msgid "Visit us"
|
|
||||||
msgstr "访问官网"
|
|
||||||
|
|
||||||
#: templates/_user_profile.html:19
|
|
||||||
msgid "Profile"
|
|
||||||
msgstr "个人信息"
|
|
||||||
|
|
||||||
#: templates/_user_profile.html:21
|
|
||||||
msgid "Logout"
|
|
||||||
msgstr "注销登录"
|
|
||||||
|
|
||||||
#: templates/captcha/image.html:3
|
|
||||||
msgid "Play CAPTCHA as audio file"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#~ msgid "Asset user"
|
|
||||||
#~ msgstr "系统用户"
|
|
||||||
|
|
||||||
#~ msgid "Password"
|
|
||||||
#~ msgstr "密码"
|
|
||||||
|
|
||||||
#~ msgid "Join usergroups"
|
|
||||||
#~ msgstr "添加到用户组"
|
|
||||||
|
|
||||||
#~ msgid "Administrator"
|
|
||||||
#~ msgstr "管理员"
|
|
||||||
|
|
||||||
#~ msgid "Email"
|
|
||||||
#~ msgstr "邮件"
|
|
||||||
|
|
||||||
#~ msgid "Role"
|
|
||||||
#~ msgstr "角色"
|
|
||||||
|
|
||||||
#~ msgid "Avatar"
|
|
||||||
#~ msgstr "头像"
|
|
||||||
|
|
||||||
#~ msgid "Wechat"
|
|
||||||
#~ msgstr "微信"
|
|
||||||
|
|
||||||
#~ msgid "Enable OTP"
|
|
||||||
#~ msgstr "二次验证"
|
|
||||||
|
|
||||||
#~ msgid "ssh private key"
|
|
||||||
#~ msgstr "ssh密钥"
|
|
||||||
|
|
||||||
#~ msgid "ssh public key"
|
|
||||||
#~ msgstr "ssh公钥"
|
|
||||||
|
|
||||||
#~ msgid "Date expired"
|
|
||||||
#~ msgstr "失效日期"
|
|
||||||
|
|
||||||
#~ msgid "Administrator is the super user of system"
|
|
||||||
#~ msgstr "Administrator是初始的超级管理员"
|
|
||||||
|
|
||||||
#~ msgid "System"
|
|
||||||
#~ msgstr "系统"
|
|
||||||
|
|
||||||
#~ msgid "Create user"
|
|
||||||
#~ msgstr "创建用户"
|
|
||||||
|
|
||||||
#~ msgid "Account"
|
|
||||||
#~ msgstr "账户"
|
|
||||||
|
|
||||||
#~ msgid "Security and Role"
|
|
||||||
#~ msgstr "角色安全"
|
|
||||||
|
|
||||||
#~ msgid "Reset"
|
|
||||||
#~ msgstr "重置"
|
|
||||||
|
|
||||||
#~ msgid "Commit"
|
|
||||||
#~ msgstr "提交"
|
|
||||||
|
|
||||||
#~ msgid "Forget password"
|
|
||||||
#~ msgstr "忘记密码"
|
|
||||||
|
|
||||||
#~ msgid "Input your email, that will send a mail to your"
|
|
||||||
#~ msgstr "输入您的邮箱, 将会发一封重置短信邮件到您的邮箱中"
|
|
||||||
|
|
||||||
#~ msgid "Login"
|
|
||||||
#~ msgstr "登录"
|
|
||||||
|
|
||||||
#~ msgid "Captcha invalid"
|
|
||||||
#~ msgstr "验证码错误"
|
|
||||||
|
|
||||||
#~ msgid "Password again"
|
|
||||||
#~ msgstr "再次输入密码"
|
|
||||||
|
|
||||||
#~ msgid "Setting"
|
|
||||||
#~ msgstr "设置"
|
|
||||||
|
|
||||||
#~ msgid "Reset link will be generated and sent to the user. "
|
|
||||||
#~ msgstr "生成重置密码连接,通过邮件发送给用户"
|
|
||||||
|
|
||||||
#~ msgid "Confirm delete"
|
|
||||||
#~ msgstr "确认删除"
|
|
||||||
|
|
||||||
#~ msgid "User detail"
|
|
||||||
#~ msgstr "用户详情"
|
|
||||||
|
|
||||||
#~ msgid "User assets"
|
|
||||||
#~ msgstr "用户资产"
|
|
||||||
|
|
||||||
#~ msgid "User log"
|
|
||||||
#~ msgstr "登录日志"
|
|
||||||
|
|
||||||
#~ msgid "Last login"
|
|
||||||
#~ msgstr "最后登录"
|
|
||||||
|
|
||||||
#~ msgid "Quick modify"
|
|
||||||
#~ msgstr "快速修改"
|
|
||||||
|
|
||||||
#~ msgid "Reset ssh key"
|
|
||||||
#~ msgstr "重置密钥"
|
|
||||||
|
|
||||||
#~ msgid "Select usergroups"
|
|
||||||
#~ msgstr "选择用户组"
|
|
||||||
|
|
||||||
#~ msgid "Add"
|
|
||||||
#~ msgstr "添加"
|
|
||||||
|
|
||||||
#~ msgid "Edit"
|
|
||||||
#~ msgstr "编辑"
|
|
||||||
|
|
||||||
#~ msgid "Delete"
|
|
||||||
#~ msgstr "删除"
|
|
||||||
|
|
||||||
#~ msgid "Delete selected"
|
|
||||||
#~ msgstr "批量删除"
|
|
||||||
|
|
||||||
#~ msgid "Update selected"
|
|
||||||
#~ msgstr "批量更新"
|
|
||||||
|
|
||||||
#~ msgid "Deactive selected"
|
|
||||||
#~ msgstr "禁用所选"
|
|
||||||
|
|
||||||
#~ msgid "Export selected"
|
|
||||||
#~ msgstr "批量导出"
|
|
||||||
|
|
||||||
#~ msgid "Begin to generate ssh private key ..."
|
|
||||||
#~ msgstr "开始生成ssh密钥"
|
|
||||||
|
|
||||||
#~ msgid "Finish to generate ssh private key ..."
|
|
||||||
#~ msgstr "生成ssh密钥成功"
|
|
||||||
|
|
||||||
#~ msgid "These is error when generate ssh key."
|
|
||||||
#~ msgstr "创建密钥失败"
|
|
||||||
|
|
||||||
#~ msgid "Create account successfully"
|
|
||||||
#~ msgstr "创建账户成功"
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "\n"
|
|
||||||
#~ " Hello %(name)s:\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " Your account has been created successfully\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">click "
|
|
||||||
#~ "here to set your password</a>\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " This link is valid for 1 hour. After it expires, <a href="
|
|
||||||
#~ "\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " ---\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " "
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "\n"
|
|
||||||
#~ " 你好 %(name)s:\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " 恭喜您,您的账号已经创建成功 </br>\n"
|
|
||||||
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点"
|
|
||||||
#~ "击这里设置密码</a> </br>\n"
|
|
||||||
#~ " 这个链接有效期1小时, 超过时间您可以 <a href=\"%(forget_password_url)s?"
|
|
||||||
#~ "email=%(email)s\">重新申请</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " ---\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " "
|
|
||||||
|
|
||||||
#~ msgid ""
|
|
||||||
#~ "\n"
|
|
||||||
#~ " Hello %(name)s:\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " Please click the link below to reset your password, if not your "
|
|
||||||
#~ "request, concern your account security\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
|
|
||||||
#~ "here reset password</a>\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " This link is valid for 1 hour. After it expires, <a href="
|
|
||||||
#~ "\"%(forget_password_url)s?email=%(email)s\">request new one<</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " ---\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(login_url)s\">Login direct</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " "
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "\n"
|
|
||||||
#~ " 您好 %(name)s:\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " 请点击下面链接重置密码, 如果不是您申请的,请关注账号安全\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">请点击"
|
|
||||||
#~ "这里设置密码 /a>\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " 这个链接有效期1小时, 超过时间您可以<a href=\"%(forget_password_url)s?"
|
|
||||||
#~ "email=%(email)s\">重新申请</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " ---\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " <a href=\"%(login_url)s\">直接登录</a>\n"
|
|
||||||
#~ "\n"
|
|
||||||
#~ " </br>\n"
|
|
||||||
#~ " "
|
|
||||||
|
|
||||||
#~ msgid "Username or password invalid"
|
|
||||||
#~ msgstr "用户名或密码错误"
|
|
||||||
|
|
||||||
#~ msgid "Logout success"
|
|
||||||
#~ msgstr "退出登录成功"
|
|
||||||
|
|
||||||
#~ msgid "Logout success, return login page"
|
|
||||||
#~ msgstr "退出登录成功,返回到登录页面"
|
|
||||||
|
|
||||||
#~ msgid "User list"
|
|
||||||
#~ msgstr "用户列表"
|
|
||||||
|
|
||||||
#~ msgid "Create user<a href=\"%s\">%s</a> success."
|
|
||||||
#~ msgstr "创建用户<a href=\"%s\">%s</a> 成功"
|
|
||||||
|
|
||||||
#~ msgid "Usergroup list"
|
|
||||||
#~ msgstr "用户组列表"
|
|
||||||
|
|
||||||
#~ msgid "Create usergroup"
|
|
||||||
#~ msgstr "创建用户组"
|
|
||||||
|
|
||||||
#~ msgid "Email address invalid, input again"
|
|
||||||
#~ msgstr "邮箱地址错误,重新输入"
|
|
||||||
|
|
||||||
#~ msgid "Send reset password message"
|
|
||||||
#~ msgstr "发送重置密码邮件"
|
|
||||||
|
|
||||||
#~ msgid "Send reset password mail success, login your mail box and follow it "
|
|
||||||
#~ msgstr ""
|
|
||||||
#~ "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
|
|
||||||
|
|
||||||
#~ msgid "Reset password success"
|
|
||||||
#~ msgstr "重置密码成功"
|
|
||||||
|
|
||||||
#~ msgid "Reset password success, return to login page"
|
|
||||||
#~ msgstr "重置密码成功,返回到登录页面"
|
|
||||||
|
|
||||||
#~ msgid "Token invalid or expired"
|
|
||||||
#~ msgstr "Token错误或失效"
|
|
||||||
|
|
||||||
#~ msgid "Password not same"
|
|
||||||
#~ msgstr "密码不一致"
|
|
|
@ -1,8 +1,14 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import errno
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
os.makedirs('../logs')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings")
|
||||||
try:
|
try:
|
||||||
from django.core.management import execute_from_command_line
|
from django.core.management import execute_from_command_line
|
||||||
|
|
|
@ -6,18 +6,19 @@
|
||||||
<script src="{% static "js/inspinia.js" %}"></script>
|
<script src="{% static "js/inspinia.js" %}"></script>
|
||||||
<script src="{% static "js/jumpserver.js" %}"></script>
|
<script src="{% static "js/jumpserver.js" %}"></script>
|
||||||
|
|
||||||
<!-- active menu -->
|
|
||||||
<script>
|
<script>
|
||||||
|
<!-- active menu -->
|
||||||
var url_array = document.location.pathname.split("/");
|
var url_array = document.location.pathname.split("/");
|
||||||
s1 = url_array[1];
|
app = url_array[1];
|
||||||
s2 = url_array[2];
|
resource = url_array[2];
|
||||||
if (s1 == ''){
|
if (app == ''){
|
||||||
$('#index').addClass('active')
|
$('#index').addClass('active')
|
||||||
} else {
|
} else {
|
||||||
$("#"+s1).addClass('active');
|
$("#"+app).addClass('active');
|
||||||
$('#'+s1+' .'+s2).addClass('active');
|
$('#'+app+' #'+resource).addClass('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<!-- ajax set cookie -->
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
var cookieValue = null;
|
var cookieValue = null;
|
||||||
if (document.cookie && document.cookie !== '') {
|
if (document.cookie && document.cookie !== '') {
|
||||||
|
@ -46,8 +47,10 @@
|
||||||
beforeSend: function(xhr, settings) {
|
beforeSend: function(xhr, settings) {
|
||||||
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
|
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
|
||||||
xhr.setRequestHeader("X-CSRFToken", csrftoken);
|
xhr.setRequestHeader("X-CSRFToken", csrftoken);
|
||||||
{# xhr.setRequestHeader("sessionid", sessionid);#}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
<!-- textarea rows -->
|
||||||
|
$('textarea').attr('rows', 5)
|
||||||
</script>
|
</script>
|
|
@ -11,7 +11,7 @@
|
||||||
</div>
|
</div>
|
||||||
<ul class="nav navbar-top-links navbar-right">
|
<ul class="nav navbar-top-links navbar-right">
|
||||||
<li>
|
<li>
|
||||||
<span class="m-r-sm text-muted welcome-message">{% trans 'Welcome use Jumpserver system' %}</span>
|
<span class="m-r-sm text-muted welcome-message">{% trans 'Welcome to use Jumpserver system' %}</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a class="dropdown-toggle count-info" data-toggle="dropdown" href="#">
|
<a class="dropdown-toggle count-info" data-toggle="dropdown" href="#">
|
||||||
|
|
|
@ -9,30 +9,30 @@
|
||||||
<i class="fa fa-group"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span>
|
<i class="fa fa-group"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="nav nav-second-level active">
|
<ul class="nav nav-second-level active">
|
||||||
<li class="users"><a href="{% url 'users:user-list' %}">{% trans 'User' %}</a></li>
|
<li id="user"><a href="{% url 'users:user-list' %}">{% trans 'User' %}</a></li>
|
||||||
<li class="usergroups"><a href="{% url 'users:usergroup-list' %}">{% trans 'Usergroup' %}</a></li>
|
<li id="user-group"><a href="{% url 'users:user-group-list' %}">{% trans 'User group' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li id="">
|
<li id="assets">
|
||||||
<a>
|
<a>
|
||||||
<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="{% url 'assets:asset-list' %}"><a href="">{% trans 'Asset' %}</a></li>
|
<li id="asset"><a href="{% url 'assets:asset-list' %}">{% trans 'Asset' %}</a></li>
|
||||||
<li class=""><a href="{% url 'assets:assetgroup-list' %}">{% trans 'Assetgroup' %}</a></li>
|
<li id="asset-group"><a href="{% url 'assets:asset-group-list' %}">{% trans 'Asset group' %}</a></li>
|
||||||
<li class=""><a href="">{% trans 'IDC' %}</a></li>
|
<li id="idc"><a href="">{% trans 'IDC' %}</a></li>
|
||||||
<li class=""><a href="">{% trans 'Assetadmin' %}</a></li>
|
<li id="admin-user"><a href="">{% trans 'Admin user' %}</a></li>
|
||||||
<li class=""><a href="">{% trans 'Assetuser' %}</a></li>
|
<li id="system-user"><a href="">{% trans 'System user' %}</a></li>
|
||||||
<li class=""><a href="">{% trans 'Label' %}</a></li>
|
<li id=""><a href="">{% trans 'Label' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li id="">
|
<li id="">
|
||||||
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a>
|
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a>
|
||||||
<ul class="nav nav-second-level">
|
<ul class="nav nav-second-level">
|
||||||
<li class="sudo">
|
<li id="sudo">
|
||||||
<a class="sudo" href="">{% trans 'Perm' %}</a>
|
<a class="sudo" href="">{% trans 'Perm' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="role">
|
<li id="role">
|
||||||
<a href="">{% trans 'Create perm' %}</a>
|
<a href="">{% trans 'Create perm' %}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -47,8 +47,8 @@
|
||||||
<i class="fa fa-download"></i> <span class="nav-label">{% trans 'File' %}</span><span class="fa arrow"></span>
|
<i class="fa fa-download"></i> <span class="nav-label">{% trans 'File' %}</span><span class="fa arrow"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="nav nav-second-level">
|
<ul class="nav nav-second-level">
|
||||||
<li class="upload"><a href="">{% trans 'File upload' %}</a></li>
|
<li id="upload"><a href="">{% trans 'File upload' %}</a></li>
|
||||||
<li class="download"><a href="">{% trans 'File download' %}</a></li>
|
<li id="download"><a href="">{% trans 'File download' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li id="">
|
<li id="">
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<strong class="font-bold"> {{ request.user.name }}<span style="color: #8095a8"></span></strong>
|
<strong class="font-bold"> {{ request.user.name }}<span style="color: #8095a8"></span></strong>
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted text-xs block">
|
<span class="text-muted text-xs block">
|
||||||
{{ request.user.get_role_display | default:"{% trans 'User' %}" }}<b class="caret"></b>
|
{{ request.user.get_role_display | default:_('User') }}<b class="caret"></b>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
{% load i18n %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<input autocomplete="off" id="{{id}}_1" class="form-control" name="{{name}}_1" type="text" />
|
<input autocomplete="off" id="{{id}}_1" class="form-control" name="{{name}}_1" placeholder="{% trans 'Captcha' %}" type="text" />
|
||||||
<span class="red-fonts" id="captcha-error" style="display: none">验证码错误</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</br>
|
</br>
|
||||||
|
|
|
@ -14,7 +14,7 @@ class UserLoginForm(forms.Form):
|
||||||
captcha = CaptchaField()
|
captcha = CaptchaField()
|
||||||
|
|
||||||
|
|
||||||
class UserAddForm(ModelForm):
|
class UserCreateForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = [
|
fields = [
|
||||||
|
@ -28,7 +28,7 @@ class UserAddForm(ModelForm):
|
||||||
}
|
}
|
||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join usergroups')}),
|
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join user groups')}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,379 +0,0 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2016-09-04 17:31+0800\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"Language: \n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
#: users/forms.py:12 users/models.py:106 users/templates/users/login.html:57
|
|
||||||
#: users/templates/users/user_detail.html:73
|
|
||||||
#: users/templates/users/user_edit.html:5
|
|
||||||
#: users/templates/users/user_list.html:13
|
|
||||||
msgid "Username"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/forms.py:13 users/templates/users/login.html:60
|
|
||||||
#: users/templates/users/reset_password.html:52
|
|
||||||
#: users/templates/users/user_add.html:8 users/templates/users/user_add.html:10
|
|
||||||
#: users/templates/users/user_edit.html:12
|
|
||||||
#: users/templates/users/user_edit.html:14
|
|
||||||
msgid "Password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/forms.py:31 users/forms.py:50
|
|
||||||
msgid "Join usergroups"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:60 users/models.py:107
|
|
||||||
#: users/templates/users/user_detail.html:69
|
|
||||||
#: users/templates/users/user_list.html:12
|
|
||||||
msgid "Name"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:61 users/models.py:118
|
|
||||||
#: users/templates/users/user_detail.html:113
|
|
||||||
msgid "Comment"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:102 users/models.py:225
|
|
||||||
msgid "Administrator"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:103
|
|
||||||
msgid "User"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:108 users/templates/users/user_detail.html:77
|
|
||||||
msgid "Email"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:109 users/templates/users/user_detail.html:181
|
|
||||||
#: users/templates/users/user_list.html:15
|
|
||||||
msgid "Usergroup"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:110 users/templates/users/user_detail.html:93
|
|
||||||
#: users/templates/users/user_list.html:14
|
|
||||||
msgid "Role"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:111
|
|
||||||
msgid "Avatar"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:112 users/templates/users/user_detail.html:88
|
|
||||||
msgid "Wechat"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:113 users/templates/users/user_detail.html:82
|
|
||||||
msgid "Phone"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:114 users/templates/users/_user.html:56
|
|
||||||
msgid "Enable OTP"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:116
|
|
||||||
msgid "ssh private key"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:117
|
|
||||||
msgid "ssh public key"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:121 users/templates/users/user_detail.html:97
|
|
||||||
msgid "Date expired"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:122 users/templates/users/user_detail.html:101
|
|
||||||
msgid "Created by"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:228
|
|
||||||
msgid "Administrator is the super user of system"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/models.py:229
|
|
||||||
msgid "System"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/_user.html:17 users/templates/users/user_list.html:5
|
|
||||||
#: users/views.py:113
|
|
||||||
msgid "Create user"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/_user.html:33
|
|
||||||
msgid "Account"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/_user.html:43
|
|
||||||
msgid "Security and Role"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/_user.html:62
|
|
||||||
msgid "Profile"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/_user.html:69
|
|
||||||
#: users/templates/users/user_detail.html:162
|
|
||||||
#: users/templates/users/user_detail.html:170
|
|
||||||
msgid "Reset"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/_user.html:70
|
|
||||||
#: users/templates/users/forget_password.html:44
|
|
||||||
#: users/templates/users/user_list.html:63
|
|
||||||
msgid "Commit"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/forget_password.html:26
|
|
||||||
msgid "Forget password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/forget_password.html:33
|
|
||||||
msgid "Input your email, that will send a mail to your"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/login.html:45 users/templates/users/login.html:65
|
|
||||||
msgid "Login"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/login.html:50
|
|
||||||
msgid "Captcha invalid"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/reset_password.html:45
|
|
||||||
#: users/templates/users/user_detail.html:159 users/utils.py:98
|
|
||||||
msgid "Reset password"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/reset_password.html:55
|
|
||||||
msgid "Password again"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/reset_password.html:57
|
|
||||||
msgid "Setting"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_add.html:12
|
|
||||||
msgid "Reset link will be generated and sent to the user. "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_delete_confirm.html:6
|
|
||||||
msgid "Confirm delete"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:18 users/views.py:173
|
|
||||||
msgid "User detail"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:20
|
|
||||||
msgid "User assets"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:21
|
|
||||||
msgid "User log"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:29
|
|
||||||
msgid "Search"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:105
|
|
||||||
msgid "Date joined"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:109
|
|
||||||
msgid "Last login"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:124
|
|
||||||
msgid "Quick modify"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:167
|
|
||||||
msgid "Reset ssh key"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:189
|
|
||||||
msgid "Select usergroups"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_detail.html:198
|
|
||||||
msgid "Add"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:16
|
|
||||||
msgid "Asset num"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:17
|
|
||||||
msgid "Active"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:44
|
|
||||||
msgid "Edit"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:45
|
|
||||||
msgid "Delete"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:55
|
|
||||||
msgid "Delete selected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:56
|
|
||||||
msgid "Update selected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:57
|
|
||||||
msgid "Deactive selected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/templates/users/user_list.html:58
|
|
||||||
msgid "Export selected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/utils.py:47
|
|
||||||
msgid "Begin to generate ssh private key ..."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/utils.py:59
|
|
||||||
msgid "Finish to generate ssh private key ..."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/utils.py:63
|
|
||||||
msgid "These is error when generate ssh key."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/utils.py:67
|
|
||||||
msgid "Create account successfully"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/utils.py:69
|
|
||||||
#, python-format
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
" Hello %(name)s:\n"
|
|
||||||
" </br>\n"
|
|
||||||
" Your account has been created successfully\n"
|
|
||||||
" </br>\n"
|
|
||||||
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">click "
|
|
||||||
"here to set your password</a>\n"
|
|
||||||
" </br>\n"
|
|
||||||
" This link is valid for 1 hour. After it expires, <a href="
|
|
||||||
"\"%(forget_password_url)s?email=%(email)s\">request new one</a>\n"
|
|
||||||
"\n"
|
|
||||||
" </br>\n"
|
|
||||||
" ---\n"
|
|
||||||
"\n"
|
|
||||||
" </br>\n"
|
|
||||||
" <a href=\"%(login_url)s\">Login direct</a>\n"
|
|
||||||
"\n"
|
|
||||||
" </br>\n"
|
|
||||||
" "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/utils.py:100
|
|
||||||
#, python-format
|
|
||||||
msgid ""
|
|
||||||
"\n"
|
|
||||||
" Hello %(name)s:\n"
|
|
||||||
" </br>\n"
|
|
||||||
" Please click the link below to reset your password, if not your request, "
|
|
||||||
"concern your account security\n"
|
|
||||||
" </br>\n"
|
|
||||||
" <a href=\"%(rest_password_url)s?token=%(rest_password_token)s\">Click "
|
|
||||||
"here reset password</a>\n"
|
|
||||||
" </br>\n"
|
|
||||||
" This link is valid for 1 hour. After it expires, <a href="
|
|
||||||
"\"%(forget_password_url)s?email=%(email)s\">request new one<</a>\n"
|
|
||||||
"\n"
|
|
||||||
" </br>\n"
|
|
||||||
" ---\n"
|
|
||||||
"\n"
|
|
||||||
" </br>\n"
|
|
||||||
" <a href=\"%(login_url)s\">Login direct</a>\n"
|
|
||||||
"\n"
|
|
||||||
" </br>\n"
|
|
||||||
" "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:53
|
|
||||||
msgid "Username or password invalid"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:70
|
|
||||||
msgid "Logout success"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:71
|
|
||||||
msgid "Logout success, return login page"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:100 users/views.py:113 users/views.py:155 users/views.py:173
|
|
||||||
#: users/views.py:197 users/views.py:210
|
|
||||||
msgid "Users"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:100
|
|
||||||
msgid "User list"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:109
|
|
||||||
#, python-format
|
|
||||||
msgid "Create user<a href=\"%s\">%s</a> success."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:155
|
|
||||||
msgid "Edit user"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:197
|
|
||||||
msgid "Usergroup list"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:210
|
|
||||||
msgid "Create usergroup"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:242
|
|
||||||
msgid "Email address invalid, input again"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:253
|
|
||||||
msgid "Send reset password message"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:254
|
|
||||||
msgid "Send reset password mail success, login your mail box and follow it "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:266
|
|
||||||
msgid "Reset password success"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:267
|
|
||||||
msgid "Reset password success, return to login page"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:283 users/views.py:296
|
|
||||||
msgid "Token invalid or expired"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: users/views.py:292
|
|
||||||
msgid "Password not same"
|
|
||||||
msgstr ""
|
|
|
@ -66,7 +66,7 @@ class UserGroup(models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'usergroup'
|
db_table = 'user-group'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def initial(cls):
|
def initial(cls):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from .models import User, UserGroup
|
||||||
|
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
groups = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='users:usergroup-detail-api')
|
groups = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='users:user-group-detail-api')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
|
|
|
@ -47,11 +47,12 @@
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group date">
|
<div class="input-group date">
|
||||||
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
||||||
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'m/d/Y' }}">
|
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'Y-m-d' }}">
|
||||||
</div>
|
</div>
|
||||||
<span class="help-block ">{{ form.date_expired.errors }}</span>
|
<span class="help-block ">{{ form.date_expired.errors }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{# {{ form.date_expired|bootstrap_horizontal }}#}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>
|
<label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
|
@ -67,7 +68,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
<div class="col-sm-4 col-sm-offset-2">
|
||||||
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
||||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Commit' %}</button>
|
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -84,6 +85,7 @@
|
||||||
$('.select2').select2();
|
$('.select2').select2();
|
||||||
|
|
||||||
$('.input-group.date').datepicker({
|
$('.input-group.date').datepicker({
|
||||||
|
format: "yyyy-mm-dd",
|
||||||
todayBtn: "linked",
|
todayBtn: "linked",
|
||||||
keyboardNavigation: false,
|
keyboardNavigation: false,
|
||||||
forceParse: false,
|
forceParse: false,
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<input type="email" name="email" class="form-control" placeholder="Email address" required="">
|
<input type="email" name="email" class="form-control" placeholder="Email address" required="">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Commit' %}</button>
|
<button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Submit' %}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,11 +13,8 @@
|
||||||
<script src="{% static "js/jumpserver.js" %}"></script>
|
<script src="{% static "js/jumpserver.js" %}"></script>
|
||||||
<style>
|
<style>
|
||||||
.captcha {
|
.captcha {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
#id_captcha_1 {
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% block custom_head_css_js %}
|
{% block custom_head_css_js %}
|
||||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||||
|
@ -12,7 +13,7 @@
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="ibox float-e-margins">
|
<div class="ibox float-e-margins">
|
||||||
<div class="ibox-title">
|
<div class="ibox-title">
|
||||||
<h5>填写用户组信息</h5>
|
<h5>{% trans 'Create user group' %}</h5>
|
||||||
<div class="ibox-tools">
|
<div class="ibox-tools">
|
||||||
<a class="collapse-link">
|
<a class="collapse-link">
|
||||||
<i class="fa fa-chevron-up"></i>
|
<i class="fa fa-chevron-up"></i>
|
|
@ -1,14 +1,15 @@
|
||||||
{% extends '_list_base.html' %}
|
{% extends '_list_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
{% load common_tags %}
|
{% load common_tags %}
|
||||||
{% block content_left_head %}
|
{% block content_left_head %}
|
||||||
<a href="{% url 'users:usergroup-add' %}" class="btn btn-sm btn-primary "> 添加用户组 </a>
|
<a href="{% url 'users:user-group-create' %}" class="btn btn-sm btn-primary "> 添加用户组 </a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_head %}
|
{% block table_head %}
|
||||||
<th class="text-center">
|
<th class="text-center">
|
||||||
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
|
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center"><a href="{% url 'users:usergroup-list' %}?sort=name">名称</a></th>
|
<th class="text-center"><a href="{% url 'users:user-group-list' %}?sort=name">名称</a></th>
|
||||||
<th class="text-center">用户数量</th>
|
<th class="text-center">用户数量</th>
|
||||||
<th class="text-center">资产数量</th>
|
<th class="text-center">资产数量</th>
|
||||||
<th class="text-center">描述</th>
|
<th class="text-center">描述</th>
|
||||||
|
@ -16,22 +17,22 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_body %}
|
{% block table_body %}
|
||||||
{% for usergroup in usergroup_list %}
|
{% for user_group in user_group_list %}
|
||||||
<tr class="gradeX">
|
<tr class="gradeX">
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<input type="checkbox" name="checked" value="{{ usergroup.id }}">
|
<input type="checkbox" name="checked" value="{{ user_group.id }}">
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{% url 'users:usergroup-detail' pk=usergroup.id %}">
|
<a href="{% url 'users:user-group-detail' pk=user_group.id %}">
|
||||||
{{ usergroup.name }}
|
{{ user_group.name }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">{{ usergroup.users.all|length }}</td>
|
<td class="text-center">{{ user_group.users.all|length }}</td>
|
||||||
<td class="text-center">数量</td>
|
<td class="text-center">数量</td>
|
||||||
<th class="text-center">{{ usergroup.comment|truncatewords:8 }}</th>
|
<th class="text-center">{{ user_group.comment|truncatewords:8 }}</th>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{% url 'users:usergroup-edit' pk=usergroup.id %}" class="btn btn-xs btn-info">编辑</a>
|
<a href="{% url 'users:user-group-update' pk=user_group.id %}" class="btn btn-xs btn-info">编辑</a>
|
||||||
<a href="{% url 'users:usergroup-delete' pk=usergroup.id %}" class="btn btn-xs btn-danger del">删除</a>
|
<a href="{% url 'users:user-group-delete' pk=user_group.id %}" class="btn btn-xs btn-danger del">删除</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
|
@ -2,7 +2,7 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load common_tags %}
|
{% load common_tags %}
|
||||||
{% block content_left_head %}
|
{% block content_left_head %}
|
||||||
<a href="{% url 'users:user-add' %}" class="btn btn-sm btn-primary "> {% trans "Create user" %} </a>
|
<a href="{% url 'users:user-create' %}" class="btn btn-sm btn-primary "> {% trans "Create user" %} </a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_head %}
|
{% block table_head %}
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<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-update' 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>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
|
|
||||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
<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">
|
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
|
||||||
{% trans 'Commit' %}
|
{% trans 'Submit' %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ class UserAddTests(TestCase):
|
||||||
'date_expired': '2086-08-06 19:12:22',
|
'date_expired': '2086-08-06 19:12:22',
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.post(reverse('users:user-add'), data)
|
response = self.client.post(reverse('users:user-create'), data)
|
||||||
self.assertEqual(response.status_code, 302)
|
self.assertEqual(response.status_code, 302)
|
||||||
self.assertEqual(response['location'], reverse('users:user-list'))
|
self.assertEqual(response['location'], reverse('users:user-list'))
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,14 @@ urlpatterns = [
|
||||||
url(r'^password/reset/success$', views.UserResetPasswordSuccessView.as_view(), name='reset-password-success'),
|
url(r'^password/reset/success$', views.UserResetPasswordSuccessView.as_view(), name='reset-password-success'),
|
||||||
url(r'^user$', views.UserListView.as_view(), name='user-list'),
|
url(r'^user$', views.UserListView.as_view(), name='user-list'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
||||||
url(r'^user/add$', views.UserAddView.as_view(), name='user-add'),
|
url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/edit$', views.UserUpdateView.as_view(), name='user-edit'),
|
url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/delete$', views.UserDeleteView.as_view(), name='user-delete'),
|
url(r'^user/(?P<pk>[0-9]+)/delete$', views.UserDeleteView.as_view(), name='user-delete'),
|
||||||
url(r'^usergroup$', views.UserGroupListView.as_view(), name='usergroup-list'),
|
url(r'^user-group$', views.UserGroupListView.as_view(), name='user-group-list'),
|
||||||
url(r'^usergroup/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='usergroup-detail'),
|
url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'),
|
||||||
url(r'^usergroup/add/$', views.UserGroupAddView.as_view(), name='usergroup-add'),
|
url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'),
|
||||||
url(r'^usergroup/(?P<pk>[0-9]+)/edit$', views.UserGroupUpdateView.as_view(), name='usergroup-edit'),
|
url(r'^user-group/(?P<pk>[0-9]+)/update$', views.UserGroupUpdateView.as_view(), name='user-group-update'),
|
||||||
url(r'^usergroup/(?P<pk>[0-9]+)/delete$', views.UserGroupDeleteView.as_view(), name='usergroup-delete'),
|
url(r'^user-group/(?P<pk>[0-9]+)/delete$', views.UserGroupDeleteView.as_view(), name='user-group-delete'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +32,6 @@ urlpatterns += [
|
||||||
url(r'^v1/users$', api.UserListAddApi.as_view(), name='user-list-api'),
|
url(r'^v1/users$', api.UserListAddApi.as_view(), name='user-list-api'),
|
||||||
url(r'^v1/users/(?P<pk>[0-9]+)$', api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
|
url(r'^v1/users/(?P<pk>[0-9]+)$', api.UserDetailDeleteUpdateApi.as_view(), name='user-detail-api'),
|
||||||
url(r'^v1/users/(?P<pk>[0-9]+)/active$', api.UserActiveApi.as_view(), name='user-active-api'),
|
url(r'^v1/users/(?P<pk>[0-9]+)/active$', api.UserActiveApi.as_view(), name='user-active-api'),
|
||||||
url(r'^v1/usergroups$', api.UserGroupListAddApi.as_view(), name='usergroup-list-api'),
|
url(r'^v1/usergroups$', api.UserGroupListAddApi.as_view(), name='user-group-list-api'),
|
||||||
url(r'^v1/usergroups/(?P<pk>[0-9]+)$', api.UserGroupDetailDeleteUpdateApi.as_view(), name='usergroup-detail-api'),
|
url(r'^v1/usergroups/(?P<pk>[0-9]+)$', api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,7 +20,7 @@ from django.contrib.auth import views as auth_view, authenticate, login, logout
|
||||||
from common.utils import get_object_or_none
|
from common.utils import get_object_or_none
|
||||||
|
|
||||||
from .models import User, UserGroup
|
from .models import User, UserGroup
|
||||||
from .forms import UserAddForm, UserUpdateForm, UserGroupForm, UserLoginForm
|
from .forms import UserCreateForm, UserUpdateForm, UserGroupForm, UserLoginForm
|
||||||
from .utils import AdminUserRequiredMixin, ssh_key_gen, user_add_success_next, send_reset_password_mail
|
from .utils import AdminUserRequiredMixin, ssh_key_gen, user_add_success_next, send_reset_password_mail
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,15 +101,15 @@ class UserListView(AdminUserRequiredMixin, ListView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
class UserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
||||||
model = User
|
model = User
|
||||||
form_class = UserAddForm
|
form_class = UserCreateForm
|
||||||
template_name = 'users/user_add.html'
|
template_name = 'users/user_create.html'
|
||||||
success_url = reverse_lazy('users:user-list')
|
success_url = reverse_lazy('users:user-list')
|
||||||
success_message = _('Create user<a href="%s">%s</a> success.')
|
success_message = _('Create user<a href="%s">%s</a> success.')
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(UserAddView, self).get_context_data(**kwargs)
|
context = super(UserCreateView, self).get_context_data(**kwargs)
|
||||||
context.update({'app': _('Users'), 'action': _('Create user')})
|
context.update({'app': _('Users'), 'action': _('Create user')})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@ -117,10 +117,8 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
||||||
user = form.save(commit=False)
|
user = form.save(commit=False)
|
||||||
user.created_by = self.request.user.username or 'System'
|
user.created_by = self.request.user.username or 'System'
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
user_add_success_next(user)
|
user_add_success_next(user)
|
||||||
|
return super(UserCreateView, self).form_valid(form)
|
||||||
return super(UserAddView, self).form_valid(form)
|
|
||||||
|
|
||||||
def get_success_message(self, cleaned_data):
|
def get_success_message(self, cleaned_data):
|
||||||
return self.success_message % (
|
return self.success_message % (
|
||||||
|
@ -132,7 +130,7 @@ class UserAddView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
||||||
class UserUpdateView(AdminUserRequiredMixin, UpdateView):
|
class UserUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||||
model = User
|
model = User
|
||||||
form_class = UserUpdateForm
|
form_class = UserUpdateForm
|
||||||
template_name = 'users/user_edit.html'
|
template_name = 'users/user_update.html'
|
||||||
context_object_name = 'user'
|
context_object_name = 'user'
|
||||||
success_url = reverse_lazy('users:user-list')
|
success_url = reverse_lazy('users:user-list')
|
||||||
|
|
||||||
|
@ -177,8 +175,8 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
|
||||||
class UserGroupListView(AdminUserRequiredMixin, ListView):
|
class UserGroupListView(AdminUserRequiredMixin, ListView):
|
||||||
model = UserGroup
|
model = UserGroup
|
||||||
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
||||||
context_object_name = 'usergroup_list'
|
context_object_name = 'user_group_list'
|
||||||
template_name = 'users/usergroup_list.html'
|
template_name = 'users/user_group_list.html'
|
||||||
ordering = '-date_added'
|
ordering = '-date_added'
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -198,26 +196,26 @@ class UserGroupListView(AdminUserRequiredMixin, ListView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class UserGroupAddView(AdminUserRequiredMixin, CreateView):
|
class UserGroupCreateView(AdminUserRequiredMixin, CreateView):
|
||||||
model = UserGroup
|
model = UserGroup
|
||||||
form_class = UserGroupForm
|
form_class = UserGroupForm
|
||||||
template_name = 'users/usergroup_add.html'
|
template_name = 'users/user_group_create.html'
|
||||||
success_url = reverse_lazy('users:usergroup-list')
|
success_url = reverse_lazy('users:user-group-list')
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(UserGroupAddView, self).get_context_data(**kwargs)
|
context = super(UserGroupCreateView, self).get_context_data(**kwargs)
|
||||||
users = User.objects.all()
|
users = User.objects.all()
|
||||||
context.update({'app': _('Users'), 'action': _('Create usergroup'), 'users': users})
|
context.update({'app': _('Users'), 'action': _('Create user group'), 'users': users})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
usergroup = form.save()
|
user_group = form.save()
|
||||||
users_id_list = self.request.POST.getlist('users', [])
|
users_id_list = self.request.POST.getlist('users', [])
|
||||||
users = [get_object_or_404(User, id=user_id) for user_id in users_id_list]
|
users = [get_object_or_404(User, id=user_id) for user_id in users_id_list]
|
||||||
usergroup.created_by = self.request.user.username or 'Admin'
|
user_group.created_by = self.request.user.username or 'Admin'
|
||||||
usergroup.users.add(*tuple(users))
|
user_group.users.add(*tuple(users))
|
||||||
usergroup.save()
|
user_group.save()
|
||||||
return super(UserGroupAddView, self).form_valid(form)
|
return super(UserGroupCreateView, self).form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class UserGroupUpdateView(UpdateView):
|
class UserGroupUpdateView(UpdateView):
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
## 语言框架
|
## 语言框架
|
||||||
1. Python 2.7 由于ansible目前不支持python3
|
1. Python 2.7 由于ansible目前不支持python3
|
||||||
2. Django 1.10 (最新版本)
|
2. Django 1.10 (最新版本)
|
||||||
3. Terminal Websocket使用go实现
|
3. Terminal Websocket使用go实现 (未来)
|
||||||
|
|
||||||
|
|
||||||
## Django规范
|
## Django规范
|
||||||
|
@ -32,7 +32,8 @@ Python方面大致的风格,我们采用pocoo的[Style Guidance](http://www.po
|
||||||
|
|
||||||
#### 最大行长度
|
#### 最大行长度
|
||||||
|
|
||||||
按PEP8规范,Python一般限制最大79个字符, 如果有必要最多84个字符
|
按PEP8规范,Python一般限制最大79个字符, 但是Django的命名,url等通常比较长,
|
||||||
|
而且21世纪都是宽屏了,所以我们限制最大120字符
|
||||||
|
|
||||||
**补充说明:HTML代码不受此规范约束。**
|
**补充说明:HTML代码不受此规范约束。**
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue