mirror of https://github.com/jumpserver/jumpserver
refacter: 重构application
parent
874a3eeebf
commit
ba4e6e9a9f
|
@ -1,3 +1,4 @@
|
||||||
|
from .application import *
|
||||||
from .remote_app import *
|
from .remote_app import *
|
||||||
from .database_app import *
|
from .database_app import *
|
||||||
from .k8s_app import *
|
from .k8s_app import *
|
||||||
|
|
|
@ -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
|
|
@ -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')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,3 +1,4 @@
|
||||||
|
from .application import *
|
||||||
from .remote_app import *
|
from .remote_app import *
|
||||||
from .database_app import *
|
from .database_app import *
|
||||||
from .k8s_app import *
|
from .k8s_app import *
|
||||||
|
|
|
@ -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',)
|
|
@ -1,3 +1,4 @@
|
||||||
|
from .application import *
|
||||||
from .remote_app import *
|
from .remote_app import *
|
||||||
from .database_app import *
|
from .database_app import *
|
||||||
from .k8s_app import *
|
from .k8s_app import *
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,14 +1,34 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
#
|
#
|
||||||
|
from rest_framework import serializers
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
from common.serializers import AdaptedBulkListSerializer
|
from common.serializers import AdaptedBulkListSerializer
|
||||||
|
|
||||||
from .. import models
|
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):
|
class DatabaseAppSerializer(BulkOrgResourceModelSerializer):
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
from .. import models
|
from .. import models
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'K8sAppSerializer',
|
class K8sAttrsSerializer(serializers.Serializer):
|
||||||
]
|
cluster = serializers.CharField(label=_('Cluster'))
|
||||||
|
|
||||||
|
|
||||||
class K8sAppSerializer(BulkOrgResourceModelSerializer):
|
class K8sAppSerializer(BulkOrgResourceModelSerializer):
|
||||||
|
|
|
@ -2,19 +2,54 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from common.serializers import AdaptedBulkListSerializer
|
from common.serializers import AdaptedBulkListSerializer
|
||||||
from common.fields.serializer import CustomMetaDictField
|
from common.fields.serializer import CustomMetaDictField
|
||||||
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
|
from assets.models import Asset
|
||||||
|
|
||||||
from .. import const
|
from .. import const
|
||||||
from ..models import RemoteApp
|
from ..models import RemoteApp
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
class RemoteAppAttrsSerializer(serializers.Serializer):
|
||||||
'RemoteAppSerializer', 'RemoteAppConnectionInfoSerializer',
|
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):
|
class RemoteAppParamsDictField(CustomMetaDictField):
|
||||||
|
|
|
@ -10,6 +10,7 @@ from .. import api
|
||||||
app_name = 'applications'
|
app_name = 'applications'
|
||||||
|
|
||||||
router = BulkRouter()
|
router = BulkRouter()
|
||||||
|
router.register(r'applications', api.ApplicationViewSet, 'application')
|
||||||
router.register(r'remote-apps', api.RemoteAppViewSet, 'remote-app')
|
router.register(r'remote-apps', api.RemoteAppViewSet, 'remote-app')
|
||||||
router.register(r'database-apps', api.DatabaseAppViewSet, 'database-app')
|
router.register(r'database-apps', api.DatabaseAppViewSet, 'database-app')
|
||||||
router.register(r'k8s-apps', api.K8sAppViewSet, 'k8s-app')
|
router.register(r'k8s-apps', api.K8sAppViewSet, 'k8s-app')
|
||||||
|
|
|
@ -7,6 +7,7 @@ from collections import OrderedDict
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
from rest_framework.fields import empty
|
||||||
|
|
||||||
from rest_framework.metadata import SimpleMetadata
|
from rest_framework.metadata import SimpleMetadata
|
||||||
from rest_framework import exceptions, serializers
|
from rest_framework import exceptions, serializers
|
||||||
|
@ -58,6 +59,10 @@ class SimpleMetadataWithFilters(SimpleMetadata):
|
||||||
field_info['type'] = self.label_lookup[field]
|
field_info['type'] = self.label_lookup[field]
|
||||||
field_info['required'] = getattr(field, 'required', False)
|
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:
|
for attr in self.attrs:
|
||||||
value = getattr(field, attr, None)
|
value = getattr(field, attr, None)
|
||||||
if value is not None and value != '':
|
if value is not None and value != '':
|
||||||
|
|
Loading…
Reference in New Issue