diff --git a/apps/assets/migrations/0002_auto_20180105_1807.py b/apps/assets/migrations/0002_auto_20180105_1807.py deleted file mode 100644 index bf1f022ac..000000000 --- a/apps/assets/migrations/0002_auto_20180105_1807.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-01-05 10:07 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0001_initial'), - ] - - operations = [ - migrations.AlterModelOptions( - name='adminuser', - options={'ordering': ['name'], 'verbose_name': 'Admin user'}, - ), - migrations.AlterModelOptions( - name='asset', - options={'verbose_name': 'Asset'}, - ), - migrations.AlterModelOptions( - name='assetgroup', - options={'ordering': ['name'], 'verbose_name': 'Asset group'}, - ), - migrations.AlterModelOptions( - name='cluster', - options={'ordering': ['name'], 'verbose_name': 'Cluster'}, - ), - migrations.AlterModelOptions( - name='systemuser', - options={'ordering': ['name'], 'verbose_name': 'System user'}, - ), - ] diff --git a/apps/assets/migrations/0003_auto_20180109_2331.py b/apps/assets/migrations/0003_auto_20180109_2331.py deleted file mode 100644 index 254de6236..000000000 --- a/apps/assets/migrations/0003_auto_20180109_2331.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-01-09 15:31 -from __future__ import unicode_literals - -import assets.models.asset -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0002_auto_20180105_1807'), - ] - - operations = [ - migrations.AlterField( - model_name='asset', - name='cluster', - field=models.ForeignKey(default=assets.models.asset.default_cluster, on_delete=django.db.models.deletion.SET_DEFAULT, related_name='assets', to='assets.Cluster', verbose_name='Cluster'), - ), - ] diff --git a/apps/assets/migrations/0004_auto_20180125_1218.py b/apps/assets/migrations/0004_auto_20180125_1218.py deleted file mode 100644 index 1886fa499..000000000 --- a/apps/assets/migrations/0004_auto_20180125_1218.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-01-25 04:18 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0003_auto_20180109_2331'), - ] - - operations = [ - migrations.AlterField( - model_name='assetgroup', - name='created_by', - field=models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by'), - ), - ] diff --git a/apps/assets/migrations/0005_auto_20180126_1637.py b/apps/assets/migrations/0005_auto_20180126_1637.py deleted file mode 100644 index 8db19e482..000000000 --- a/apps/assets/migrations/0005_auto_20180126_1637.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-01-26 08:37 -from __future__ import unicode_literals - -from django.db import migrations, models -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0004_auto_20180125_1218'), - ] - - operations = [ - migrations.CreateModel( - name='Label', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=128, verbose_name='Name')), - ('value', models.CharField(max_length=128, verbose_name='Value')), - ('category', models.CharField(choices=[('S', 'System'), ('U', 'User')], default='U', max_length=128, verbose_name='Category')), - ('is_active', models.BooleanField(default=True, verbose_name='Is active')), - ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')), - ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), - ], - options={ - 'db_table': 'assets_label', - }, - ), - migrations.AlterUniqueTogether( - name='label', - unique_together=set([('name', 'value')]), - ), - migrations.AddField( - model_name='asset', - name='labels', - field=models.ManyToManyField(blank=True, related_name='assets', to='assets.Label', verbose_name='Labels'), - ), - ] diff --git a/apps/assets/migrations/0006_auto_20180130_1502.py b/apps/assets/migrations/0006_auto_20180130_1502.py deleted file mode 100644 index b77470d27..000000000 --- a/apps/assets/migrations/0006_auto_20180130_1502.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-01-30 07:02 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0005_auto_20180126_1637'), - ] - - operations = [ - migrations.RemoveField( - model_name='asset', - name='cabinet_no', - ), - migrations.RemoveField( - model_name='asset', - name='cabinet_pos', - ), - migrations.RemoveField( - model_name='asset', - name='env', - ), - migrations.RemoveField( - model_name='asset', - name='remote_card_ip', - ), - migrations.RemoveField( - model_name='asset', - name='status', - ), - migrations.RemoveField( - model_name='asset', - name='type', - ), - ] diff --git a/apps/assets/migrations/0007_auto_20180225_1815.py b/apps/assets/migrations/0007_auto_20180225_1815.py deleted file mode 100644 index 009381bcb..000000000 --- a/apps/assets/migrations/0007_auto_20180225_1815.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-02-25 10:15 -from __future__ import unicode_literals - -import assets.models.asset -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0006_auto_20180130_1502'), - ] - - operations = [ - migrations.CreateModel( - name='Node', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), - ('key', models.CharField(max_length=64, unique=True, verbose_name='Key')), - ('value', models.CharField(max_length=128, unique=True, verbose_name='Value')), - ('child_mark', models.IntegerField(default=0)), - ('date_create', models.DateTimeField(auto_now_add=True)), - ], - ), - migrations.RemoveField( - model_name='asset', - name='cluster', - ), - migrations.RemoveField( - model_name='asset', - name='groups', - ), - migrations.RemoveField( - model_name='systemuser', - name='cluster', - ), - migrations.AlterField( - model_name='asset', - name='admin_user', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='assets.AdminUser', verbose_name='Admin user'), - ), - migrations.AlterField( - model_name='systemuser', - name='protocol', - field=models.CharField(choices=[('ssh', 'ssh'), ('rdp', 'rdp')], default='ssh', max_length=16, verbose_name='Protocol'), - ), - migrations.AddField( - model_name='asset', - name='nodes', - field=models.ManyToManyField(default=assets.models.asset.default_node, related_name='assets', to='assets.Node', verbose_name='Nodes'), - ), - migrations.AddField( - model_name='systemuser', - name='nodes', - field=models.ManyToManyField(blank=True, to='assets.Node', verbose_name='Nodes'), - ), - ] diff --git a/apps/assets/migrations/0008_auto_20180306_1804.py b/apps/assets/migrations/0008_auto_20180306_1804.py deleted file mode 100644 index 48d352619..000000000 --- a/apps/assets/migrations/0008_auto_20180306_1804.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-03-06 10:04 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0007_auto_20180225_1815'), - ] - - operations = [ - migrations.AlterField( - model_name='adminuser', - name='created_by', - field=models.CharField(max_length=128, null=True, verbose_name='Created by'), - ), - migrations.AlterField( - model_name='adminuser', - name='username', - field=models.CharField(max_length=128, verbose_name='Username'), - ), - migrations.AlterField( - model_name='asset', - name='platform', - field=models.CharField(choices=[('Linux', 'Linux'), ('Unix', 'Unix'), ('MacOS', 'MacOS'), ('BSD', 'BSD'), ('Windows', 'Windows'), ('Other', 'Other')], default='Linux', max_length=128, verbose_name='Platform'), - ), - migrations.AlterField( - model_name='systemuser', - name='created_by', - field=models.CharField(max_length=128, null=True, verbose_name='Created by'), - ), - migrations.AlterField( - model_name='systemuser', - name='username', - field=models.CharField(max_length=128, verbose_name='Username'), - ), - ] diff --git a/apps/assets/migrations/0009_auto_20180307_1212.py b/apps/assets/migrations/0009_auto_20180307_1212.py deleted file mode 100644 index 08d770642..000000000 --- a/apps/assets/migrations/0009_auto_20180307_1212.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-03-07 04:12 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0008_auto_20180306_1804'), - ] - - operations = [ - migrations.AlterField( - model_name='node', - name='value', - field=models.CharField(max_length=128, verbose_name='Value'), - ), - ] diff --git a/apps/assets/migrations/0010_auto_20180307_1749.py b/apps/assets/migrations/0010_auto_20180307_1749.py deleted file mode 100644 index 5e6be0943..000000000 --- a/apps/assets/migrations/0010_auto_20180307_1749.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-03-07 09:49 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0009_auto_20180307_1212'), - ] - - operations = [ - migrations.AlterField( - model_name='node', - name='value', - field=models.CharField(max_length=128, unique=True, verbose_name='Value'), - ), - ] diff --git a/apps/assets/migrations/0011_auto_20180326_0957.py b/apps/assets/migrations/0011_auto_20180326_0957.py deleted file mode 100644 index 07b9055dc..000000000 --- a/apps/assets/migrations/0011_auto_20180326_0957.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-03-26 01:57 -from __future__ import unicode_literals - -import assets.models.utils -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0010_auto_20180307_1749'), - ] - - operations = [ - migrations.CreateModel( - name='Domain', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=128, unique=True, verbose_name='Name')), - ('comment', models.TextField(blank=True, verbose_name='Comment')), - ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), - ], - ), - migrations.CreateModel( - name='Gateway', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=128, unique=True, verbose_name='Name')), - ('username', models.CharField(max_length=128, verbose_name='Username')), - ('_password', models.CharField(blank=True, max_length=256, null=True, verbose_name='Password')), - ('_private_key', models.TextField(blank=True, max_length=4096, null=True, validators=[assets.models.utils.private_key_validator], verbose_name='SSH private key')), - ('_public_key', models.TextField(blank=True, max_length=4096, verbose_name='SSH public key')), - ('date_created', models.DateTimeField(auto_now_add=True)), - ('date_updated', models.DateTimeField(auto_now=True)), - ('created_by', models.CharField(max_length=128, null=True, verbose_name='Created by')), - ('ip', models.GenericIPAddressField(db_index=True, verbose_name='IP')), - ('port', models.IntegerField(default=22, verbose_name='Port')), - ('protocol', models.CharField(choices=[('ssh', 'ssh'), ('rdp', 'rdp')], default='ssh', max_length=16, verbose_name='Protocol')), - ('comment', models.CharField(blank=True, max_length=128, null=True, verbose_name='Comment')), - ('is_active', models.BooleanField(default=True, verbose_name='Is active')), - ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='assets.Domain', verbose_name='Domain')), - ], - options={ - 'abstract': False, - }, - ), - migrations.AddField( - model_name='asset', - name='domain', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='assets', to='assets.Domain', verbose_name='Domain'), - ), - ] diff --git a/apps/assets/migrations/0012_auto_20180404_1302.py b/apps/assets/migrations/0012_auto_20180404_1302.py deleted file mode 100644 index 0ccb63e27..000000000 --- a/apps/assets/migrations/0012_auto_20180404_1302.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-04 05:02 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0011_auto_20180326_0957'), - ] - - operations = [ - migrations.AlterField( - model_name='asset', - name='domain', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assets', to='assets.Domain', verbose_name='Domain'), - ), - ] diff --git a/apps/assets/migrations/0013_auto_20180411_1135.py b/apps/assets/migrations/0013_auto_20180411_1135.py deleted file mode 100644 index baaf789bd..000000000 --- a/apps/assets/migrations/0013_auto_20180411_1135.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-11 03:35 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0012_auto_20180404_1302'), - ] - - operations = [ - migrations.AddField( - model_name='systemuser', - name='assets', - field=models.ManyToManyField(blank=True, to='assets.Asset', verbose_name='Assets'), - ), - migrations.AlterField( - model_name='systemuser', - name='sudo', - field=models.TextField(default='/bin/whoami', verbose_name='Sudo'), - ), - ] diff --git a/apps/assets/migrations/0014_auto_20180427_1245.py b/apps/assets/migrations/0014_auto_20180427_1245.py deleted file mode 100644 index 735a50879..000000000 --- a/apps/assets/migrations/0014_auto_20180427_1245.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-27 04:45 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0013_auto_20180411_1135'), - ] - - operations = [ - migrations.AlterField( - model_name='adminuser', - name='username', - field=models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_-]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.AlterField( - model_name='gateway', - name='username', - field=models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_-]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.AlterField( - model_name='systemuser', - name='username', - field=models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_-]*$', 'Special char not allowed')], verbose_name='Username'), - ), - ] diff --git a/apps/assets/migrations/0015_auto_20180510_1235.py b/apps/assets/migrations/0015_auto_20180510_1235.py deleted file mode 100644 index 81d12d2e4..000000000 --- a/apps/assets/migrations/0015_auto_20180510_1235.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-05-10 04:35 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0014_auto_20180427_1245'), - ] - - operations = [ - migrations.AlterField( - model_name='adminuser', - name='username', - field=models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_@\\-\\.]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.AlterField( - model_name='gateway', - name='username', - field=models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_@\\-\\.]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.AlterField( - model_name='systemuser', - name='username', - field=models.CharField(max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_@\\-\\.]*$', 'Special char not allowed')], verbose_name='Username'), - ), - ] diff --git a/apps/assets/migrations/0016_auto_20180511_1203.py b/apps/assets/migrations/0016_auto_20180511_1203.py deleted file mode 100644 index 32f79a3c6..000000000 --- a/apps/assets/migrations/0016_auto_20180511_1203.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-05-11 04:03 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0015_auto_20180510_1235'), - ] - - operations = [ - migrations.AlterField( - model_name='node', - name='value', - field=models.CharField(max_length=128, verbose_name='Value'), - ), - ] diff --git a/apps/assets/migrations/0017_auto_20180702_1415.py b/apps/assets/migrations/0017_auto_20180702_1415.py deleted file mode 100644 index 9950424a6..000000000 --- a/apps/assets/migrations/0017_auto_20180702_1415.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-07-02 06:15 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -def migrate_win_to_ssh_protocol(apps, schema_editor): - asset_model = apps.get_model("assets", "Asset") - db_alias = schema_editor.connection.alias - asset_model.objects.using(db_alias).filter(platform__startswith='Win').update(protocol='rdp') - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0016_auto_20180511_1203'), - ] - - operations = [ - migrations.AddField( - model_name='asset', - name='protocol', - field=models.CharField(choices=[('ssh', 'ssh'), ('rdp', 'rdp'), ('telnet', 'telnet (beta)')], default='ssh', max_length=128, verbose_name='Protocol'), - ), - migrations.AddField( - model_name='systemuser', - name='login_mode', - field=models.CharField(choices=[('auto', 'Automatic login'), ('manual', 'Manually login')], default='auto', max_length=10, verbose_name='Login mode'), - ), - migrations.AlterField( - model_name='adminuser', - name='username', - field=models.CharField(blank=True, max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_@\\-\\.]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.AlterField( - model_name='asset', - name='platform', - field=models.CharField(choices=[('Linux', 'Linux'), ('Unix', 'Unix'), ('MacOS', 'MacOS'), ('BSD', 'BSD'), ('Windows', 'Windows'), ('Windows2016', 'Windows(2016)'), ('Other', 'Other')], default='Linux', max_length=128, verbose_name='Platform'), - ), - migrations.AlterField( - model_name='gateway', - name='username', - field=models.CharField(blank=True, max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_@\\-\\.]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.AlterField( - model_name='systemuser', - name='protocol', - field=models.CharField(choices=[('ssh', 'ssh'), ('rdp', 'rdp'), ('telnet', 'telnet (beta)')], default='ssh', max_length=16, verbose_name='Protocol'), - ), - migrations.AlterField( - model_name='systemuser', - name='username', - field=models.CharField(blank=True, max_length=32, validators=[django.core.validators.RegexValidator('^[0-9a-zA-Z_@\\-\\.]*$', 'Special char not allowed')], verbose_name='Username'), - ), - migrations.RunPython(migrate_win_to_ssh_protocol), - ] diff --git a/apps/assets/migrations/0018_auto_20180807_1116.py b/apps/assets/migrations/0018_auto_20180807_1116.py deleted file mode 100644 index c4e848b43..000000000 --- a/apps/assets/migrations/0018_auto_20180807_1116.py +++ /dev/null @@ -1,84 +0,0 @@ -# Generated by Django 2.0.7 on 2018-08-07 03:16 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0017_auto_20180702_1415'), - ] - - operations = [ - migrations.AddField( - model_name='adminuser', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AddField( - model_name='asset', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AddField( - model_name='domain', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AddField( - model_name='gateway', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AddField( - model_name='label', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AddField( - model_name='node', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AddField( - model_name='systemuser', - name='org_id', - field=models.CharField(blank=True, default=None, max_length=36, null=True), - ), - migrations.AlterField( - model_name='adminuser', - name='name', - field=models.CharField(max_length=128, verbose_name='Name'), - ), - migrations.AlterField( - model_name='asset', - name='hostname', - field=models.CharField(max_length=128, verbose_name='Hostname'), - ), - migrations.AlterField( - model_name='gateway', - name='name', - field=models.CharField(max_length=128, verbose_name='Name'), - ), - migrations.AlterField( - model_name='systemuser', - name='name', - field=models.CharField(max_length=128, verbose_name='Name'), - ), - migrations.AlterUniqueTogether( - name='adminuser', - unique_together={('name', 'org_id')}, - ), - migrations.AlterUniqueTogether( - name='asset', - unique_together={('org_id', 'hostname')}, - ), - migrations.AlterUniqueTogether( - name='gateway', - unique_together={('name', 'org_id')}, - ), - migrations.AlterUniqueTogether( - name='systemuser', - unique_together={('name', 'org_id')}, - ), - ] diff --git a/apps/assets/migrations/0019_auto_20180816_1320.py b/apps/assets/migrations/0019_auto_20180816_1320.py deleted file mode 100644 index 0d468e511..000000000 --- a/apps/assets/migrations/0019_auto_20180816_1320.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 2.0.7 on 2018-08-16 05:20 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('assets', '0018_auto_20180807_1116'), - ] - - operations = [ - migrations.AddField( - model_name='asset', - name='cpu_vcpus', - field=models.IntegerField(null=True, verbose_name='CPU vcpus'), - ), - migrations.AlterUniqueTogether( - name='label', - unique_together={('name', 'value', 'org_id')}, - ), - ] diff --git a/apps/assets/migrations/0033_auto_20190624_2108.py b/apps/assets/migrations/0033_auto_20190624_2108.py index c9ac245d0..dc89bc125 100644 --- a/apps/assets/migrations/0033_auto_20190624_2108.py +++ b/apps/assets/migrations/0033_auto_20190624_2108.py @@ -1,6 +1,5 @@ # Generated by Django 2.1.7 on 2019-06-24 13:08 -import common.fields.model from django.db import migrations diff --git a/apps/common/mixins.py b/apps/common/mixins.py deleted file mode 100644 index b46673cd6..000000000 --- a/apps/common/mixins.py +++ /dev/null @@ -1,234 +0,0 @@ -# coding: utf-8 - -from django.db import models -from django.http import JsonResponse -from django.utils import timezone -from django.core.cache import cache -from django.utils.translation import ugettext_lazy as _ -from django.contrib import messages -from rest_framework.utils import html -from rest_framework.settings import api_settings -from rest_framework.exceptions import ValidationError -from rest_framework.fields import SkipField - -from .const import KEY_CACHE_RESOURCES_ID - - -class NoDeleteQuerySet(models.query.QuerySet): - - def delete(self): - return self.update(is_discard=True, discard_time=timezone.now()) - - -class NoDeleteManager(models.Manager): - - def get_all(self): - return NoDeleteQuerySet(self.model, using=self._db) - - def get_queryset(self): - return NoDeleteQuerySet(self.model, using=self._db).filter(is_discard=False) - - def get_deleted(self): - return NoDeleteQuerySet(self.model, using=self._db).filter(is_discard=True) - - -class NoDeleteModelMixin(models.Model): - is_discard = models.BooleanField(verbose_name=_("is discard"), default=False) - discard_time = models.DateTimeField(verbose_name=_("discard time"), null=True, blank=True) - - objects = NoDeleteManager() - - class Meta: - abstract = True - - def delete(self): - self.is_discard = True - self.discard_time = timezone.now() - return self.save() - - -class JSONResponseMixin(object): - """JSON mixin""" - @staticmethod - def render_json_response(context): - return JsonResponse(context) - - -class IDInFilterMixin(object): - def filter_queryset(self, queryset): - queryset = super(IDInFilterMixin, self).filter_queryset(queryset) - id_list = self.request.query_params.get('id__in') - if id_list: - import json - try: - ids = json.loads(id_list) - except Exception as e: - return queryset - if isinstance(ids, list): - queryset = queryset.filter(id__in=ids) - return queryset - - -class IDInCacheFilterMixin(object): - - def filter_queryset(self, queryset): - queryset = super(IDInCacheFilterMixin, self).filter_queryset(queryset) - spm = self.request.query_params.get('spm') - cache_key = KEY_CACHE_RESOURCES_ID.format(spm) - resources_id = cache.get(cache_key) - if resources_id and isinstance(resources_id, list): - queryset = queryset.filter(id__in=resources_id) - return queryset - - -class IDExportFilterMixin(object): - def filter_queryset(self, queryset): - # 下载导入模版 - if self.request.query_params.get('template') == 'import': - return [] - else: - return super(IDExportFilterMixin, self).filter_queryset(queryset) - - -class BulkSerializerMixin(object): - """ - Become rest_framework_bulk not support uuid as a primary key - so rewrite it. https://github.com/miki725/django-rest-framework-bulk/issues/66 - """ - def to_internal_value(self, data): - from rest_framework_bulk import BulkListSerializer - ret = super(BulkSerializerMixin, self).to_internal_value(data) - - id_attr = getattr(self.Meta, 'update_lookup_field', 'id') - if self.context.get('view'): - request_method = getattr(getattr(self.context.get('view'), 'request'), 'method', '') - # add update_lookup_field field back to validated data - # since super by default strips out read-only fields - # hence id will no longer be present in validated_data - if all((isinstance(self.root, BulkListSerializer), - id_attr, - request_method in ('PUT', 'PATCH'))): - id_field = self.fields[id_attr] - if data.get("id"): - id_value = id_field.to_internal_value(data.get("id")) - else: - id_value = id_field.to_internal_value(data.get("pk")) - ret[id_attr] = id_value - - return ret - - -class BulkListSerializerMixin(object): - """ - Become rest_framework_bulk doing bulk update raise Exception: - 'QuerySet' object has no attribute 'pk' when doing bulk update - so rewrite it . - https://github.com/miki725/django-rest-framework-bulk/issues/68 - """ - - def to_internal_value(self, data): - """ - List of dicts of native values <- List of dicts of primitive datatypes. - """ - if html.is_html_input(data): - data = html.parse_html_list(data) - - if not isinstance(data, list): - message = self.error_messages['not_a_list'].format( - input_type=type(data).__name__ - ) - raise ValidationError({ - api_settings.NON_FIELD_ERRORS_KEY: [message] - }, code='not_a_list') - - if not self.allow_empty and len(data) == 0: - if self.parent and self.partial: - raise SkipField() - - message = self.error_messages['empty'] - raise ValidationError({ - api_settings.NON_FIELD_ERRORS_KEY: [message] - }, code='empty') - - ret = [] - errors = [] - - for item in data: - try: - # prepare child serializer to only handle one instance - if 'id' in item.keys(): - self.child.instance = self.instance.get(id=item['id']) if self.instance else None - if 'pk' in item.keys(): - self.child.instance = self.instance.get(id=item['pk']) if self.instance else None - - self.child.initial_data = item - # raw - validated = self.child.run_validation(item) - except ValidationError as exc: - errors.append(exc.detail) - else: - ret.append(validated) - errors.append({}) - - if any(errors): - raise ValidationError(errors) - - return ret - - -class DatetimeSearchMixin: - date_format = '%Y-%m-%d' - date_from = date_to = None - - def get_date_range(self): - date_from_s = self.request.GET.get('date_from') - date_to_s = self.request.GET.get('date_to') - - if date_from_s: - date_from = timezone.datetime.strptime(date_from_s, self.date_format) - tz = timezone.get_current_timezone() - self.date_from = tz.localize(date_from) - else: - self.date_from = timezone.now() - timezone.timedelta(7) - - if date_to_s: - date_to = timezone.datetime.strptime( - date_to_s + ' 23:59:59', self.date_format + ' %H:%M:%S' - ) - self.date_to = date_to.replace( - tzinfo=timezone.get_current_timezone() - ) - else: - self.date_to = timezone.now() - - def get(self, request, *args, **kwargs): - self.get_date_range() - return super().get(request, *args, **kwargs) - - -class ApiMessageMixin: - success_message = _("%(name)s was %(action)s successfully") - _action_map = {"create": _("create"), "update": _("update")} - - def get_success_message(self, cleaned_data): - if not isinstance(cleaned_data, dict): - return '' - data = {k: v for k, v in cleaned_data.items()} - action = getattr(self, "action", "create") - data["action"] = self._action_map.get(action) - try: - message = self.success_message % data - except: - message = '' - return message - - def dispatch(self, request, *args, **kwargs): - resp = super().dispatch(request, *args, **kwargs) - if request.method.lower() in ("get", "delete", "patch"): - return resp - if resp.status_code >= 400: - return resp - message = self.get_success_message(resp.data) - if message: - messages.success(request, message) - return resp diff --git a/apps/common/mixins/__init__.py b/apps/common/mixins/__init__.py new file mode 100644 index 000000000..4249b3d64 --- /dev/null +++ b/apps/common/mixins/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# +from .models import * +from .serializers import * +from .api import * +from .views import * diff --git a/apps/common/mixins/api.py b/apps/common/mixins/api.py new file mode 100644 index 000000000..410f077eb --- /dev/null +++ b/apps/common/mixins/api.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# +from django.http import JsonResponse +from django.core.cache import cache +from django.utils.translation import ugettext_lazy as _ +from django.contrib import messages + +from ..const import KEY_CACHE_RESOURCES_ID + +__all__ = [ + "JSONResponseMixin", "IDInCacheFilterMixin", "IDExportFilterMixin", + "IDInFilterMixin", "ApiMessageMixin" +] + + +class JSONResponseMixin(object): + """JSON mixin""" + @staticmethod + def render_json_response(context): + return JsonResponse(context) + + +class IDInFilterMixin(object): + def filter_queryset(self, queryset): + queryset = super(IDInFilterMixin, self).filter_queryset(queryset) + id_list = self.request.query_params.get('id__in') + if id_list: + import json + try: + ids = json.loads(id_list) + except Exception as e: + return queryset + if isinstance(ids, list): + queryset = queryset.filter(id__in=ids) + return queryset + + +class IDInCacheFilterMixin(object): + + def filter_queryset(self, queryset): + queryset = super(IDInCacheFilterMixin, self).filter_queryset(queryset) + spm = self.request.query_params.get('spm') + cache_key = KEY_CACHE_RESOURCES_ID.format(spm) + resources_id = cache.get(cache_key) + if resources_id and isinstance(resources_id, list): + queryset = queryset.filter(id__in=resources_id) + return queryset + + +class IDExportFilterMixin(object): + def filter_queryset(self, queryset): + # 下载导入模版 + if self.request.query_params.get('template') == 'import': + return [] + else: + return super(IDExportFilterMixin, self).filter_queryset(queryset) + + +class ApiMessageMixin: + success_message = _("%(name)s was %(action)s successfully") + _action_map = {"create": _("create"), "update": _("update")} + + def get_success_message(self, cleaned_data): + if not isinstance(cleaned_data, dict): + return '' + data = {k: v for k, v in cleaned_data.items()} + action = getattr(self, "action", "create") + data["action"] = self._action_map.get(action) + try: + message = self.success_message % data + except: + message = '' + return message + + def dispatch(self, request, *args, **kwargs): + resp = super().dispatch(request, *args, **kwargs) + if request.method.lower() in ("get", "delete", "patch"): + return resp + if resp.status_code >= 400: + return resp + message = self.get_success_message(resp.data) + if message: + messages.success(request, message) + return resp \ No newline at end of file diff --git a/apps/common/mixins/models.py b/apps/common/mixins/models.py new file mode 100644 index 000000000..d4af23896 --- /dev/null +++ b/apps/common/mixins/models.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# + +from django.db import models +from django.utils import timezone +from django.utils.translation import ugettext_lazy as _ + + +__all__ = ["NoDeleteManager", "NoDeleteModelMixin", "NoDeleteQuerySet"] + + +class NoDeleteQuerySet(models.query.QuerySet): + + def delete(self): + return self.update(is_discard=True, discard_time=timezone.now()) + + +class NoDeleteManager(models.Manager): + + def get_all(self): + return NoDeleteQuerySet(self.model, using=self._db) + + def get_queryset(self): + return NoDeleteQuerySet(self.model, using=self._db).filter(is_discard=False) + + def get_deleted(self): + return NoDeleteQuerySet(self.model, using=self._db).filter(is_discard=True) + + +class NoDeleteModelMixin(models.Model): + is_discard = models.BooleanField(verbose_name=_("is discard"), default=False) + discard_time = models.DateTimeField(verbose_name=_("discard time"), null=True, blank=True) + + objects = NoDeleteManager() + + class Meta: + abstract = True + + def delete(self): + self.is_discard = True + self.discard_time = timezone.now() + return self.save() diff --git a/apps/common/mixins/serializers.py b/apps/common/mixins/serializers.py new file mode 100644 index 000000000..009d0b994 --- /dev/null +++ b/apps/common/mixins/serializers.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# + +from rest_framework.utils import html +from rest_framework.settings import api_settings +from rest_framework.exceptions import ValidationError +from rest_framework.fields import SkipField + +__all__ = ['BulkSerializerMixin', 'BulkListSerializerMixin'] + + +class BulkSerializerMixin(object): + """ + Become rest_framework_bulk not support uuid as a primary key + so rewrite it. https://github.com/miki725/django-rest-framework-bulk/issues/66 + """ + def to_internal_value(self, data): + from rest_framework_bulk import BulkListSerializer + ret = super(BulkSerializerMixin, self).to_internal_value(data) + + id_attr = getattr(self.Meta, 'update_lookup_field', 'id') + if self.context.get('view'): + request_method = getattr(getattr(self.context.get('view'), 'request'), 'method', '') + # add update_lookup_field field back to validated data + # since super by default strips out read-only fields + # hence id will no longer be present in validated_data + if all((isinstance(self.root, BulkListSerializer), + id_attr, + request_method in ('PUT', 'PATCH'))): + id_field = self.fields[id_attr] + if data.get("id"): + id_value = id_field.to_internal_value(data.get("id")) + else: + id_value = id_field.to_internal_value(data.get("pk")) + ret[id_attr] = id_value + + return ret + + +class BulkListSerializerMixin(object): + """ + Become rest_framework_bulk doing bulk update raise Exception: + 'QuerySet' object has no attribute 'pk' when doing bulk update + so rewrite it . + https://github.com/miki725/django-rest-framework-bulk/issues/68 + """ + + def to_internal_value(self, data): + """ + List of dicts of native values <- List of dicts of primitive datatypes. + """ + if html.is_html_input(data): + data = html.parse_html_list(data) + + if not isinstance(data, list): + message = self.error_messages['not_a_list'].format( + input_type=type(data).__name__ + ) + raise ValidationError({ + api_settings.NON_FIELD_ERRORS_KEY: [message] + }, code='not_a_list') + + if not self.allow_empty and len(data) == 0: + if self.parent and self.partial: + raise SkipField() + + message = self.error_messages['empty'] + raise ValidationError({ + api_settings.NON_FIELD_ERRORS_KEY: [message] + }, code='empty') + + ret = [] + errors = [] + + for item in data: + try: + # prepare child serializer to only handle one instance + if 'id' in item.keys(): + self.child.instance = self.instance.get(id=item['id']) if self.instance else None + if 'pk' in item.keys(): + self.child.instance = self.instance.get(id=item['pk']) if self.instance else None + + self.child.initial_data = item + # raw + validated = self.child.run_validation(item) + except ValidationError as exc: + errors.append(exc.detail) + else: + ret.append(validated) + errors.append({}) + + if any(errors): + raise ValidationError(errors) + + return ret diff --git a/apps/common/mixins/views.py b/apps/common/mixins/views.py new file mode 100644 index 000000000..a00535b5b --- /dev/null +++ b/apps/common/mixins/views.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# +# coding: utf-8 + +from django.utils import timezone + + +__all__ = ["DatetimeSearchMixin"] + + +class DatetimeSearchMixin: + date_format = '%Y-%m-%d' + date_from = date_to = None + + def get_date_range(self): + date_from_s = self.request.GET.get('date_from') + date_to_s = self.request.GET.get('date_to') + + if date_from_s: + date_from = timezone.datetime.strptime(date_from_s, self.date_format) + tz = timezone.get_current_timezone() + self.date_from = tz.localize(date_from) + else: + self.date_from = timezone.now() - timezone.timedelta(7) + + if date_to_s: + date_to = timezone.datetime.strptime( + date_to_s + ' 23:59:59', self.date_format + ' %H:%M:%S' + ) + self.date_to = date_to.replace( + tzinfo=timezone.get_current_timezone() + ) + else: + self.date_to = timezone.now() + + def get(self, request, *args, **kwargs): + self.get_date_range() + return super().get(request, *args, **kwargs) + + diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 0ca68d947..0f9f7df55 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -301,10 +301,10 @@ LOGGING = { 'handlers': ['gunicorn_console', 'gunicorn_file'], 'level': 'INFO', }, - # 'django.db': { - # 'handlers': ['console', 'file'], - # 'level': 'DEBUG' - # } + 'django.db': { + 'handlers': ['console', 'file'], + 'level': 'DEBUG' + } } } diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py index bcb4fb0ee..d47b00bf9 100644 --- a/apps/perms/models/asset_permission.py +++ b/apps/perms/models/asset_permission.py @@ -55,6 +55,8 @@ class Action: x = cls.NAME_MAP_REVERSE.get(x, 0) y = cls.NAME_MAP_REVERSE.get(y, 0) return x | y + if not value: + return None return reduce(to_choices, value) @classmethod diff --git a/apps/perms/serializers/asset_permission.py b/apps/perms/serializers/asset_permission.py index 13197dd24..ecbed669b 100644 --- a/apps/perms/serializers/asset_permission.py +++ b/apps/perms/serializers/asset_permission.py @@ -10,11 +10,11 @@ from perms.models import AssetPermission, Action __all__ = [ 'AssetPermissionCreateUpdateSerializer', 'AssetPermissionListSerializer', 'AssetPermissionUpdateUserSerializer', 'AssetPermissionUpdateAssetSerializer', - 'ActionField', + 'ActionsField', ] -class ActionField(serializers.MultipleChoiceField): +class ActionsField(serializers.MultipleChoiceField): def __init__(self, *args, **kwargs): kwargs['choices'] = Action.CHOICES super().__init__(*args, **kwargs) @@ -23,10 +23,12 @@ class ActionField(serializers.MultipleChoiceField): return Action.value_to_choices(value) def to_internal_value(self, data): + if data is None: + return data return Action.choices_to_value(data) -class ActionDisplayField(ActionField): +class ActionsDisplayField(ActionsField): def to_representation(self, value): values = super().to_representation(value) choices = dict(Action.CHOICES) @@ -34,7 +36,7 @@ class ActionDisplayField(ActionField): class AssetPermissionCreateUpdateSerializer(BulkOrgResourceModelSerializer): - actions = ActionField() + actions = ActionsField(required=False, allow_null=True) class Meta: model = AssetPermission @@ -47,7 +49,7 @@ class AssetPermissionListSerializer(BulkOrgResourceModelSerializer): assets = StringManyToManyField(many=True, read_only=True) nodes = StringManyToManyField(many=True, read_only=True) system_users = StringManyToManyField(many=True, read_only=True) - actions = ActionDisplayField() + actions = ActionsDisplayField() is_valid = serializers.BooleanField() is_expired = serializers.BooleanField() diff --git a/apps/perms/serializers/user_permission.py b/apps/perms/serializers/user_permission.py index 43cf47136..639ba7140 100644 --- a/apps/perms/serializers/user_permission.py +++ b/apps/perms/serializers/user_permission.py @@ -6,7 +6,7 @@ from rest_framework import serializers from assets.models import Node, SystemUser from assets.serializers import AssetSerializer -from .asset_permission import ActionField +from .asset_permission import ActionsField __all__ = [ 'AssetPermissionNodeSerializer', 'GrantedNodeSerializer', @@ -19,7 +19,7 @@ class AssetSystemUserSerializer(serializers.ModelSerializer): """ 查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少 """ - actions = ActionField(read_only=True) + actions = ActionsField(read_only=True) class Meta: model = SystemUser @@ -115,4 +115,4 @@ class GrantedNodeSerializer(serializers.ModelSerializer): class ActionsSerializer(serializers.Serializer): - actions = ActionField(read_only=True) \ No newline at end of file + actions = ActionsField(read_only=True) diff --git a/apps/settings/signals_handler.py b/apps/settings/signals_handler.py index 7a1b782f5..9302b63e2 100644 --- a/apps/settings/signals_handler.py +++ b/apps/settings/signals_handler.py @@ -77,6 +77,7 @@ def monkey_patch_settings(sender, **kwargs): @receiver(django_ready) def auto_generate_terminal_host_key(sender, **kwargs): try: + print("Auto gen host key") if Setting.objects.filter(name='TERMINAL_HOST_KEY').exists(): return private_key, public_key = ssh_key_gen()