Commit 26f68bc7 authored by ibuler's avatar ibuler

[Update] 修改asset表结构

parent a5b874e2
...@@ -168,8 +168,8 @@ class AssetGatewayApi(generics.RetrieveAPIView): ...@@ -168,8 +168,8 @@ class AssetGatewayApi(generics.RetrieveAPIView):
asset = get_object_or_404(Asset, pk=asset_id) asset = get_object_or_404(Asset, pk=asset_id)
if asset.domain and \ if asset.domain and \
asset.domain.gateways.filter(protocol=asset.protocol).exists(): asset.domain.gateways.filter(protocol='ssh').exists():
gateway = random.choice(asset.domain.gateways.filter(protocol=asset.protocol)) gateway = random.choice(asset.domain.gateways.filter(protocol='ssh'))
serializer = serializers.GatewayWithAuthSerializer(instance=gateway) serializer = serializers.GatewayWithAuthSerializer(instance=gateway)
return Response(serializer.data) return Response(serializer.data)
else: else:
......
...@@ -48,6 +48,12 @@ class AssetQuerySet(models.QuerySet): ...@@ -48,6 +48,12 @@ class AssetQuerySet(models.QuerySet):
return self.active() return self.active()
class AssetManager(OrgManager):
def get_queryset(self):
queryset = super().get_queryset().prefetch_related("nodes", "protocols")
return queryset
class Protocol(models.Model): class Protocol(models.Model):
PROTOCOL_SSH = 'ssh' PROTOCOL_SSH = 'ssh'
PROTOCOL_RDP = 'rdp' PROTOCOL_RDP = 'rdp'
...@@ -127,7 +133,7 @@ class Asset(OrgModelMixin): ...@@ -127,7 +133,7 @@ class Asset(OrgModelMixin):
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created')) date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date created'))
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
objects = OrgManager.from_queryset(AssetQuerySet)() objects = AssetManager.from_queryset(AssetQuerySet)()
CONNECTIVITY_CACHE_KEY = '_JMS_ASSET_CONNECTIVITY_{}' CONNECTIVITY_CACHE_KEY = '_JMS_ASSET_CONNECTIVITY_{}'
UNREACHABLE, REACHABLE, UNKNOWN = range(0, 3) UNREACHABLE, REACHABLE, UNKNOWN = range(0, 3)
CONNECTIVITY_CHOICES = ( CONNECTIVITY_CHOICES = (
...@@ -148,19 +154,39 @@ class Asset(OrgModelMixin): ...@@ -148,19 +154,39 @@ class Asset(OrgModelMixin):
return True, '' return True, ''
return False, warning return False, warning
def support_ansible(self): @property
if self.platform in ("Windows", "Windows2016", "Other"): def protocols_name(self):
return False names = []
if self.protocol != 'ssh': for protocol in self.protocols.all():
return False names.append(protocol.name)
return True return names
def has_protocol(self, name):
return name in self.protocols_name
def get_protocol_by_name(self, name):
for i in self.protocols.all():
if i.name.lower() == name.lower():
return i
return None
@property
def protocol_ssh(self):
return self.get_protocol_by_name("ssh")
@property
def protocol_rdp(self):
return self.get_protocol_by_name("rdp")
def is_unixlike(self): def is_unixlike(self):
if self.platform not in ("Windows", "Windows2016"): if self.platform not in ("Windows", "Windows2016", "Other"):
return True return True
else: else:
return False return False
def is_support_ansible(self):
return self.has_protocol('ssh') and self.platform not in ("Other",)
def get_nodes(self): def get_nodes(self):
from .node import Node from .node import Node
nodes = self.nodes.all() or [Node.root()] nodes = self.nodes.all() or [Node.root()]
...@@ -189,6 +215,15 @@ class Asset(OrgModelMixin): ...@@ -189,6 +215,15 @@ class Asset(OrgModelMixin):
filter_arg |= Q(Q(org_id__isnull=True) | Q(org_id=''), hostname__in=hosts) filter_arg |= Q(Q(org_id__isnull=True) | Q(org_id=''), hostname__in=hosts)
return Asset.objects.filter(filter_arg) return Asset.objects.filter(filter_arg)
@property
def cpu_info(self):
info = ""
if self.cpu_model:
info += self.cpu_model
if self.cpu_count and self.cpu_cores:
info += "{}*{}".format(self.cpu_count, self.cpu_cores)
return info
@property @property
def hardware_info(self): def hardware_info(self):
if self.cpu_count: if self.cpu_count:
...@@ -232,35 +267,6 @@ class Asset(OrgModelMixin): ...@@ -232,35 +267,6 @@ class Asset(OrgModelMixin):
fake_node.is_node = False fake_node.is_node = False
return fake_node return fake_node
def to_json(self):
info = {
'id': self.id,
'hostname': self.hostname,
'ip': self.ip,
'port': self.port,
}
if self.domain and self.domain.gateway_set.all():
info["gateways"] = [d.id for d in self.domain.gateway_set.all()]
return info
def _to_secret_json(self):
"""
Ansible use it create inventory
Todo: May be move to ops implements it
"""
data = self.to_json()
if self.admin_user:
self.admin_user.load_specific_asset_auth(self)
admin_user = self.admin_user
data.update({
'username': admin_user.username,
'password': admin_user.password,
'private_key': admin_user.private_key_file,
'become': admin_user.become_info,
'groups': [node.value for node in self.nodes.all()],
})
return data
def as_tree_node(self, parent_node): def as_tree_node(self, parent_node):
from common.tree import TreeNode from common.tree import TreeNode
icon_skin = 'file' icon_skin = 'file'
...@@ -282,9 +288,11 @@ class Asset(OrgModelMixin): ...@@ -282,9 +288,11 @@ class Asset(OrgModelMixin):
'id': self.id, 'id': self.id,
'hostname': self.hostname, 'hostname': self.hostname,
'ip': self.ip, 'ip': self.ip,
'port': self.port, 'protocols': [
{"name": p.name, "port": p.port}
for p in self.protocols.all()
],
'platform': self.platform, 'platform': self.platform,
'protocol': self.protocol,
} }
} }
} }
...@@ -308,10 +316,10 @@ class Asset(OrgModelMixin): ...@@ -308,10 +316,10 @@ class Asset(OrgModelMixin):
asset = cls(ip='.'.join(ip), asset = cls(ip='.'.join(ip),
hostname=forgery_py.internet.user_name(True), hostname=forgery_py.internet.user_name(True),
admin_user=choice(AdminUser.objects.all()), admin_user=choice(AdminUser.objects.all()),
port=22,
created_by='Fake') created_by='Fake')
try: try:
asset.save() asset.save()
asset.protocols.create(name="ssh", port=22)
if nodes and len(nodes) > 3: if nodes and len(nodes) > 3:
_nodes = random.sample(nodes, 3) _nodes = random.sample(nodes, 3)
else: else:
......
...@@ -8,7 +8,6 @@ from django.utils.translation import ugettext_lazy as _ ...@@ -8,7 +8,6 @@ from django.utils.translation import ugettext_lazy as _
from orgs.mixins import OrgResourceSerializerMixin from orgs.mixins import OrgResourceSerializerMixin
from common.mixins import BulkSerializerMixin from common.mixins import BulkSerializerMixin
from common.serializers import AdaptedBulkListSerializer from common.serializers import AdaptedBulkListSerializer
from common.validators import ProjectUniqueValidator
from ..models import Asset, Protocol from ..models import Asset, Protocol
from .system_user import AssetSystemUserSerializer from .system_user import AssetSystemUserSerializer
...@@ -24,7 +23,8 @@ class ProtocolSerializer(serializers.ModelSerializer): ...@@ -24,7 +23,8 @@ class ProtocolSerializer(serializers.ModelSerializer):
fields = ["name", "port"] fields = ["name", "port"]
class AssetSerializer(BulkSerializerMixin, OrgResourceSerializerMixin, serializers.ModelSerializer): class AssetSerializer(BulkSerializerMixin, OrgResourceSerializerMixin,
serializers.ModelSerializer):
protocols = ProtocolSerializer(many=True) protocols = ProtocolSerializer(many=True)
""" """
......
...@@ -31,7 +31,7 @@ def check_asset_can_run_ansible(asset): ...@@ -31,7 +31,7 @@ def check_asset_can_run_ansible(asset):
msg = _("Asset has been disabled, skipped: {}").format(asset) msg = _("Asset has been disabled, skipped: {}").format(asset)
logger.info(msg) logger.info(msg)
return False return False
if not asset.support_ansible(): if not asset.is_support_ansible():
msg = _("Asset may not be support ansible, skipped: {}").format(asset) msg = _("Asset may not be support ansible, skipped: {}").format(asset)
logger.info(msg) logger.info(msg)
return False return False
......
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
<tbody> <tbody>
{% if asset.protocol == 'ssh' %} {% if asset.is_support_ansible %}
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td>{% trans 'Test connective' %}:</td> <td>{% trans 'Test connective' %}:</td>
<td> <td>
...@@ -118,7 +118,7 @@ function initAssetUserTable() { ...@@ -118,7 +118,7 @@ function initAssetUserTable() {
var view_btn = ' <a class="btn btn-xs btn-primary btn-view-auth" data-username="DEFAULT_USERNAME">{% trans "View auth" %}</a>'.replace("DEFAULT_USERNAME", cellData); var view_btn = ' <a class="btn btn-xs btn-primary btn-view-auth" data-username="DEFAULT_USERNAME">{% trans "View auth" %}</a>'.replace("DEFAULT_USERNAME", cellData);
var test_btn = ' <a class="btn btn-xs btn-info btn-test-connective" data-username="DEFAULT_USERNAME">{% trans "Test" %}</a>'.replace("DEFAULT_USERNAME", cellData); var test_btn = ' <a class="btn btn-xs btn-info btn-test-connective" data-username="DEFAULT_USERNAME">{% trans "Test" %}</a>'.replace("DEFAULT_USERNAME", cellData);
btn += view_btn; btn += view_btn;
{% if asset.protocol == 'ssh' %} {% if asset.is_support_ansible %}
btn += test_btn; btn += test_btn;
{% endif %} {% endif %}
$(td).html(btn); $(td).html(btn);
......
...@@ -69,12 +69,13 @@ ...@@ -69,12 +69,13 @@
<td><b>{{ asset.public_ip|default:"" }}</b></td> <td><b>{{ asset.public_ip|default:"" }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Port' %}:</td> <td>{% trans 'Protocol' %}</td>
<td><b>{{ asset.port }}</b></td> <td>
</tr> {% for protocol in asset.protocols.all %}
<tr> <b>{{ protocol.name }}:</b>
<td>{% trans 'Protocol' %}:</td> {{ protocol.port }}
<td><b>{{ asset.protocol }}</b></td> {% endfor %}
</td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Admin user' %}:</td> <td>{% trans 'Admin user' %}:</td>
...@@ -94,7 +95,7 @@ ...@@ -94,7 +95,7 @@
</tr> </tr>
<tr> <tr>
<td>{% trans 'CPU' %}:</td> <td>{% trans 'CPU' %}:</td>
<td><b>{{ asset.cpu_model|default:"" }} {{ asset.cpu_count|default:"" }}*{{ asset.cpu_cores|default:"" }}</b></td> <td><b>{{ asset.cpu_info }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Memory' %}:</td> <td>{% trans 'Memory' %}:</td>
...@@ -166,7 +167,7 @@ ...@@ -166,7 +167,7 @@
</span> </span>
</td> </td>
</tr> </tr>
{% if asset.protocol == 'ssh' %} {% if asset.is_support_ansible %}
<tr> <tr>
<td>{% trans 'Refresh hardware' %}:</td> <td>{% trans 'Refresh hardware' %}:</td>
<td> <td>
......
...@@ -300,10 +300,10 @@ LOGGING = { ...@@ -300,10 +300,10 @@ LOGGING = {
'handlers': ['gunicorn_console', 'gunicorn_file'], 'handlers': ['gunicorn_console', 'gunicorn_file'],
'level': 'INFO', 'level': 'INFO',
}, },
# 'django.db': { 'django.db': {
# 'handlers': ['console', 'file'], 'handlers': ['console', 'file'],
# 'level': 'DEBUG' 'level': 'DEBUG'
# } }
} }
} }
......
...@@ -21,7 +21,7 @@ class JMSBaseInventory(BaseInventory): ...@@ -21,7 +21,7 @@ class JMSBaseInventory(BaseInventory):
'id': asset.id, 'id': asset.id,
'hostname': asset.hostname, 'hostname': asset.hostname,
'ip': asset.ip, 'ip': asset.ip,
'port': asset.port, 'port': asset.protocol_ssh.port,
'vars': dict(), 'vars': dict(),
'groups': [], 'groups': [],
} }
...@@ -73,7 +73,7 @@ class JMSInventory(JMSBaseInventory): ...@@ -73,7 +73,7 @@ class JMSInventory(JMSBaseInventory):
""" """
def __init__(self, assets, run_as_admin=False, run_as=None, become_info=None): def __init__(self, assets, run_as_admin=False, run_as=None, become_info=None):
""" """
:param host_id_list: ["test1", ] :param assets: assets
:param run_as_admin: True 是否使用管理用户去执行, 每台服务器的管理用户可能不同 :param run_as_admin: True 是否使用管理用户去执行, 每台服务器的管理用户可能不同
:param run_as: 用户名(添加了统一的资产用户管理器之后AssetUserManager加上之后修改为username) :param run_as: 用户名(添加了统一的资产用户管理器之后AssetUserManager加上之后修改为username)
:param become_info: 是否become成某个用户去执行 :param become_info: 是否become成某个用户去执行
......
...@@ -134,8 +134,11 @@ function getSelectedAssetsNode() { ...@@ -134,8 +134,11 @@ function getSelectedAssetsNode() {
var assetsNodeId = []; var assetsNodeId = [];
var assetsNode = []; var assetsNode = [];
nodes.forEach(function (node) { nodes.forEach(function (node) {
if (node.meta.type === 'asset' && !node.isHidden && node.meta.asset.protocol === 'ssh') { if (node.meta.type === 'asset' && !node.isHidden) {
if (assetsNodeId.indexOf(node.id) === -1) { var protocols = $.map(node.meta.asset.protocols, function (v) {
return v.name
});
if (assetsNodeId.indexOf(node.id) === -1 && protocols.indexOf("ssh") > -1) {
assetsNodeId.push(node.id); assetsNodeId.push(node.id);
assetsNode.push(node) assetsNode.push(node)
} }
......
...@@ -154,7 +154,7 @@ class UserGrantedAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin, ListAPIV ...@@ -154,7 +154,7 @@ class UserGrantedAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin, ListAPIV
util = AssetPermissionUtil(user, cache_policy=self.cache_policy) util = AssetPermissionUtil(user, cache_policy=self.cache_policy)
assets = util.get_assets() assets = util.get_assets()
for k, v in assets.items(): for k, v in assets.items():
system_users_granted = [s for s in v if s.protocol == k.protocol] system_users_granted = [s for s in v if k.has_protocol(s.protocol)]
k.system_users_granted = system_users_granted k.system_users_granted = system_users_granted
queryset.append(k) queryset.append(k)
return queryset return queryset
...@@ -215,8 +215,7 @@ class UserGrantedNodesWithAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin, ...@@ -215,8 +215,7 @@ class UserGrantedNodesWithAssetsApi(UserPermissionCacheMixin, AssetsFilterMixin,
for node, _assets in nodes.items(): for node, _assets in nodes.items():
assets = _assets.keys() assets = _assets.keys()
for k, v in _assets.items(): for k, v in _assets.items():
system_users_granted = [s for s in v if system_users_granted = [s for s in v if k.has_protocol(s.protocol)]
s.protocol == k.protocol]
k.system_users_granted = system_users_granted k.system_users_granted = system_users_granted
node.assets_granted = assets node.assets_granted = assets
queryset.append(node) queryset.append(node)
...@@ -358,7 +357,7 @@ class UserGrantedNodeChildrenApi(UserPermissionCacheMixin, ListAPIView): ...@@ -358,7 +357,7 @@ class UserGrantedNodeChildrenApi(UserPermissionCacheMixin, ListAPIView):
for asset, system_users in nodes_granted[node].items(): for asset, system_users in nodes_granted[node].items():
fake_node = asset.as_node() fake_node = asset.as_node()
fake_node.assets_amount = 0 fake_node.assets_amount = 0
system_users = [s for s in system_users if s.protocol == asset.protocol] system_users = [s for s in system_users if asset.has_protocol(s.protocol)]
fake_node.asset.system_users_granted = system_users fake_node.asset.system_users_granted = system_users
fake_node.key = node.key + ':0' fake_node.key = node.key + ':0'
fake_nodes.append(fake_node) fake_nodes.append(fake_node)
...@@ -383,7 +382,7 @@ class UserGrantedNodeChildrenApi(UserPermissionCacheMixin, ListAPIView): ...@@ -383,7 +382,7 @@ class UserGrantedNodeChildrenApi(UserPermissionCacheMixin, ListAPIView):
fake_node = asset.as_node() fake_node = asset.as_node()
fake_node.assets_amount = 0 fake_node.assets_amount = 0
system_users = [s for s in system_users if system_users = [s for s in system_users if
s.protocol == asset.protocol] asset.has_protocol(s.protocol)]
fake_node.asset.system_users_granted = system_users fake_node.asset.system_users_granted = system_users
fake_node.key = node.key + ':0' fake_node.key = node.key + ':0'
matched_assets.append(fake_node) matched_assets.append(fake_node)
......
...@@ -182,7 +182,7 @@ class AssetPermissionUtil: ...@@ -182,7 +182,7 @@ class AssetPermissionUtil:
for perm in permissions: for perm in permissions:
for asset in perm.assets.all().valid().prefetch_related('nodes'): for asset in perm.assets.all().valid().prefetch_related('nodes'):
assets[asset].update( assets[asset].update(
perm.system_users.filter(protocol=asset.protocol) perm.system_users.filter(protocol__in=asset.protocols_name)
) )
return assets return assets
...@@ -213,7 +213,7 @@ class AssetPermissionUtil: ...@@ -213,7 +213,7 @@ class AssetPermissionUtil:
_assets = node.get_all_assets().valid().prefetch_related('nodes') _assets = node.get_all_assets().valid().prefetch_related('nodes')
for asset in _assets: for asset in _assets:
assets[asset].update( assets[asset].update(
[s for s in system_users if s.protocol == asset.protocol] [s for s in system_users if asset.has_protocol(s.protocol)]
) )
self._assets = assets self._assets = assets
self._setattr_actions_to_system_user() self._setattr_actions_to_system_user()
...@@ -226,15 +226,12 @@ class AssetPermissionUtil: ...@@ -226,15 +226,12 @@ class AssetPermissionUtil:
resource=resource resource=resource
) )
@property
def node_key(self): def node_key(self):
return self.get_cache_key('NODES_WITH_ASSETS') return self.get_cache_key('NODES_WITH_ASSETS')
@property
def asset_key(self): def asset_key(self):
return self.get_cache_key('ASSETS') return self.get_cache_key('ASSETS')
@property
def system_key(self): def system_key(self):
return self.get_cache_key('SYSTEM_USER') return self.get_cache_key('SYSTEM_USER')
...@@ -265,7 +262,8 @@ class AssetPermissionUtil: ...@@ -265,7 +262,8 @@ class AssetPermissionUtil:
tree = GenerateTree() tree = GenerateTree()
for asset, system_users in assets.items(): for asset, system_users in assets.items():
tree.add_asset(asset, system_users) tree.add_asset(asset, system_users)
return tree.get_nodes() nodes = tree.get_nodes()
return nodes
def get_nodes_with_assets_from_cache(self): def get_nodes_with_assets_from_cache(self):
cached = cache.get(self.node_key) cached = cache.get(self.node_key)
...@@ -405,7 +403,7 @@ def parse_node_to_tree_node(node): ...@@ -405,7 +403,7 @@ def parse_node_to_tree_node(node):
def parse_asset_to_tree_node(node, asset, system_users): def parse_asset_to_tree_node(node, asset, system_users):
system_users_protocol_matched = [s for s in system_users if s.protocol == asset.protocol] system_users_protocol_matched = [s for s in system_users if asset.has_protocol(s.protocol)]
icon_skin = 'file' icon_skin = 'file'
if asset.platform.lower() == 'windows': if asset.platform.lower() == 'windows':
icon_skin = 'windows' icon_skin = 'windows'
...@@ -438,8 +436,8 @@ def parse_asset_to_tree_node(node, asset, system_users): ...@@ -438,8 +436,8 @@ def parse_asset_to_tree_node(node, asset, system_users):
'id': asset.id, 'id': asset.id,
'hostname': asset.hostname, 'hostname': asset.hostname,
'ip': asset.ip, 'ip': asset.ip,
'port': asset.port, 'protocols': [{"name": p.name, "port": p.port}
'protocol': asset.protocol, for p in asset.protocols.all()],
'platform': asset.platform, 'platform': asset.platform,
'domain': None if not asset.domain else asset.domain.id, 'domain': None if not asset.domain else asset.domain.id,
'is_active': asset.is_active, 'is_active': asset.is_active,
......
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