refacter: 重构application

pull/4886/head
ibuler 2020-10-19 20:13:01 +08:00 committed by 老广
parent 874a3eeebf
commit ba4e6e9a9f
12 changed files with 292 additions and 9 deletions

View File

@ -1,3 +1,4 @@
from .application import *
from .remote_app import *
from .database_app import *
from .k8s_app import *

View File

@ -0,0 +1,20 @@
# coding: utf-8
#
from orgs.mixins.api import OrgBulkModelViewSet
from .. import models
from .. import serializers
from ..hands import IsOrgAdminOrAppUser
__all__ = [
'ApplicationViewSet',
]
class ApplicationViewSet(OrgBulkModelViewSet):
model = models.Application
filter_fields = ('name',)
search_fields = filter_fields
permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = serializers.ApplicationSerializer

View File

@ -0,0 +1,37 @@
# Generated by Django 2.2.13 on 2020-10-19 12:01
from django.db import migrations, models
import django.db.models.deletion
import django_mysql.models
import uuid
class Migration(migrations.Migration):
dependencies = [
('assets', '0057_fill_node_value_assets_amount_and_parent_key'),
('applications', '0005_k8sapp'),
]
operations = [
migrations.CreateModel(
name='Application',
fields=[
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')),
('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')),
('name', models.CharField(max_length=128, verbose_name='Name')),
('category', models.CharField(choices=[('db', 'Database'), ('remote_app', 'Remote app'), ('cloud', 'Cloud')], max_length=16, verbose_name='Category')),
('type', models.CharField(choices=[('mysql', 'MySQL'), ('oracle', 'Oracle'), ('postgresql', 'PostgreSQL'), ('mariadb', 'MariaDB'), ('chrome', 'Chrome'), ('mysql_workbench', 'MySQL Workbench'), ('vmware_client', 'vSphere Client'), ('custom', 'Custom'), ('k8s', 'Kubernetes')], max_length=16, verbose_name='Type')),
('attrs', django_mysql.models.JSONField(default=dict)),
('comment', models.TextField(blank=True, default='', max_length=128, verbose_name='Comment')),
('domain', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.Domain')),
],
options={
'ordering': ('name',),
'unique_together': {('org_id', 'name')},
},
),
]

View File

@ -1,3 +1,4 @@
from .application import *
from .remote_app import *
from .database_app import *
from .k8s_app import *

View File

@ -0,0 +1,115 @@
from itertools import chain
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django_mysql.models import JSONField, QuerySet
from orgs.mixins.models import OrgModelMixin
from common.mixins import CommonModelMixin
from common.db.models import ChoiceSet
class DBType(ChoiceSet):
mysql = 'mysql', 'MySQL'
oracle = 'oracle', 'Oracle'
pgsql = 'postgresql', 'PostgreSQL'
mariadb = 'mariadb', 'MariaDB'
@classmethod
def get_type_serializer_cls_mapper(cls):
from ..serializers import database_app
mapper = {
cls.mysql: database_app.MySQLAttrsSerializer,
cls.oracle: database_app.OracleAttrsSerializer,
cls.pgsql: database_app.PostgreAttrsSerializer,
cls.mariadb: database_app.MariaDBAttrsSerializer,
}
return mapper
class RemoteAppType(ChoiceSet):
chrome = 'chrome', 'Chrome'
mysql_workbench = 'mysql_workbench', 'MySQL Workbench'
vmware_client = 'vmware_client', 'vSphere Client'
custom = 'custom', _('Custom')
@classmethod
def get_type_serializer_cls_mapper(cls):
from ..serializers import remote_app
mapper = {
cls.chrome: remote_app.ChromeAttrsSerializer,
cls.mysql_workbench: remote_app.MySQLWorkbenchAttrsSerializer,
cls.vmware_client: remote_app.VMwareClientAttrsSerializer,
cls.custom: remote_app.CustomRemoteAppAttrsSeralizers,
}
return mapper
class CloudType(ChoiceSet):
k8s = 'k8s', 'Kubernetes'
@classmethod
def get_type_serializer_cls_mapper(cls):
from ..serializers import k8s_app
mapper = {
cls.k8s: k8s_app.K8sAttrsSerializer,
}
return mapper
class Category(ChoiceSet):
db = 'db', _('Database')
remote_app = 'remote_app', _('Remote app')
cloud = 'cloud', 'Cloud'
@classmethod
def get_category_type_mapper(cls):
return {
cls.db: DBType,
cls.remote_app: RemoteAppType,
cls.cloud: CloudType
}
@classmethod
def get_category_type_choices_mapper(cls):
return {
name: tp.choices
for name, tp in cls.get_category_type_mapper().items()
}
@classmethod
def get_type_choices(cls, category):
return cls.get_category_type_choices_mapper().get(category, [])
@classmethod
def get_all_type_choices(cls):
all_grouped_choices = tuple(cls.get_category_type_choices_mapper().values())
return tuple(chain(*all_grouped_choices))
@classmethod
def get_all_type_serializer_mapper(cls):
mapper = {}
for tp in cls.get_category_type_mapper().values():
mapper.update(tp.get_type_serializer_cls_mapper())
return mapper
@classmethod
def get_type_serializer_cls(cls, tp):
mapper = cls.get_all_type_serializer_mapper()
return mapper.get(tp, None)
class Application(CommonModelMixin, OrgModelMixin):
name = models.CharField(max_length=128, verbose_name=_('Name'))
domain = models.ForeignKey('assets.Domain', on_delete=models.SET_NULL, null=True)
category = models.CharField(max_length=16, choices=Category.choices, verbose_name=_('Category'))
type = models.CharField(max_length=16, choices=Category.get_all_type_choices(), verbose_name=_('Type'))
attrs = JSONField()
comment = models.TextField(
max_length=128, default='', blank=True, verbose_name=_('Comment')
)
objects = QuerySet.as_manager()
class Meta:
unique_together = [('org_id', 'name')]
ordering = ('name',)

View File

@ -1,3 +1,4 @@
from .application import *
from .remote_app import *
from .database_app import *
from .k8s_app import *

View File

@ -0,0 +1,46 @@
# coding: utf-8
#
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .. import models
__all__ = [
'ApplicationSerializer',
]
class ApplicationSerializer(BulkOrgResourceModelSerializer):
class Meta:
model = models.Application
fields = [
'id', 'name', 'category', 'type', 'get_type_display', 'attrs',
'created_by', 'date_created', 'date_updated', 'comment'
]
read_only_fields = [
'created_by', 'date_created', 'date_updated', 'get_type_display',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
app_type = ''
attrs_data = {}
if self.instance:
app_type = self.instance.type
attrs_data = self.instance.attrs
request = self.context.get('request')
if request:
app_type = request.query_params.get('type')
if hasattr(self, 'initial_data'):
app_type = self.initial_data.get('type')
attrs_data = self.initial_data.get('attrs')
if not app_type:
return
attrs_cls = models.Category.get_type_serializer_cls(app_type)
if attrs_data:
attrs_serializer = attrs_cls(data=attrs_data)
else:
attrs_serializer = attrs_cls()
self.fields['attrs'] = attrs_serializer

View File

@ -1,14 +1,34 @@
# coding: utf-8
#
from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from common.serializers import AdaptedBulkListSerializer
from .. import models
__all__ = [
'DatabaseAppSerializer',
]
class DatabaseAttrsSerializer(serializers.Serializer):
host = serializers.CharField()
port = serializers.IntegerField()
database = serializers.CharField(allow_blank=True, allow_null=True)
class MySQLAttrsSerializer(DatabaseAttrsSerializer):
port = serializers.IntegerField(default=3306, label=_('Port'))
class PostgreAttrsSerializer(DatabaseAttrsSerializer):
port = serializers.IntegerField(default=5432)
class OracleAttrsSerializer(DatabaseAttrsSerializer):
port = serializers.IntegerField(default=1521)
class MariaDBAttrsSerializer(MySQLAttrsSerializer):
pass
class DatabaseAppSerializer(BulkOrgResourceModelSerializer):

View File

@ -1,11 +1,12 @@
from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .. import models
__all__ = [
'K8sAppSerializer',
]
class K8sAttrsSerializer(serializers.Serializer):
cluster = serializers.CharField(label=_('Cluster'))
class K8sAppSerializer(BulkOrgResourceModelSerializer):

View File

@ -2,19 +2,54 @@
#
import copy
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from common.serializers import AdaptedBulkListSerializer
from common.fields.serializer import CustomMetaDictField
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from assets.models import Asset
from .. import const
from ..models import RemoteApp
__all__ = [
'RemoteAppSerializer', 'RemoteAppConnectionInfoSerializer',
]
class RemoteAppAttrsSerializer(serializers.Serializer):
asset = serializers.PrimaryKeyRelatedField(queryset=Asset.objects, label=_("Assets"))
path = serializers.CharField(label=_('Remote App path'))
class ChromeAttrsSerializer(RemoteAppAttrsSerializer):
REMOTE_APP_PATH = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
path = serializers.CharField(label=_('Remote App path'), default=REMOTE_APP_PATH)
chrome_target = serializers.CharField(label=_('Target URL'))
chrome_username = serializers.CharField(label=_('Username'))
chrome_password = serializers.CharField(write_only=True, label=_('Password'))
class MySQLWorkbenchAttrsSerializer(RemoteAppAttrsSerializer):
REMOTE_APP_PATH = 'C:\Program Files\MySQL\MySQL Workbench 8.0 CE\MySQLWorkbench.exe'
path = serializers.CharField(label=_('Remote App path'), default=REMOTE_APP_PATH)
mysql_workbench_ip = serializers.CharField(label=_('IP'))
mysql_workbench_port = serializers.IntegerField(label=_('Port'))
mysql_workbench_name = serializers.CharField(label=_('Database'))
mysql_workbench_username = serializers.CharField(label=_('Username'))
mysql_workbench_password = serializers.CharField(write_only=True, label=_('Password'))
class VMwareClientAttrsSerializer(RemoteAppAttrsSerializer):
REMOTE_APP_PATH = 'C:\Program Files (x86)\VMware\Infrastructure\Virtual Infrastructure Client\Launcher\VpxClient.exe'
path = serializers.CharField(label=_('Remote App path'), default=REMOTE_APP_PATH)
vmware_target = serializers.CharField(label=_('Target URL'))
vmware_username = serializers.CharField(label=_('Username'))
vmware_password = serializers.CharField(write_only=True, label=_('Password'))
class CustomRemoteAppAttrsSeralizers(RemoteAppAttrsSerializer):
custom_cmdline = serializers.CharField(label=_('Operating parameter'))
custom_target = serializers.CharField(label=_('Target url'))
custom_username = serializers.CharField(label=_('Username'))
custom_password = serializers.CharField(write_only=True, label=_('Password'))
class RemoteAppParamsDictField(CustomMetaDictField):

View File

@ -10,6 +10,7 @@ from .. import api
app_name = 'applications'
router = BulkRouter()
router.register(r'applications', api.ApplicationViewSet, 'application')
router.register(r'remote-apps', api.RemoteAppViewSet, 'remote-app')
router.register(r'database-apps', api.DatabaseAppViewSet, 'database-app')
router.register(r'k8s-apps', api.K8sAppViewSet, 'k8s-app')

View File

@ -7,6 +7,7 @@ from collections import OrderedDict
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.utils.encoding import force_text
from rest_framework.fields import empty
from rest_framework.metadata import SimpleMetadata
from rest_framework import exceptions, serializers
@ -58,6 +59,10 @@ class SimpleMetadataWithFilters(SimpleMetadata):
field_info['type'] = self.label_lookup[field]
field_info['required'] = getattr(field, 'required', False)
default = getattr(field, 'default', False)
if default and isinstance(default, (str, int)):
field_info['default'] = default
for attr in self.attrs:
value = getattr(field, attr, None)
if value is not None and value != '':