mirror of https://github.com/jumpserver/jumpserver
perf: 修改 host info
parent
b7075b5378
commit
5358f35c08
|
@ -12,12 +12,6 @@ class Migration(migrations.Migration):
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
|
||||||
name='Host',
|
|
||||||
fields=[
|
|
||||||
('asset_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='assets.asset')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='DeviceInfo',
|
name='DeviceInfo',
|
||||||
fields=[
|
fields=[
|
||||||
|
@ -39,11 +33,17 @@ class Migration(migrations.Migration):
|
||||||
('os_version', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS version')),
|
('os_version', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS version')),
|
||||||
('os_arch', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS arch')),
|
('os_arch', models.CharField(blank=True, max_length=16, null=True, verbose_name='OS arch')),
|
||||||
('hostname_raw', models.CharField(blank=True, max_length=128, null=True, verbose_name='Hostname raw')),
|
('hostname_raw', models.CharField(blank=True, max_length=128, null=True, verbose_name='Hostname raw')),
|
||||||
('host', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.host', verbose_name='Host')),
|
|
||||||
('number', models.CharField(blank=True, max_length=128, null=True, verbose_name='Asset number')),
|
('number', models.CharField(blank=True, max_length=128, null=True, verbose_name='Asset number')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'DeviceInfo',
|
'verbose_name': 'DeviceInfo',
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Host',
|
||||||
|
fields=[
|
||||||
|
('asset_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='assets.asset')),
|
||||||
|
('device_info', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.deviceinfo', verbose_name='Host')),
|
||||||
|
],
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,16 +28,19 @@ def migrate_hardware(apps, *args):
|
||||||
break
|
break
|
||||||
|
|
||||||
hardware_infos = []
|
hardware_infos = []
|
||||||
|
hosts_updated = []
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
hardware = hardware_model()
|
hardware = hardware_model()
|
||||||
asset = asset_mapper[host.asset_ptr_id]
|
asset = asset_mapper[host.asset_ptr_id]
|
||||||
hardware.host = host
|
|
||||||
hardware.date_updated = timezone.now()
|
hardware.date_updated = timezone.now()
|
||||||
for name in fields:
|
for name in fields:
|
||||||
setattr(hardware, name, getattr(asset, name))
|
setattr(hardware, name, getattr(asset, name))
|
||||||
hardware_infos.append(hardware)
|
hardware_infos.append(hardware)
|
||||||
|
host.device_info_id = hardware.id
|
||||||
|
hosts_updated.append(host)
|
||||||
|
|
||||||
hardware_model.objects.bulk_create(hardware_infos, ignore_conflicts=True)
|
hardware_model.objects.bulk_create(hardware_infos, ignore_conflicts=True)
|
||||||
|
host_model.objects.bulk_update(hosts_updated, ['device_info_id'])
|
||||||
created += len(hardware_infos)
|
created += len(hardware_infos)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,14 @@ from .common import Asset
|
||||||
|
|
||||||
|
|
||||||
class Host(Asset):
|
class Host(Asset):
|
||||||
|
device_info = models.OneToOneField('DeviceInfo', null=True, on_delete=models.SET_NULL, verbose_name=_("Host"))
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
self.category = Category.HOST
|
self.category = Category.HOST
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class DeviceInfo(CommonModelMixin):
|
class DeviceInfo(CommonModelMixin):
|
||||||
host = models.ForeignKey(Host, on_delete=models.CASCADE, verbose_name=_("Host"))
|
|
||||||
# Collect
|
# Collect
|
||||||
vendor = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Vendor'))
|
vendor = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Vendor'))
|
||||||
model = models.CharField(max_length=54, null=True, blank=True, verbose_name=_('Model'))
|
model = models.CharField(max_length=54, null=True, blank=True, verbose_name=_('Model'))
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
platform_ops_methods = []
|
||||||
|
|
||||||
|
|
||||||
|
def get_platform_methods():
|
||||||
|
methods = []
|
||||||
|
for root, dirs, files in os.walk(BASE_DIR, topdown=False):
|
||||||
|
for name in dirs:
|
||||||
|
path = os.path.join(root, name)
|
||||||
|
rel_path = path.replace(BASE_DIR, '.')
|
||||||
|
if len(rel_path.split('/')) != 4:
|
||||||
|
continue
|
||||||
|
manifest_path = os.path.join(path, 'manifest.yml')
|
||||||
|
if not os.path.exists(manifest_path):
|
||||||
|
print("Path not exists: {}".format(manifest_path))
|
||||||
|
continue
|
||||||
|
f = open(manifest_path, 'r')
|
||||||
|
try:
|
||||||
|
manifest = yaml.safe_load(f)
|
||||||
|
except yaml.YAMLError as e:
|
||||||
|
print(e)
|
||||||
|
continue
|
||||||
|
current, category, tp, name = rel_path.split('/')
|
||||||
|
manifest.update({
|
||||||
|
'id': name,
|
||||||
|
'category': category,
|
||||||
|
'type': tp,
|
||||||
|
})
|
||||||
|
methods.append(manifest)
|
||||||
|
return methods
|
||||||
|
|
||||||
|
|
||||||
|
def get_platform_method(platform, method):
|
||||||
|
methods = get_platform_methods()
|
||||||
|
|
||||||
|
def key(m):
|
||||||
|
return m.get('method') == method \
|
||||||
|
and m['category'] == platform.category \
|
||||||
|
and m['type'] == platform.type
|
||||||
|
return list(filter(key, methods))
|
|
@ -0,0 +1,10 @@
|
||||||
|
{% for account in accounts %}
|
||||||
|
- hosts: {{ account.asset.name }}
|
||||||
|
vars:
|
||||||
|
account:
|
||||||
|
username: {{ account.username }}
|
||||||
|
password: {{ account.password }}
|
||||||
|
public_key: {{ account.public_key }}
|
||||||
|
roles:
|
||||||
|
- change_password
|
||||||
|
{% endfor %}
|
|
@ -0,0 +1,10 @@
|
||||||
|
name: Change password using ansible
|
||||||
|
version: 1
|
||||||
|
description: 使用特权账号更改账号的密码
|
||||||
|
author: ibuler
|
||||||
|
method: change_password
|
||||||
|
vars:
|
||||||
|
account:
|
||||||
|
username: test
|
||||||
|
password: teset123
|
||||||
|
public_key: test
|
|
@ -0,0 +1,27 @@
|
||||||
|
- name: ping
|
||||||
|
ping:
|
||||||
|
|
||||||
|
#- name: print variables
|
||||||
|
# debug:
|
||||||
|
# msg: "Username: {{ account.username }}, Password: {{ account.password }}"
|
||||||
|
|
||||||
|
- name: Change password
|
||||||
|
user:
|
||||||
|
name: "{{ account.username }}"
|
||||||
|
password: "{{ account.password | password_hash('sha512') }}"
|
||||||
|
update_password: always
|
||||||
|
when: account.password
|
||||||
|
|
||||||
|
- name: Change public key
|
||||||
|
authorized_key:
|
||||||
|
user: "{{ account.username }}"
|
||||||
|
key: "{{ account.public_key }}"
|
||||||
|
state: present
|
||||||
|
when: account.public_key
|
||||||
|
|
||||||
|
- name: Verify password
|
||||||
|
ping:
|
||||||
|
vars:
|
||||||
|
ansible_user: "{{ account.username }}"
|
||||||
|
ansible_pass: "{{ account.password }}"
|
||||||
|
ansible_ssh_connection: paramiko
|
|
@ -0,0 +1,15 @@
|
||||||
|
- hosts: centos
|
||||||
|
gather_facts: no
|
||||||
|
vars:
|
||||||
|
account:
|
||||||
|
username: web
|
||||||
|
password: test123
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Verify password
|
||||||
|
ping:
|
||||||
|
vars:
|
||||||
|
ansible_ssh_user: "{{ account.username }}"
|
||||||
|
ansible_ssh_pass: "{{ account.password }}"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
name: Create account by ansible
|
||||||
|
version: 1
|
||||||
|
description: 使用特权账号更改账号的密码
|
||||||
|
author: ibuler
|
||||||
|
method: create_account
|
|
@ -0,0 +1,15 @@
|
||||||
|
- hosts: centos
|
||||||
|
gather_facts: no
|
||||||
|
vars:
|
||||||
|
account:
|
||||||
|
username: web
|
||||||
|
password: test123
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Verify password
|
||||||
|
ping:
|
||||||
|
vars:
|
||||||
|
ansible_user: "{{ account.username }}"
|
||||||
|
ansible_pass: "{{ account.password }}"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
name: Change password using ansible
|
||||||
|
version: 1
|
||||||
|
description: 使用特权账号更改账号的密码
|
||||||
|
author: ibuler
|
|
@ -6,6 +6,7 @@ from common.drf.serializers import JMSWritableNestedModelSerializer
|
||||||
from ..models import Platform, PlatformProtocol
|
from ..models import Platform, PlatformProtocol
|
||||||
from ..const import Category, AllTypes
|
from ..const import Category, AllTypes
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['PlatformSerializer']
|
__all__ = ['PlatformSerializer']
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +21,10 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
||||||
category = ChoiceDisplayField(choices=Category.choices, label=_("Category"))
|
category = ChoiceDisplayField(choices=Category.choices, label=_("Category"))
|
||||||
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
|
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
|
||||||
type_constraints = serializers.ReadOnlyField(required=False, read_only=True)
|
type_constraints = serializers.ReadOnlyField(required=False, read_only=True)
|
||||||
|
su_method = ChoiceDisplayField(
|
||||||
|
choices=[('sudo', 'sudo su -'), ('su', 'su - ')],
|
||||||
|
label='切换方式', required=False, default='sudo'
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Platform
|
model = Platform
|
||||||
|
@ -41,5 +46,14 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
||||||
read_only_fields = [
|
read_only_fields = [
|
||||||
'category_display', 'type_display',
|
'category_display', 'type_display',
|
||||||
]
|
]
|
||||||
|
extra_kwargs = {
|
||||||
|
'su_enabled': {'label': '启用切换账号'},
|
||||||
|
'verify_account_enabled': {'label': '启用校验账号'},
|
||||||
|
'verify_account_method': {'label': '校验账号方式'},
|
||||||
|
'create_account_enabled': {'label': '启用创建账号'},
|
||||||
|
'create_account_method': {'label': '创建账号方式'},
|
||||||
|
'change_password_enabled': {'label': '启用账号改密'},
|
||||||
|
'change_password_method': {'label': '账号改密方式'},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue