mirror of https://github.com/jumpserver/jumpserver
perf: 优化迁移文件
parent
a35e0c5efa
commit
8f31a25fda
|
@ -137,8 +137,8 @@ class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
||||||
def get_type_default_platform(cls, category, tp):
|
def get_type_default_platform(cls, category, tp):
|
||||||
constraints = cls.get_constraints(category, tp)
|
constraints = cls.get_constraints(category, tp)
|
||||||
data = {
|
data = {
|
||||||
'name': tp.label, 'category': category.value,
|
'category': category,
|
||||||
'type': tp.value, 'internal': True,
|
'type': tp, 'internal': True,
|
||||||
'charset': constraints.get('charset', 'utf-8'),
|
'charset': constraints.get('charset', 'utf-8'),
|
||||||
'domain_enabled': constraints.get('domain_enabled', False),
|
'domain_enabled': constraints.get('domain_enabled', False),
|
||||||
'su_enabled': constraints.get('su_enabled', False),
|
'su_enabled': constraints.get('su_enabled', False),
|
||||||
|
@ -162,8 +162,30 @@ class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_or_update_internal_platforms(cls):
|
def create_or_update_by_platform_data(cls, name, platform_data):
|
||||||
from assets.models import Platform, PlatformAutomation, PlatformProtocol
|
from assets.models import Platform, PlatformAutomation, PlatformProtocol
|
||||||
|
|
||||||
|
automation_data = platform_data.pop('automation', {})
|
||||||
|
protocols_data = platform_data.pop('protocols', [])
|
||||||
|
|
||||||
|
platform, created = Platform.objects.update_or_create(
|
||||||
|
defaults=platform_data, name=name
|
||||||
|
)
|
||||||
|
if not platform.automation:
|
||||||
|
automation = PlatformAutomation.objects.create()
|
||||||
|
platform.automation = automation
|
||||||
|
platform.save()
|
||||||
|
else:
|
||||||
|
automation = platform.automation
|
||||||
|
for k, v in automation_data.items():
|
||||||
|
setattr(automation, k, v)
|
||||||
|
automation.save()
|
||||||
|
|
||||||
|
platform.protocols.all().delete()
|
||||||
|
[PlatformProtocol.objects.create(**p, platform=platform) for p in protocols_data]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_or_update_internal_platforms(cls):
|
||||||
print("Create internal platforms")
|
print("Create internal platforms")
|
||||||
for category, type_cls in cls.category_types():
|
for category, type_cls in cls.category_types():
|
||||||
print("## Category: {}".format(category.label))
|
print("## Category: {}".format(category.label))
|
||||||
|
@ -188,22 +210,31 @@ class AllTypes(ChoicesMixin, metaclass=IncludesTextChoicesMeta):
|
||||||
for p in protocols_data:
|
for p in protocols_data:
|
||||||
p['setting'] = {**_protocols_setting.get(p['name'], {}), **p.get('setting', {})}
|
p['setting'] = {**_protocols_setting.get(p['name'], {}), **p.get('setting', {})}
|
||||||
|
|
||||||
platform_data = {**default_platform_data, **d}
|
platform_data = {
|
||||||
automation_data = {**default_automation, **_automation}
|
**default_platform_data, **d,
|
||||||
platform, created = Platform.objects.update_or_create(
|
'automation': {**default_automation, **_automation},
|
||||||
defaults=platform_data, name=platform_data['name']
|
'protocols': protocols_data
|
||||||
)
|
}
|
||||||
|
cls.create_or_update_by_platform_data(name, platform_data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update_user_create_platforms(cls, platform_cls):
|
||||||
|
internal_platforms = []
|
||||||
|
for category, type_cls in cls.category_types():
|
||||||
|
data = type_cls.internal_platforms()
|
||||||
|
for tp, platform_datas in data.items():
|
||||||
|
for d in platform_datas:
|
||||||
|
internal_platforms.append(d['name'])
|
||||||
|
|
||||||
|
user_platforms = platform_cls.objects.exclude(name__in=internal_platforms)
|
||||||
|
user_platforms.update(internal=False)
|
||||||
|
|
||||||
|
for platform in user_platforms:
|
||||||
|
print("Update platform: {}".format(platform.name))
|
||||||
|
platform_data = cls.get_type_default_platform(platform.category, platform.type)
|
||||||
|
cls.create_or_update_by_platform_data(platform.name, platform_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not platform.automation:
|
|
||||||
automation = PlatformAutomation.objects.create()
|
|
||||||
platform.automation = automation
|
|
||||||
platform.save()
|
|
||||||
else:
|
|
||||||
automation = platform.automation
|
|
||||||
for k, v in automation_data.items():
|
|
||||||
setattr(automation, k, v)
|
|
||||||
automation.save()
|
|
||||||
|
|
||||||
platform.protocols.all().delete()
|
|
||||||
[PlatformProtocol.objects.create(**p, platform=platform) for p in protocols_data]
|
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,89 @@ class Migration(migrations.Migration):
|
||||||
name='info',
|
name='info',
|
||||||
field=models.JSONField(blank=True, default=dict, verbose_name='Info'),
|
field=models.JSONField(blank=True, default=dict, verbose_name='Info'),
|
||||||
),
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='asset',
|
||||||
|
old_name='hostname',
|
||||||
|
new_name='name',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='asset',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=128, verbose_name='Name'),
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='asset',
|
||||||
|
options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetsystemuser', 'Can push system user to asset'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node')], 'verbose_name': 'Asset'},
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='asset',
|
||||||
|
old_name='ip',
|
||||||
|
new_name='address',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='date_updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='updated_by',
|
||||||
|
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='asset',
|
||||||
|
name='created_by',
|
||||||
|
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by'),
|
||||||
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Host',
|
name='Host',
|
||||||
fields=[
|
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')),
|
('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='Database',
|
||||||
|
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')),
|
||||||
|
('db_name', models.CharField(blank=True, max_length=1024, verbose_name='Database')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Database',
|
||||||
|
},
|
||||||
|
bases=('assets.asset',),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Device',
|
||||||
|
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')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
bases=('assets.asset',),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Cloud',
|
||||||
|
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')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
bases=('assets.asset',),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Web',
|
||||||
|
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')),
|
||||||
|
('autofill', models.CharField(default='basic', max_length=16)),
|
||||||
|
('password_selector', models.CharField(blank=True, default='', max_length=128)),
|
||||||
|
('submit_selector', models.CharField(blank=True, default='', max_length=128)),
|
||||||
|
('username_selector', models.CharField(blank=True, default='', max_length=128))
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
bases=('assets.asset',),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -66,7 +66,4 @@ class Migration(migrations.Migration):
|
||||||
model_name='asset',
|
model_name='asset',
|
||||||
name='vendor',
|
name='vendor',
|
||||||
),
|
),
|
||||||
migrations.DeleteModel(
|
|
||||||
name='Cluster',
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -33,5 +33,25 @@ class Migration(migrations.Migration):
|
||||||
name='type',
|
name='type',
|
||||||
field=models.CharField(default='linux', max_length=32, verbose_name='Type'),
|
field=models.CharField(default='linux', max_length=32, verbose_name='Type'),
|
||||||
),
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='platform',
|
||||||
|
name='domain_enabled',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='Domain enabled'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='platform',
|
||||||
|
name='protocols_enabled',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='Protocols enabled'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='platform',
|
||||||
|
name='su_enabled',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Su enabled'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='platform',
|
||||||
|
name='su_method',
|
||||||
|
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='SU method'),
|
||||||
|
),
|
||||||
migrations.RunPython(migrate_platform_type_to_lower)
|
migrations.RunPython(migrate_platform_type_to_lower)
|
||||||
]
|
]
|
||||||
|
|
|
@ -12,48 +12,36 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Database',
|
name='PlatformProtocol',
|
||||||
fields=[
|
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')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('db_name', models.CharField(blank=True, max_length=1024, verbose_name='Database')),
|
('name', models.CharField(max_length=32, verbose_name='Name')),
|
||||||
|
('port', models.IntegerField(verbose_name='Port')),
|
||||||
|
('setting', models.JSONField(default=dict, verbose_name='Setting')),
|
||||||
|
('platform', models.ForeignKey(on_delete=models.deletion.CASCADE, related_name='protocols', to='assets.platform'),),
|
||||||
],
|
],
|
||||||
options={
|
|
||||||
'verbose_name': 'Database',
|
|
||||||
},
|
|
||||||
bases=('assets.asset',),
|
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Device',
|
name='PlatformAutomation',
|
||||||
fields=[
|
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')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('ping_enabled', models.BooleanField(default=False, verbose_name='Ping enabled')),
|
||||||
|
('ping_method', models.CharField(blank=True, max_length=32, null=True, verbose_name='Ping method')),
|
||||||
|
('gather_facts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
|
||||||
|
('gather_facts_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Gather facts method')),
|
||||||
|
('create_account_enabled', models.BooleanField(default=False, verbose_name='Create account enabled')),
|
||||||
|
('create_account_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Create account method')),
|
||||||
|
('change_password_enabled', models.BooleanField(default=False, verbose_name='Change password enabled')),
|
||||||
|
('change_password_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Change password method')),
|
||||||
|
('verify_account_enabled', models.BooleanField(default=False, verbose_name='Verify account enabled')),
|
||||||
|
('verify_account_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Verify account method')),
|
||||||
|
('gather_accounts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
|
||||||
|
('gather_accounts_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Gather facts method')),
|
||||||
],
|
],
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
bases=('assets.asset',),
|
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.AddField(
|
||||||
name='Cloud',
|
model_name='platform',
|
||||||
fields=[
|
name='automation',
|
||||||
('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')),
|
field=models.OneToOneField(blank=True, null=True, on_delete=models.deletion.CASCADE, related_name='platform', to='assets.platformautomation', verbose_name='Automation'),
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
bases=('assets.asset',),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Web',
|
|
||||||
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')),
|
|
||||||
('autofill', models.CharField(default='basic', max_length=16)),
|
|
||||||
('password_selector', models.CharField(blank=True, default='', max_length=128)),
|
|
||||||
('submit_selector', models.CharField(blank=True, default='', max_length=128)),
|
|
||||||
('username_selector', models.CharField(blank=True, default='', max_length=128))
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'abstract': False,
|
|
||||||
},
|
|
||||||
bases=('assets.asset',),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,159 +1,24 @@
|
||||||
# Generated by Django 3.1.14 on 2022-04-26 07:58
|
# Generated by Django 3.1.14 on 2022-04-26 07:58
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
from assets.const import AllTypes
|
||||||
failed_apps = []
|
|
||||||
|
|
||||||
|
|
||||||
def create_app_platform(apps, *args):
|
def create_internal_platforms(apps, *args):
|
||||||
platform_model = apps.get_model('assets', 'Platform')
|
AllTypes.create_or_update_internal_platforms()
|
||||||
platforms = [
|
|
||||||
# DB
|
|
||||||
{'name': 'MySQL', 'category': 'database', 'type': 'mysql'},
|
|
||||||
{'name': 'MariaDB', 'category': 'database', 'type': 'mariadb'},
|
|
||||||
{'name': 'PostgreSQL', 'category': 'database', 'type': 'postgresql'},
|
|
||||||
{'name': 'Oracle', 'category': 'database', 'type': 'oracle'},
|
|
||||||
{'name': 'SQLServer', 'category': 'database', 'type': 'sqlserver'},
|
|
||||||
{'name': 'MongoDB', 'category': 'database', 'type': 'mongodb'},
|
|
||||||
{'name': 'Redis', 'category': 'database', 'type': 'redis'},
|
|
||||||
{'name': 'Kubernetes', 'category': 'cloud', 'type': 'k8s'},
|
|
||||||
{'name': 'Web', 'category': 'web', 'type': 'general'},
|
|
||||||
]
|
|
||||||
|
|
||||||
for platform in platforms:
|
|
||||||
platform['internal'] = True
|
|
||||||
print("Create platform: {}".format(platform['name']))
|
|
||||||
platform_model.objects.update_or_create(defaults=platform, name=platform['name'])
|
|
||||||
|
|
||||||
|
|
||||||
def get_prop_name_id(apps, app, category):
|
def update_user_platforms(apps, *args):
|
||||||
asset_model = apps.get_model('assets', 'Asset')
|
platform_cls = apps.get_model('assets', 'Platform')
|
||||||
_id = app.id
|
AllTypes.update_user_create_platforms(platform_cls)
|
||||||
id_exists = asset_model.objects.filter(id=_id).exists()
|
|
||||||
if id_exists:
|
|
||||||
_id = uuid.uuid4()
|
|
||||||
name = app.name
|
|
||||||
name_exists = asset_model.objects.filter(hostname=name).exists()
|
|
||||||
if name_exists:
|
|
||||||
name = category + '-' + app.name
|
|
||||||
return _id, name
|
|
||||||
|
|
||||||
|
|
||||||
def migrate_database_to_asset(apps, *args):
|
|
||||||
app_model = apps.get_model('applications', 'Application')
|
|
||||||
db_model = apps.get_model('assets', 'Database')
|
|
||||||
platform_model = apps.get_model('assets', 'Platform')
|
|
||||||
|
|
||||||
applications = app_model.objects.filter(category='db')
|
|
||||||
platforms = platform_model.objects.all()
|
|
||||||
platforms_map = {p.type: p for p in platforms}
|
|
||||||
|
|
||||||
for app in applications:
|
|
||||||
attrs = {'host': '', 'port': 0, 'database': ''}
|
|
||||||
_attrs = app.attrs or {}
|
|
||||||
attrs.update(_attrs)
|
|
||||||
|
|
||||||
db = db_model(
|
|
||||||
id=app.id, hostname=app.name, ip=attrs['host'],
|
|
||||||
protocols='{}/{}'.format(app.type, attrs['port']),
|
|
||||||
db_name=attrs['database'] or '',
|
|
||||||
platform=platforms_map[app.type],
|
|
||||||
org_id=app.org_id
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
print("Create database: ", app.name)
|
|
||||||
db.save()
|
|
||||||
except:
|
|
||||||
failed_apps.append(app)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def migrate_cloud_to_asset(apps, *args):
|
|
||||||
app_model = apps.get_model('applications', 'Application')
|
|
||||||
cloud_model = apps.get_model('assets', 'Cloud')
|
|
||||||
platform_model = apps.get_model('assets', 'Platform')
|
|
||||||
|
|
||||||
applications = app_model.objects.filter(category='cloud')
|
|
||||||
platform = platform_model.objects.filter(type='k8s').first()
|
|
||||||
print()
|
|
||||||
|
|
||||||
for app in applications:
|
|
||||||
attrs = app.attrs
|
|
||||||
print("Create cloud: {}".format(app.name))
|
|
||||||
cloud = cloud_model(
|
|
||||||
id=app.id, hostname=app.name,
|
|
||||||
ip=attrs.get('cluster', ''),
|
|
||||||
protocols='', platform=platform,
|
|
||||||
org_id=app.org_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
cloud.save()
|
|
||||||
except Exception as e:
|
|
||||||
failed_apps.append(cloud)
|
|
||||||
print("Error: ", e)
|
|
||||||
|
|
||||||
|
|
||||||
def create_app_nodes(apps, org_id):
|
|
||||||
node_model = apps.get_model('assets', 'Node')
|
|
||||||
|
|
||||||
child_pattern = r'^[0-9]+:[0-9]+$'
|
|
||||||
node_keys = node_model.objects.filter(org_id=org_id) \
|
|
||||||
.filter(key__regex=child_pattern) \
|
|
||||||
.values_list('key', flat=True)
|
|
||||||
if not node_keys:
|
|
||||||
return
|
|
||||||
node_key_split = [key.split(':') for key in node_keys]
|
|
||||||
next_value = max([int(k[1]) for k in node_key_split]) + 1
|
|
||||||
parent_key = node_key_split[0][0]
|
|
||||||
next_key = '{}:{}'.format(parent_key, next_value)
|
|
||||||
name = 'Apps'
|
|
||||||
parent = node_model.objects.get(key=parent_key)
|
|
||||||
full_value = parent.full_value + '/' + name
|
|
||||||
defaults = {
|
|
||||||
'key': next_key, 'value': name, 'parent_key': parent_key,
|
|
||||||
'full_value': full_value, 'org_id': org_id
|
|
||||||
}
|
|
||||||
node, created = node_model.objects.get_or_create(
|
|
||||||
defaults=defaults, value=name, org_id=org_id,
|
|
||||||
)
|
|
||||||
node.parent = parent
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def migrate_to_nodes(apps, *args):
|
|
||||||
org_model = apps.get_model('orgs', 'Organization')
|
|
||||||
asset_model = apps.get_model('assets', 'Asset')
|
|
||||||
orgs = org_model.objects.all()
|
|
||||||
|
|
||||||
# Todo: 优化一些
|
|
||||||
for org in orgs:
|
|
||||||
node = create_app_nodes(apps, org.id)
|
|
||||||
assets = asset_model.objects.filter(
|
|
||||||
platform__category__in=['remote_app', 'database', 'cloud'],
|
|
||||||
org_id=org.id
|
|
||||||
)
|
|
||||||
if not node:
|
|
||||||
continue
|
|
||||||
print("Set node asset: ", node)
|
|
||||||
node.assets_amount = len(assets)
|
|
||||||
node.save()
|
|
||||||
node.assets.set(assets)
|
|
||||||
parent = node.parent
|
|
||||||
parent.assets_amount += len(assets)
|
|
||||||
parent.save()
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('assets', '0096_auto_20220426_1550'),
|
('assets', '0096_auto_20220426_1550'),
|
||||||
('applications', '0020_auto_20220316_2028')
|
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RunPython(create_app_platform),
|
migrations.RunPython(create_internal_platforms),
|
||||||
migrations.RunPython(migrate_database_to_asset),
|
migrations.RunPython(update_user_platforms),
|
||||||
migrations.RunPython(migrate_cloud_to_asset),
|
|
||||||
migrations.RunPython(migrate_to_nodes)
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,65 +1,137 @@
|
||||||
# Generated by Django 3.1.14 on 2022-04-30 14:41
|
# Generated by Django 3.1.14 on 2022-04-26 07:58
|
||||||
from django.db import migrations, models
|
import uuid
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
failed_apps = []
|
||||||
|
|
||||||
|
|
||||||
|
def get_prop_name_id(apps, app, category):
|
||||||
|
asset_model = apps.get_model('assets', 'Asset')
|
||||||
|
_id = app.id
|
||||||
|
id_exists = asset_model.objects.filter(id=_id).exists()
|
||||||
|
if id_exists:
|
||||||
|
_id = uuid.uuid4()
|
||||||
|
name = app.name
|
||||||
|
name_exists = asset_model.objects.filter(name=name).exists()
|
||||||
|
if name_exists:
|
||||||
|
name = category + '-' + app.name
|
||||||
|
return _id, name
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_database_to_asset(apps, *args):
|
||||||
|
app_model = apps.get_model('applications', 'Application')
|
||||||
|
db_model = apps.get_model('assets', 'Database')
|
||||||
|
platform_model = apps.get_model('assets', 'Platform')
|
||||||
|
|
||||||
|
applications = app_model.objects.filter(category='db')
|
||||||
|
platforms = platform_model.objects.all().filter(internal=True)
|
||||||
|
platforms_map = {p.type: p for p in platforms}
|
||||||
|
|
||||||
|
for app in applications:
|
||||||
|
attrs = {'host': '', 'port': 0, 'database': ''}
|
||||||
|
_attrs = app.attrs or {}
|
||||||
|
attrs.update(_attrs)
|
||||||
|
|
||||||
|
db = db_model(
|
||||||
|
id=app.id, name=app.name, address=attrs['host'],
|
||||||
|
protocols='{}/{}'.format(app.type, attrs['port']),
|
||||||
|
db_name=attrs['database'] or '',
|
||||||
|
platform=platforms_map[app.type],
|
||||||
|
org_id=app.org_id
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
print("Create database: ", app.name)
|
||||||
|
db.save()
|
||||||
|
except:
|
||||||
|
failed_apps.append(app)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_cloud_to_asset(apps, *args):
|
||||||
|
app_model = apps.get_model('applications', 'Application')
|
||||||
|
cloud_model = apps.get_model('assets', 'Cloud')
|
||||||
|
platform_model = apps.get_model('assets', 'Platform')
|
||||||
|
|
||||||
|
applications = app_model.objects.filter(category='cloud')
|
||||||
|
platform = platform_model.objects.filter(type='k8s').first()
|
||||||
|
print()
|
||||||
|
|
||||||
|
for app in applications:
|
||||||
|
attrs = app.attrs
|
||||||
|
print("Create cloud: {}".format(app.name))
|
||||||
|
cloud = cloud_model(
|
||||||
|
id=app.id, name=app.name,
|
||||||
|
address=attrs.get('cluster', ''),
|
||||||
|
protocols='', platform=platform,
|
||||||
|
org_id=app.org_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cloud.save()
|
||||||
|
except Exception as e:
|
||||||
|
failed_apps.append(cloud)
|
||||||
|
print("Error: ", e)
|
||||||
|
|
||||||
|
|
||||||
|
def create_app_nodes(apps, org_id):
|
||||||
|
node_model = apps.get_model('assets', 'Node')
|
||||||
|
|
||||||
|
child_pattern = r'^[0-9]+:[0-9]+$'
|
||||||
|
node_keys = node_model.objects.filter(org_id=org_id) \
|
||||||
|
.filter(key__regex=child_pattern) \
|
||||||
|
.values_list('key', flat=True)
|
||||||
|
if not node_keys:
|
||||||
|
return
|
||||||
|
node_key_split = [key.split(':') for key in node_keys]
|
||||||
|
next_value = max([int(k[1]) for k in node_key_split]) + 1
|
||||||
|
parent_key = node_key_split[0][0]
|
||||||
|
next_key = '{}:{}'.format(parent_key, next_value)
|
||||||
|
name = 'Apps'
|
||||||
|
parent = node_model.objects.get(key=parent_key)
|
||||||
|
full_value = parent.full_value + '/' + name
|
||||||
|
defaults = {
|
||||||
|
'key': next_key, 'value': name, 'parent_key': parent_key,
|
||||||
|
'full_value': full_value, 'org_id': org_id
|
||||||
|
}
|
||||||
|
node, created = node_model.objects.get_or_create(
|
||||||
|
defaults=defaults, value=name, org_id=org_id,
|
||||||
|
)
|
||||||
|
node.parent = parent
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_to_nodes(apps, *args):
|
||||||
|
org_model = apps.get_model('orgs', 'Organization')
|
||||||
|
asset_model = apps.get_model('assets', 'Asset')
|
||||||
|
orgs = org_model.objects.all()
|
||||||
|
|
||||||
|
# Todo: 优化一些
|
||||||
|
for org in orgs:
|
||||||
|
node = create_app_nodes(apps, org.id)
|
||||||
|
assets = asset_model.objects.filter(
|
||||||
|
platform__category__in=['remote_app', 'database', 'cloud'],
|
||||||
|
org_id=org.id
|
||||||
|
)
|
||||||
|
if not node:
|
||||||
|
continue
|
||||||
|
print("Set node asset: ", node)
|
||||||
|
node.assets_amount = len(assets)
|
||||||
|
node.save()
|
||||||
|
node.assets.set(assets)
|
||||||
|
parent = node.parent
|
||||||
|
parent.assets_amount += len(assets)
|
||||||
|
parent.save()
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('assets', '0097_auto_20220426_1558'),
|
('assets', '0097_auto_20220426_1558'),
|
||||||
|
('applications', '0020_auto_20220316_2028')
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.RunPython(migrate_database_to_asset),
|
||||||
name='PlatformProtocol',
|
migrations.RunPython(migrate_cloud_to_asset),
|
||||||
fields=[
|
migrations.RunPython(migrate_to_nodes)
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.CharField(max_length=32, verbose_name='Name')),
|
|
||||||
('port', models.IntegerField(verbose_name='Port')),
|
|
||||||
('setting', models.JSONField(default=dict, verbose_name='Setting')),
|
|
||||||
('platform', models.ForeignKey(on_delete=models.deletion.CASCADE, related_name='protocols', to='assets.platform'),),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='PlatformAutomation',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('ping_enabled', models.BooleanField(default=False, verbose_name='Ping enabled')),
|
|
||||||
('ping_method', models.CharField(blank=True, max_length=32, null=True, verbose_name='Ping method')),
|
|
||||||
('gather_facts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
|
|
||||||
('gather_facts_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Gather facts method')),
|
|
||||||
('create_account_enabled', models.BooleanField(default=False, verbose_name='Create account enabled')),
|
|
||||||
('create_account_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Create account method')),
|
|
||||||
('change_password_enabled', models.BooleanField(default=False, verbose_name='Change password enabled')),
|
|
||||||
('change_password_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Change password method')),
|
|
||||||
('verify_account_enabled', models.BooleanField(default=False, verbose_name='Verify account enabled')),
|
|
||||||
('verify_account_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Verify account method')),
|
|
||||||
('gather_accounts_enabled', models.BooleanField(default=False, verbose_name='Gather facts enabled')),
|
|
||||||
('gather_accounts_method', models.TextField(blank=True, max_length=32, null=True, verbose_name='Gather facts method')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='platform',
|
|
||||||
name='automation',
|
|
||||||
field=models.OneToOneField(blank=True, null=True, on_delete=models.deletion.CASCADE, related_name='platform', to='assets.platformautomation', verbose_name='Automation'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='platform',
|
|
||||||
name='domain_enabled',
|
|
||||||
field=models.BooleanField(default=True, verbose_name='Domain enabled'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='platform',
|
|
||||||
name='protocols_enabled',
|
|
||||||
field=models.BooleanField(default=True, verbose_name='Protocols enabled'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='platform',
|
|
||||||
name='su_enabled',
|
|
||||||
field=models.BooleanField(default=False, verbose_name='Su enabled'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='platform',
|
|
||||||
name='su_method',
|
|
||||||
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='SU method'),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,11 +5,6 @@ from django.db import migrations
|
||||||
from assets.models import Platform
|
from assets.models import Platform
|
||||||
|
|
||||||
|
|
||||||
def migrate_platform_set_ops(apps, *args):
|
|
||||||
platform_model = apps.get_model('assets', 'Platform')
|
|
||||||
Platform.set_default_platforms_ops(platform_model)
|
|
||||||
|
|
||||||
|
|
||||||
def migrate_accounts(apps, schema_editor):
|
def migrate_accounts(apps, schema_editor):
|
||||||
auth_book_model = apps.get_model('assets', 'AuthBook')
|
auth_book_model = apps.get_model('assets', 'AuthBook')
|
||||||
account_model = apps.get_model('assets', 'Account')
|
account_model = apps.get_model('assets', 'Account')
|
||||||
|
@ -89,5 +84,4 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RunPython(migrate_accounts),
|
migrations.RunPython(migrate_accounts),
|
||||||
migrations.RunPython(migrate_platform_set_ops)
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -45,39 +45,4 @@ class Migration(migrations.Migration):
|
||||||
model_name='asset',
|
model_name='asset',
|
||||||
name='public_ip',
|
name='public_ip',
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
|
||||||
name='asset',
|
|
||||||
options={'ordering': ['name'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetsystemuser', 'Can push system user to asset'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node')], 'verbose_name': 'Asset'},
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='asset',
|
|
||||||
old_name='hostname',
|
|
||||||
new_name='name',
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='asset',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=128, verbose_name='Name'),
|
|
||||||
),
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='asset',
|
|
||||||
old_name='ip',
|
|
||||||
new_name='address',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='asset',
|
|
||||||
name='date_updated',
|
|
||||||
field=models.DateTimeField(auto_now=True, verbose_name='Date updated'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='asset',
|
|
||||||
name='updated_by',
|
|
||||||
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='asset',
|
|
||||||
name='created_by',
|
|
||||||
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by'),
|
|
||||||
),
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -13,6 +13,9 @@ class Migration(migrations.Migration):
|
||||||
migrations.DeleteModel(
|
migrations.DeleteModel(
|
||||||
name='AdminUser',
|
name='AdminUser',
|
||||||
),
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='Cluster',
|
||||||
|
),
|
||||||
migrations.RemoveField(
|
migrations.RemoveField(
|
||||||
model_name='historicalauthbook',
|
model_name='historicalauthbook',
|
||||||
name='asset',
|
name='asset',
|
||||||
|
|
|
@ -82,7 +82,7 @@ def create_ticket_flow_and_approval_rule(apps, schema_editor):
|
||||||
super_user = user_model.objects.filter(role='Admin')
|
super_user = user_model.objects.filter(role='Admin')
|
||||||
assignees_display = ['{0.name}({0.username})'.format(i) for i in super_user]
|
assignees_display = ['{0.name}({0.username})'.format(i) for i in super_user]
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
for ticket_type in [TicketType.apply_asset, TicketType.apply_application]:
|
for ticket_type in [TicketType.apply_asset, 'apply_application']:
|
||||||
ticket_flow_instance = ticket_flow_model.objects.create(created_by='System', type=ticket_type, org_id=org_id)
|
ticket_flow_instance = ticket_flow_model.objects.create(created_by='System', type=ticket_type, org_id=org_id)
|
||||||
approval_rule_instance = approval_rule_model.objects.create(strategy=TicketApprovalStrategy.super_admin, assignees_display=assignees_display)
|
approval_rule_instance = approval_rule_model.objects.create(strategy=TicketApprovalStrategy.super_admin, assignees_display=assignees_display)
|
||||||
approval_rule_instance.assignees.set(list(super_user))
|
approval_rule_instance.assignees.set(list(super_user))
|
||||||
|
|
|
@ -112,7 +112,7 @@ def apply_application_migrate(apps, *args):
|
||||||
init_global_dict(apps)
|
init_global_dict(apps)
|
||||||
|
|
||||||
ticket_model = apps.get_model('tickets', 'Ticket')
|
ticket_model = apps.get_model('tickets', 'Ticket')
|
||||||
tickets = ticket_model.objects.filter(type=TicketType.apply_application)
|
tickets = ticket_model.objects.filter(type='apply_application')
|
||||||
ticket_apply_app_model = apps.get_model('tickets', 'ApplyApplicationTicket')
|
ticket_apply_app_model = apps.get_model('tickets', 'ApplyApplicationTicket')
|
||||||
|
|
||||||
for instance in tickets:
|
for instance in tickets:
|
||||||
|
|
Loading…
Reference in New Issue