mirror of https://github.com/jumpserver/jumpserver
perf: 修改 host info
parent
b7075b5378
commit
5358f35c08
|
@ -12,12 +12,6 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
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(
|
||||
name='DeviceInfo',
|
||||
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_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')),
|
||||
('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')),
|
||||
],
|
||||
options={
|
||||
'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
|
||||
|
||||
hardware_infos = []
|
||||
hosts_updated = []
|
||||
for host in hosts:
|
||||
hardware = hardware_model()
|
||||
asset = asset_mapper[host.asset_ptr_id]
|
||||
hardware.host = host
|
||||
hardware.date_updated = timezone.now()
|
||||
for name in fields:
|
||||
setattr(hardware, name, getattr(asset, name))
|
||||
hardware_infos.append(hardware)
|
||||
host.device_info_id = hardware.id
|
||||
hosts_updated.append(host)
|
||||
|
||||
hardware_model.objects.bulk_create(hardware_infos, ignore_conflicts=True)
|
||||
host_model.objects.bulk_update(hosts_updated, ['device_info_id'])
|
||||
created += len(hardware_infos)
|
||||
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@ from .common import Asset
|
|||
|
||||
|
||||
class Host(Asset):
|
||||
device_info = models.OneToOneField('DeviceInfo', null=True, on_delete=models.SET_NULL, verbose_name=_("Host"))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.category = Category.HOST
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class DeviceInfo(CommonModelMixin):
|
||||
host = models.ForeignKey(Host, on_delete=models.CASCADE, verbose_name=_("Host"))
|
||||
# Collect
|
||||
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'))
|
||||
|
|
|
@ -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 ..const import Category, AllTypes
|
||||
|
||||
|
||||
__all__ = ['PlatformSerializer']
|
||||
|
||||
|
||||
|
@ -20,6 +21,10 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
|||
category = ChoiceDisplayField(choices=Category.choices, label=_("Category"))
|
||||
protocols = PlatformProtocolsSerializer(label=_('Protocols'), many=True, required=False)
|
||||
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:
|
||||
model = Platform
|
||||
|
@ -41,5 +46,14 @@ class PlatformSerializer(JMSWritableNestedModelSerializer):
|
|||
read_only_fields = [
|
||||
'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