Unverified Commit a2aa923a authored by 老广's avatar 老广 Committed by GitHub

Merge pull request #1698 from jumpserver/dev

Dev
parents dea007f2 2ac5786b
...@@ -48,7 +48,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): ...@@ -48,7 +48,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
return return
node = get_object_or_404(Node, id=node_id) node = get_object_or_404(Node, id=node_id)
show_current_asset = self.request.query_params.get("show_current_asset") show_current_asset = self.request.query_params.get("show_current_asset") in ('1', 'true')
if node.is_root(): if node.is_root():
if show_current_asset: if show_current_asset:
......
...@@ -36,6 +36,10 @@ class DomainForm(forms.ModelForm): ...@@ -36,6 +36,10 @@ class DomainForm(forms.ModelForm):
class GatewayForm(PasswordAndKeyAuthForm, OrgModelForm): class GatewayForm(PasswordAndKeyAuthForm, OrgModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
password_field = self.fields.get('password')
password_field.help_text = _('Password should not contain special characters')
def save(self, commit=True): def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save` # Because we define custom field, so we need rewrite :method: `save`
......
...@@ -6,8 +6,10 @@ import uuid ...@@ -6,8 +6,10 @@ import uuid
import logging import logging
import random import random
from functools import reduce from functools import reduce
from collections import defaultdict
from django.db import models from django.db import models
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.cache import cache from django.core.cache import cache
...@@ -100,6 +102,7 @@ class Asset(OrgModelMixin): ...@@ -100,6 +102,7 @@ class Asset(OrgModelMixin):
verbose_name=_('CPU model')) verbose_name=_('CPU model'))
cpu_count = models.IntegerField(null=True, verbose_name=_('CPU count')) cpu_count = models.IntegerField(null=True, verbose_name=_('CPU count'))
cpu_cores = models.IntegerField(null=True, verbose_name=_('CPU cores')) cpu_cores = models.IntegerField(null=True, verbose_name=_('CPU cores'))
cpu_vcpus = models.IntegerField(null=True, verbose_name=_('CPU vcpus'))
memory = models.CharField(max_length=64, null=True, blank=True, memory = models.CharField(max_length=64, null=True, blank=True,
verbose_name=_('Memory')) verbose_name=_('Memory'))
disk_total = models.CharField(max_length=1024, null=True, blank=True, disk_total = models.CharField(max_length=1024, null=True, blank=True,
...@@ -161,17 +164,25 @@ class Asset(OrgModelMixin): ...@@ -161,17 +164,25 @@ class Asset(OrgModelMixin):
nodes = list(reduce(lambda x, y: set(x) | set(y), nodes)) nodes = list(reduce(lambda x, y: set(x) | set(y), nodes))
return nodes return nodes
@property @classmethod
def org_name(self): def get_queryset_by_fullname_list(cls, fullname_list):
from orgs.models import Organization org_fullname_map = defaultdict(list)
org = Organization.get_instance(self.org_id) for fullname in fullname_list:
return org.name hostname, org = cls.split_fullname(fullname)
org_fullname_map[org].append(hostname)
filter_arg = Q()
for org, hosts in org_fullname_map.items():
if org.is_real():
filter_arg |= Q(hostname__in=hosts, org_id=org.id)
else:
filter_arg |= Q(Q(org_id__isnull=True) | Q(org_id=''), hostname__in=hosts)
return Asset.objects.filter(filter_arg)
@property @property
def hardware_info(self): def hardware_info(self):
if self.cpu_count: if self.cpu_count:
return '{} Core {} {}'.format( return '{} Core {} {}'.format(
self.cpu_count * self.cpu_cores, self.cpu_vcpus or self.cpu_count * self.cpu_cores,
self.memory, self.disk_total self.memory, self.disk_total
) )
else: else:
......
...@@ -35,4 +35,4 @@ class Label(OrgModelMixin): ...@@ -35,4 +35,4 @@ class Label(OrgModelMixin):
class Meta: class Meta:
db_table = "assets_label" db_table = "assets_label"
unique_together = [('name', 'value')] unique_together = [('name', 'value', 'org_id')]
...@@ -44,7 +44,7 @@ def set_assets_hardware_info(result, **kwargs): ...@@ -44,7 +44,7 @@ def set_assets_hardware_info(result, **kwargs):
logger.error("Get asset info failed: {}".format(hostname)) logger.error("Get asset info failed: {}".format(hostname))
continue continue
asset = get_object_or_none(Asset, hostname=hostname) asset = Asset.objects.get_object_by_fullname(hostname)
if not asset: if not asset:
continue continue
...@@ -60,6 +60,7 @@ def set_assets_hardware_info(result, **kwargs): ...@@ -60,6 +60,7 @@ def set_assets_hardware_info(result, **kwargs):
___cpu_model = ___cpu_model[:64] ___cpu_model = ___cpu_model[:64]
___cpu_count = info.get('ansible_processor_count', 0) ___cpu_count = info.get('ansible_processor_count', 0)
___cpu_cores = info.get('ansible_processor_cores', None) or len(info.get('ansible_processor', [])) ___cpu_cores = info.get('ansible_processor_cores', None) or len(info.get('ansible_processor', []))
___cpu_vcpus = info.get('ansible_processor_vcpus', 0)
___memory = '%s %s' % capacity_convert('{} MB'.format(info.get('ansible_memtotal_mb'))) ___memory = '%s %s' % capacity_convert('{} MB'.format(info.get('ansible_memtotal_mb')))
disk_info = {} disk_info = {}
for dev, dev_info in info.get('ansible_devices', {}).items(): for dev, dev_info in info.get('ansible_devices', {}).items():
...@@ -95,7 +96,7 @@ def update_assets_hardware_info_util(assets, task_name=None): ...@@ -95,7 +96,7 @@ def update_assets_hardware_info_util(assets, task_name=None):
# task_name = _("Update some assets hardware info") # task_name = _("Update some assets hardware info")
task_name = _("更新资产硬件信息") task_name = _("更新资产硬件信息")
tasks = const.UPDATE_ASSETS_HARDWARE_TASKS tasks = const.UPDATE_ASSETS_HARDWARE_TASKS
hostname_list = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] hostname_list = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()]
if not hostname_list: if not hostname_list:
logger.info("Not hosts get, may be asset is not active or not unixlike platform") logger.info("Not hosts get, may be asset is not active or not unixlike platform")
return {} return {}
...@@ -134,7 +135,7 @@ def update_assets_hardware_info_period(): ...@@ -134,7 +135,7 @@ def update_assets_hardware_info_period():
# task_name = _("Update assets hardware info period") # task_name = _("Update assets hardware info period")
task_name = _("定期更新资产硬件信息") task_name = _("定期更新资产硬件信息")
hostname_list = [ hostname_list = [
asset.hostname for asset in Asset.objects.all() asset.fullname for asset in Asset.objects.all()
if asset.is_active and asset.is_unixlike() if asset.is_active and asset.is_unixlike()
] ]
tasks = const.UPDATE_ASSETS_HARDWARE_TASKS tasks = const.UPDATE_ASSETS_HARDWARE_TASKS
...@@ -181,7 +182,7 @@ def test_admin_user_connectability_util(admin_user, task_name): ...@@ -181,7 +182,7 @@ def test_admin_user_connectability_util(admin_user, task_name):
from ops.utils import update_or_create_ansible_task from ops.utils import update_or_create_ansible_task
assets = admin_user.get_related_assets() assets = admin_user.get_related_assets()
hosts = [asset.hostname for asset in assets hosts = [asset.fullname for asset in assets
if asset.is_active and asset.is_unixlike()] if asset.is_active and asset.is_unixlike()]
if not hosts: if not hosts:
return return
...@@ -228,7 +229,7 @@ def test_asset_connectability_util(assets, task_name=None): ...@@ -228,7 +229,7 @@ def test_asset_connectability_util(assets, task_name=None):
if task_name is None: if task_name is None:
# task_name = _("Test assets connectability") # task_name = _("Test assets connectability")
task_name = _("测试资产可连接性") task_name = _("测试资产可连接性")
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()]
if not hosts: if not hosts:
logger.info("No hosts, passed") logger.info("No hosts, passed")
return {} return {}
...@@ -280,7 +281,7 @@ def test_system_user_connectability_util(system_user, task_name): ...@@ -280,7 +281,7 @@ def test_system_user_connectability_util(system_user, task_name):
""" """
from ops.utils import update_or_create_ansible_task from ops.utils import update_or_create_ansible_task
assets = system_user.get_assets() assets = system_user.get_assets()
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()]
tasks = const.TEST_SYSTEM_USER_CONN_TASKS tasks = const.TEST_SYSTEM_USER_CONN_TASKS
if not hosts: if not hosts:
logger.info("No hosts, passed") logger.info("No hosts, passed")
...@@ -378,7 +379,7 @@ def push_system_user_util(system_users, assets, task_name): ...@@ -378,7 +379,7 @@ def push_system_user_util(system_users, assets, task_name):
logger.info("Not tasks, passed") logger.info("Not tasks, passed")
return {} return {}
hosts = [asset.hostname for asset in assets if asset.is_active and asset.is_unixlike()] hosts = [asset.fullname for asset in assets if asset.is_active and asset.is_unixlike()]
if not hosts: if not hosts:
logger.info("Not hosts, passed") logger.info("Not hosts, passed")
return {} return {}
......
...@@ -451,10 +451,11 @@ $(document).ready(function(){ ...@@ -451,10 +451,11 @@ $(document).ready(function(){
$.each(rows, function (index, obj) { $.each(rows, function (index, obj) {
assets.push(obj.id) assets.push(obj.id)
}); });
var _node_id = current_node ? current_node : null;
$.ajax({ $.ajax({
url: "{% url "assets:asset-export" %}", url: "{% url "assets:asset-export" %}",
method: 'POST', method: 'POST',
data: JSON.stringify({assets_id: assets, node_id: current_node.node_id}), data: JSON.stringify({assets_id: assets, node_id: _node_id}),
dataType: "json", dataType: "json",
success: function (data, textStatus) { success: function (data, textStatus) {
window.open(data.redirect) window.open(data.redirect)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
{% block form %} {% block form %}
<form action="" method="post" class="form-horizontal"> <form action="" method="post" class="form-horizontal">
{% if form.no_field_errors %} {% if form.non_field_errors %}
<div class="alert alert-danger"> <div class="alert alert-danger">
{{ form.non_field_errors }} {{ form.non_field_errors }}
</div> </div>
......
...@@ -12,8 +12,8 @@ def get_assets_by_id_list(id_list): ...@@ -12,8 +12,8 @@ def get_assets_by_id_list(id_list):
return Asset.objects.filter(id__in=id_list) return Asset.objects.filter(id__in=id_list)
def get_assets_by_hostname_list(hostname_list): def get_assets_by_fullname_list(hostname_list):
return Asset.objects.filter(hostname__in=hostname_list) return Asset.objects.get_queryset_by_fullname_list(hostname_list)
def get_system_user_by_name(name): def get_system_user_by_name(name):
......
...@@ -214,13 +214,13 @@ class AssetExportView(LoginRequiredMixin, View): ...@@ -214,13 +214,13 @@ class AssetExportView(LoginRequiredMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
try: try:
assets_id = json.loads(request.body).get('assets_id', []) assets_id = json.loads(request.body).get('assets_id', [])
assets_node_id = json.loads(request.body).get('node_id', None) node_id = json.loads(request.body).get('node_id', None)
except ValueError: except ValueError:
return HttpResponse('Json object not valid', status=400) return HttpResponse('Json object not valid', status=400)
if not assets_id and assets_node_id: if not assets_id:
assets_node = get_object_or_none(Node, id=assets_node_id) node = get_object_or_none(Node, id=node_id) if node_id else Node.root()
assets = assets_node.get_all_assets() assets = node.get_all_assets()
for asset in assets: for asset in assets:
assets_id.append(asset.id) assets_id.append(asset.id)
......
...@@ -8,7 +8,7 @@ msgid "" ...@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n" "Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-08-13 15:01+0800\n" "POT-Creation-Date: 2018-08-15 15:14+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n"
...@@ -103,7 +103,7 @@ msgid "Port" ...@@ -103,7 +103,7 @@ msgid "Port"
msgstr "端口" msgstr "端口"
#: assets/forms/domain.py:15 assets/forms/label.py:13 #: assets/forms/domain.py:15 assets/forms/label.py:13
#: assets/models/asset.py:231 assets/templates/assets/admin_user_list.html:25 #: assets/models/asset.py:232 assets/templates/assets/admin_user_list.html:25
#: assets/templates/assets/domain_detail.html:60 #: assets/templates/assets/domain_detail.html:60
#: assets/templates/assets/domain_list.html:23 #: assets/templates/assets/domain_list.html:23
#: assets/templates/assets/label_list.html:16 #: assets/templates/assets/label_list.html:16
...@@ -123,7 +123,11 @@ msgstr "端口" ...@@ -123,7 +123,11 @@ msgstr "端口"
msgid "Asset" msgid "Asset"
msgstr "资产" msgstr "资产"
#: assets/forms/domain.py:55 assets/forms/user.py:79 assets/forms/user.py:139 #: assets/forms/domain.py:42
msgid "Password should not contain special characters"
msgstr "密码不能包含特殊字符"
#: assets/forms/domain.py:59 assets/forms/user.py:79 assets/forms/user.py:139
#: assets/models/base.py:22 assets/models/cluster.py:18 #: assets/models/base.py:22 assets/models/cluster.py:18
#: assets/models/domain.py:18 assets/models/group.py:20 #: assets/models/domain.py:18 assets/models/group.py:20
#: assets/models/label.py:18 assets/templates/assets/admin_user_detail.html:56 #: assets/models/label.py:18 assets/templates/assets/admin_user_detail.html:56
...@@ -156,7 +160,7 @@ msgstr "资产" ...@@ -156,7 +160,7 @@ msgstr "资产"
msgid "Name" msgid "Name"
msgstr "名称" msgstr "名称"
#: assets/forms/domain.py:56 assets/forms/user.py:80 assets/forms/user.py:140 #: assets/forms/domain.py:60 assets/forms/user.py:80 assets/forms/user.py:140
#: assets/models/base.py:23 assets/templates/assets/admin_user_detail.html:60 #: assets/models/base.py:23 assets/templates/assets/admin_user_detail.html:60
#: assets/templates/assets/admin_user_list.html:24 #: assets/templates/assets/admin_user_list.html:24
#: assets/templates/assets/domain_gateway_list.html:60 #: assets/templates/assets/domain_gateway_list.html:60
...@@ -303,42 +307,48 @@ msgstr "CPU数量" ...@@ -303,42 +307,48 @@ msgstr "CPU数量"
msgid "CPU cores" msgid "CPU cores"
msgstr "CPU核数" msgstr "CPU核数"
#: assets/models/asset.py:104 assets/templates/assets/asset_detail.html:89 #: assets/models/asset.py:103
#, fuzzy
#| msgid "CPU count"
msgid "CPU vcpus"
msgstr "CPU数量"
#: assets/models/asset.py:105 assets/templates/assets/asset_detail.html:89
msgid "Memory" msgid "Memory"
msgstr "内存" msgstr "内存"
#: assets/models/asset.py:106 #: assets/models/asset.py:107
msgid "Disk total" msgid "Disk total"
msgstr "硬盘大小" msgstr "硬盘大小"
#: assets/models/asset.py:108 #: assets/models/asset.py:109
msgid "Disk info" msgid "Disk info"
msgstr "硬盘信息" msgstr "硬盘信息"
#: assets/models/asset.py:111 assets/templates/assets/asset_detail.html:101 #: assets/models/asset.py:112 assets/templates/assets/asset_detail.html:101
#: assets/templates/assets/user_asset_list.html:166 #: assets/templates/assets/user_asset_list.html:166
msgid "OS" msgid "OS"
msgstr "操作系统" msgstr "操作系统"
#: assets/models/asset.py:113 #: assets/models/asset.py:114
msgid "OS version" msgid "OS version"
msgstr "系统版本" msgstr "系统版本"
#: assets/models/asset.py:115 #: assets/models/asset.py:116
msgid "OS arch" msgid "OS arch"
msgstr "系统架构" msgstr "系统架构"
#: assets/models/asset.py:117 #: assets/models/asset.py:118
msgid "Hostname raw" msgid "Hostname raw"
msgstr "主机名原始" msgstr "主机名原始"
#: assets/models/asset.py:121 assets/templates/assets/asset_create.html:34 #: assets/models/asset.py:122 assets/templates/assets/asset_create.html:34
#: assets/templates/assets/asset_detail.html:220 #: assets/templates/assets/asset_detail.html:220
#: assets/templates/assets/asset_update.html:39 templates/_nav.html:27 #: assets/templates/assets/asset_update.html:39 templates/_nav.html:27
msgid "Labels" msgid "Labels"
msgstr "标签管理" msgstr "标签管理"
#: assets/models/asset.py:123 assets/models/base.py:30 #: assets/models/asset.py:124 assets/models/base.py:30
#: assets/models/cluster.py:28 assets/models/group.py:21 #: assets/models/cluster.py:28 assets/models/group.py:21
#: assets/templates/assets/admin_user_detail.html:68 #: assets/templates/assets/admin_user_detail.html:68
#: assets/templates/assets/asset_detail.html:117 #: assets/templates/assets/asset_detail.html:117
...@@ -350,7 +360,7 @@ msgstr "标签管理" ...@@ -350,7 +360,7 @@ msgstr "标签管理"
msgid "Created by" msgid "Created by"
msgstr "创建者" msgstr "创建者"
#: assets/models/asset.py:126 assets/models/cluster.py:26 #: assets/models/asset.py:127 assets/models/cluster.py:26
#: assets/models/domain.py:21 assets/models/group.py:22 #: assets/models/domain.py:21 assets/models/group.py:22
#: assets/models/label.py:24 assets/templates/assets/admin_user_detail.html:64 #: assets/models/label.py:24 assets/templates/assets/admin_user_detail.html:64
#: assets/templates/assets/domain_detail.html:68 #: assets/templates/assets/domain_detail.html:68
...@@ -364,7 +374,7 @@ msgstr "创建者" ...@@ -364,7 +374,7 @@ msgstr "创建者"
msgid "Date created" msgid "Date created"
msgstr "创建日期" msgstr "创建日期"
#: assets/models/asset.py:128 assets/models/base.py:27 #: assets/models/asset.py:129 assets/models/base.py:27
#: assets/models/cluster.py:29 assets/models/domain.py:19 #: assets/models/cluster.py:29 assets/models/domain.py:19
#: assets/models/domain.py:48 assets/models/group.py:23 #: assets/models/domain.py:48 assets/models/group.py:23
#: assets/models/label.py:22 assets/templates/assets/admin_user_detail.html:72 #: assets/models/label.py:22 assets/templates/assets/admin_user_detail.html:72
...@@ -474,7 +484,7 @@ msgstr "默认资产组" ...@@ -474,7 +484,7 @@ msgstr "默认资产组"
msgid "User" msgid "User"
msgstr "用户" msgstr "用户"
#: assets/models/label.py:19 assets/models/node.py:19 #: assets/models/label.py:19 assets/models/node.py:20
#: assets/templates/assets/label_list.html:15 common/models.py:27 #: assets/templates/assets/label_list.html:15 common/models.py:27
msgid "Value" msgid "Value"
msgstr "值" msgstr "值"
...@@ -483,7 +493,7 @@ msgstr "值" ...@@ -483,7 +493,7 @@ msgstr "值"
msgid "Category" msgid "Category"
msgstr "分类" msgstr "分类"
#: assets/models/node.py:18 #: assets/models/node.py:19
msgid "Key" msgid "Key"
msgstr "" msgstr ""
...@@ -557,35 +567,35 @@ msgstr "系统用户" ...@@ -557,35 +567,35 @@ msgstr "系统用户"
msgid "%(value)s is not an even number" msgid "%(value)s is not an even number"
msgstr "%(value)s is not an even number" msgstr "%(value)s is not an even number"
#: assets/tasks.py:96 assets/tasks.py:116 #: assets/tasks.py:97 assets/tasks.py:117
msgid "更新资产硬件信息" msgid "更新资产硬件信息"
msgstr "" msgstr ""
#: assets/tasks.py:135 #: assets/tasks.py:136
msgid "定期更新资产硬件信息" msgid "定期更新资产硬件信息"
msgstr "" msgstr ""
#: assets/tasks.py:213 #: assets/tasks.py:214
msgid "定期测试管理账号可连接性: {}" msgid "定期测试管理账号可连接性: {}"
msgstr "" msgstr ""
#: assets/tasks.py:220 #: assets/tasks.py:221
msgid "测试管理行号可连接性: {}" msgid "测试管理行号可连接性: {}"
msgstr "" msgstr ""
#: assets/tasks.py:230 #: assets/tasks.py:231
msgid "测试资产可连接性" msgid "测试资产可连接性"
msgstr "" msgstr ""
#: assets/tasks.py:300 #: assets/tasks.py:301
msgid "Test system user connectability: {}" msgid "Test system user connectability: {}"
msgstr "测试系统用户可连接性: {}" msgstr "测试系统用户可连接性: {}"
#: assets/tasks.py:316 #: assets/tasks.py:317
msgid "定期测试系统用户可连接性: {}" msgid "定期测试系统用户可连接性: {}"
msgstr "" msgstr ""
#: assets/tasks.py:401 #: assets/tasks.py:402
msgid "推送系统用户到入资产: {}" msgid "推送系统用户到入资产: {}"
msgstr "" msgstr ""
...@@ -850,7 +860,7 @@ msgstr "选择节点" ...@@ -850,7 +860,7 @@ msgstr "选择节点"
#: assets/templates/assets/admin_user_detail.html:100 #: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:200 #: assets/templates/assets/asset_detail.html:200
#: assets/templates/assets/asset_list.html:630 #: assets/templates/assets/asset_list.html:631
#: assets/templates/assets/system_user_detail.html:195 #: assets/templates/assets/system_user_detail.html:195
#: assets/templates/assets/system_user_list.html:139 templates/_modal.html:22 #: assets/templates/assets/system_user_list.html:139 templates/_modal.html:22
#: terminal/templates/terminal/session_detail.html:108 #: terminal/templates/terminal/session_detail.html:108
...@@ -1052,7 +1062,7 @@ msgstr "重命名成功" ...@@ -1052,7 +1062,7 @@ msgstr "重命名成功"
msgid "Rename failed, do not change the root node name" msgid "Rename failed, do not change the root node name"
msgstr "重命名失败,不可以更改根节点名称" msgstr "重命名失败,不可以更改根节点名称"
#: assets/templates/assets/asset_list.html:625 #: assets/templates/assets/asset_list.html:626
#: assets/templates/assets/system_user_list.html:134 #: assets/templates/assets/system_user_list.html:134
#: users/templates/users/user_detail.html:369 #: users/templates/users/user_detail.html:369
#: users/templates/users/user_detail.html:394 #: users/templates/users/user_detail.html:394
...@@ -1063,20 +1073,20 @@ msgstr "重命名失败,不可以更改根节点名称" ...@@ -1063,20 +1073,20 @@ msgstr "重命名失败,不可以更改根节点名称"
msgid "Are you sure?" msgid "Are you sure?"
msgstr "你确认吗?" msgstr "你确认吗?"
#: assets/templates/assets/asset_list.html:626 #: assets/templates/assets/asset_list.html:627
msgid "This will delete the selected assets !!!" msgid "This will delete the selected assets !!!"
msgstr "删除选择资产" msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:634 #: assets/templates/assets/asset_list.html:635
msgid "Asset Deleted." msgid "Asset Deleted."
msgstr "已被删除" msgstr "已被删除"
#: assets/templates/assets/asset_list.html:635 #: assets/templates/assets/asset_list.html:636
#: assets/templates/assets/asset_list.html:640 #: assets/templates/assets/asset_list.html:641
msgid "Asset Delete" msgid "Asset Delete"
msgstr "删除" msgstr "删除"
#: assets/templates/assets/asset_list.html:639 #: assets/templates/assets/asset_list.html:640
msgid "Asset Deleting failed." msgid "Asset Deleting failed."
msgstr "删除失败" msgstr "删除失败"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# #
from .ansible.inventory import BaseInventory from .ansible.inventory import BaseInventory
from assets.utils import get_assets_by_hostname_list, get_system_user_by_name from assets.utils import get_assets_by_fullname_list, get_system_user_by_name
__all__ = [ __all__ = [
'JMSInventory' 'JMSInventory'
...@@ -44,7 +44,7 @@ class JMSInventory(BaseInventory): ...@@ -44,7 +44,7 @@ class JMSInventory(BaseInventory):
super().__init__(host_list=host_list) super().__init__(host_list=host_list)
def get_jms_assets(self): def get_jms_assets(self):
assets = get_assets_by_hostname_list(self.hostname_list) assets = get_assets_by_fullname_list(self.hostname_list)
return assets return assets
def convert_to_ansible(self, asset, run_as_admin=False): def convert_to_ansible(self, asset, run_as_admin=False):
......
...@@ -8,7 +8,7 @@ from django.shortcuts import redirect ...@@ -8,7 +8,7 @@ from django.shortcuts import redirect
from django.forms import ModelForm from django.forms import ModelForm
from django.http.response import HttpResponseForbidden from django.http.response import HttpResponseForbidden
from common.utils import get_logger from common.utils import get_logger, is_uuid
from .utils import current_org, set_current_org, set_to_root_org from .utils import current_org, set_current_org, set_to_root_org
from .models import Organization from .models import Organization
...@@ -39,6 +39,25 @@ class OrgManager(models.Manager): ...@@ -39,6 +39,25 @@ class OrgManager(models.Manager):
tl.times += 1 tl.times += 1
return queryset return queryset
def filter_by_fullname(self, fullname, field=None):
ori_org = current_org
value, org = self.model.split_fullname(fullname)
set_current_org(org)
if not field:
if hasattr(self.model, 'name'):
field = 'name'
elif hasattr(self.model, 'hostname'):
field = 'hostname'
queryset = self.get_queryset().filter(**{field: value})
set_current_org(ori_org)
return queryset
def get_object_by_fullname(self, fullname, field=None):
queryset = self.filter_by_fullname(fullname, field=field)
if len(queryset) == 1:
return queryset[0]
return None
def all(self): def all(self):
if not current_org: if not current_org:
msg = 'You can `objects.set_current_org(org).all()` then run it' msg = 'You can `objects.set_current_org(org).all()` then run it'
...@@ -57,11 +76,50 @@ class OrgModelMixin(models.Model): ...@@ -57,11 +76,50 @@ class OrgModelMixin(models.Model):
org_id = models.CharField(max_length=36, null=True, blank=True, default=None) org_id = models.CharField(max_length=36, null=True, blank=True, default=None)
objects = OrgManager() objects = OrgManager()
sep = '@'
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if current_org and current_org.is_real(): if current_org and current_org.is_real():
self.org_id = current_org.id self.org_id = current_org.id
return super().save(*args, **kwargs) return super().save(*args, **kwargs)
@classmethod
def split_fullname(cls, fullname, sep=None):
if not sep:
sep = cls.sep
index = fullname.rfind(sep)
if index == -1:
value = fullname
org = Organization.default()
else:
value = fullname[:index]
org = Organization.get_instance(fullname[index + 1:])
return value, org
@property
def org(self):
from orgs.models import Organization
org = Organization.get_instance(self.org_id)
return org
@property
def org_name(self):
return self.org.name
@property
def fullname(self, attr=None):
name = ''
if attr and hasattr(self, attr):
name = getattr(self, attr)
elif hasattr(self, 'name'):
name = self.name
elif hasattr(self, 'hostname'):
name = self.hostname
if self.org.is_real():
return name + self.sep + self.org_name
else:
return name
class Meta: class Meta:
abstract = True abstract = True
......
...@@ -4,6 +4,8 @@ from django.db import models ...@@ -4,6 +4,8 @@ from django.db import models
from django.core.cache import cache from django.core.cache import cache
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import is_uuid
class Organization(models.Model): class Organization(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
...@@ -15,19 +17,23 @@ class Organization(models.Model): ...@@ -15,19 +17,23 @@ class Organization(models.Model):
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
CACHE_PREFIX = 'JMS_ORG_{}' CACHE_PREFIX = 'JMS_ORG_{}'
ROOT_ID = 'ROOT' ROOT_ID_NAME = 'ROOT'
DEFAULT_ID = 'DEFAULT' DEFAULT_ID_NAME = 'DEFAULT'
def __str__(self): def __str__(self):
return self.name return self.name
def set_to_cache(self): def set_to_cache(self):
key = self.CACHE_PREFIX.format(self.id) key_id = self.CACHE_PREFIX.format(self.id)
cache.set(key, self, 3600) key_name = self.CACHE_PREFIX.format(self.name)
cache.set(key_id, self, 3600)
cache.set(key_name, self, 3600)
def expire_cache(self): def expire_cache(self):
key = self.CACHE_PREFIX.format(self.id) key_id = self.CACHE_PREFIX.format(self.id)
cache.set(key, self, 1) key_name = self.CACHE_PREFIX.format(self.name)
cache.delete(key_id)
cache.delete(key_name)
@classmethod @classmethod
def get_instance_from_cache(cls, oid): def get_instance_from_cache(cls, oid):
...@@ -35,18 +41,23 @@ class Organization(models.Model): ...@@ -35,18 +41,23 @@ class Organization(models.Model):
return cache.get(key, None) return cache.get(key, None)
@classmethod @classmethod
def get_instance(cls, oid, default=True): def get_instance(cls, id_or_name, default=True):
cached = cls.get_instance_from_cache(oid) cached = cls.get_instance_from_cache(id_or_name)
if cached: if cached:
return cached return cached
if oid == cls.DEFAULT_ID: if not id_or_name:
return cls.default() if default else None
elif id_or_name == cls.DEFAULT_ID_NAME:
return cls.default() return cls.default()
elif oid == cls.ROOT_ID: elif id_or_name == cls.ROOT_ID_NAME:
return cls.root() return cls.root()
try: try:
org = cls.objects.get(id=oid) if is_uuid(id_or_name):
org = cls.objects.get(id=id_or_name)
else:
org = cls.objects.get(name=id_or_name)
org.set_to_cache() org.set_to_cache()
except cls.DoesNotExist: except cls.DoesNotExist:
org = cls.default() if default else None org = cls.default() if default else None
...@@ -56,6 +67,8 @@ class Organization(models.Model): ...@@ -56,6 +67,8 @@ class Organization(models.Model):
from users.models import User from users.models import User
if self.is_default(): if self.is_default():
users = User.objects.filter(orgs__isnull=True) users = User.objects.filter(orgs__isnull=True)
elif not self.is_real():
users = User.objects.all()
else: else:
users = self.users.all() users = self.users.all()
users = users.exclude(role=User.ROLE_APP) users = users.exclude(role=User.ROLE_APP)
...@@ -90,14 +103,20 @@ class Organization(models.Model): ...@@ -90,14 +103,20 @@ class Organization(models.Model):
@classmethod @classmethod
def default(cls): def default(cls):
return cls(id=cls.DEFAULT_ID, name="Default") return cls(id=cls.DEFAULT_ID_NAME, name=cls.DEFAULT_ID_NAME)
@classmethod @classmethod
def root(cls): def root(cls):
return cls(id=cls.ROOT_ID, name='Root') return cls(id=cls.ROOT_ID_NAME, name=cls.ROOT_ID_NAME)
def is_root(self):
if self.id is self.ROOT_ID_NAME:
return True
else:
return False
def is_default(self): def is_default(self):
if self.id is self.DEFAULT_ID: if self.id is self.DEFAULT_ID_NAME:
return True return True
else: else:
return False return False
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment