mirror of https://github.com/jumpserver/jumpserver
feat(applications): 添加 k8s 应用
parent
0a242c3e81
commit
91649a3908
|
@ -1,2 +1,3 @@
|
||||||
from .remote_app import *
|
from .remote_app import *
|
||||||
from .database_app import *
|
from .database_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__ = [
|
||||||
|
'K8sAppViewSet',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppViewSet(OrgBulkModelViewSet):
|
||||||
|
model = models.K8sApp
|
||||||
|
filter_fields = ('name',)
|
||||||
|
search_fields = filter_fields
|
||||||
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
serializer_class = serializers.K8sAppSerializer
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Generated by Django 2.2.13 on 2020-08-07 07:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('applications', '0004_auto_20191218_1705'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='K8sApp',
|
||||||
|
fields=[
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')),
|
||||||
|
('updated_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated 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')),
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
|
||||||
|
('org_id', models.CharField(blank=True, db_index=True, default='', max_length=36, verbose_name='Organization')),
|
||||||
|
('name', models.CharField(max_length=128, verbose_name='Name')),
|
||||||
|
('type', models.CharField(choices=[('k8s', 'Kubernetes')], default='k8s', max_length=128, verbose_name='Type')),
|
||||||
|
('cluster', models.CharField(max_length=1024, verbose_name='Cluster')),
|
||||||
|
('comment', models.TextField(blank=True, default='', max_length=128, verbose_name='Comment')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'KubernetesApp',
|
||||||
|
'ordering': ('name',),
|
||||||
|
'unique_together': {('org_id', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,2 +1,3 @@
|
||||||
from .remote_app import *
|
from .remote_app import *
|
||||||
from .database_app import *
|
from .database_app import *
|
||||||
|
from .k8s_app import *
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from common.db import models
|
||||||
|
from orgs.mixins.models import OrgModelMixin
|
||||||
|
|
||||||
|
|
||||||
|
class K8sApp(OrgModelMixin, models.JMSModel):
|
||||||
|
class TYPE(models.ChoiceSet):
|
||||||
|
K8S = 'k8s', _('Kubernetes')
|
||||||
|
|
||||||
|
name = models.CharField(max_length=128, verbose_name=_('Name'))
|
||||||
|
type = models.CharField(
|
||||||
|
default=TYPE.K8S, choices=TYPE.choices,
|
||||||
|
max_length=128, verbose_name=_('Type')
|
||||||
|
)
|
||||||
|
cluster = models.CharField(max_length=1024, verbose_name=_('Cluster'))
|
||||||
|
comment = models.TextField(
|
||||||
|
max_length=128, default='', blank=True, verbose_name=_('Comment')
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = [('org_id', 'name'), ]
|
||||||
|
verbose_name = _('KubernetesApp')
|
||||||
|
ordering = ('name', )
|
|
@ -1,2 +1,3 @@
|
||||||
from .remote_app import *
|
from .remote_app import *
|
||||||
from .database_app import *
|
from .database_app import *
|
||||||
|
from .k8s_app import *
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
|
from .. import models
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'K8sAppSerializer',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppSerializer(BulkOrgResourceModelSerializer):
|
||||||
|
type_display = serializers.CharField(source='get_type_display', read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sApp
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'type', 'type_display', 'comment', 'created_by',
|
||||||
|
'date_created', 'date_updated', 'cluster'
|
||||||
|
]
|
||||||
|
read_only_fields = [
|
||||||
|
'id', 'created_by', 'date_created', 'date_updated',
|
||||||
|
]
|
|
@ -12,6 +12,7 @@ app_name = 'applications'
|
||||||
router = BulkRouter()
|
router = BulkRouter()
|
||||||
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')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('remote-apps/<uuid:pk>/connection-info/', api.RemoteAppConnectionInfoApi.as_view(), name='remote-app-connection-info'),
|
path('remote-apps/<uuid:pk>/connection-info/', api.RemoteAppConnectionInfoApi.as_view(), name='remote-app-connection-info'),
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 2.2.13 on 2020-08-07 02:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('assets', '0053_auto_20200723_1232'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='systemuser',
|
||||||
|
name='token',
|
||||||
|
field=models.TextField(default='', verbose_name='Token'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='systemuser',
|
||||||
|
name='protocol',
|
||||||
|
field=models.CharField(choices=[('ssh', 'ssh'), ('rdp', 'rdp'), ('telnet', 'telnet'), ('vnc', 'vnc'), ('mysql', 'mysql'), ('k8s', 'k8s')], default='ssh', max_length=16, verbose_name='Protocol'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -91,12 +91,14 @@ class SystemUser(BaseUser):
|
||||||
PROTOCOL_TELNET = 'telnet'
|
PROTOCOL_TELNET = 'telnet'
|
||||||
PROTOCOL_VNC = 'vnc'
|
PROTOCOL_VNC = 'vnc'
|
||||||
PROTOCOL_MYSQL = 'mysql'
|
PROTOCOL_MYSQL = 'mysql'
|
||||||
|
PROTOCOL_K8S = 'k8s'
|
||||||
PROTOCOL_CHOICES = (
|
PROTOCOL_CHOICES = (
|
||||||
(PROTOCOL_SSH, 'ssh'),
|
(PROTOCOL_SSH, 'ssh'),
|
||||||
(PROTOCOL_RDP, 'rdp'),
|
(PROTOCOL_RDP, 'rdp'),
|
||||||
(PROTOCOL_TELNET, 'telnet'),
|
(PROTOCOL_TELNET, 'telnet'),
|
||||||
(PROTOCOL_VNC, 'vnc'),
|
(PROTOCOL_VNC, 'vnc'),
|
||||||
(PROTOCOL_MYSQL, 'mysql'),
|
(PROTOCOL_MYSQL, 'mysql'),
|
||||||
|
(PROTOCOL_K8S, 'k8s'),
|
||||||
)
|
)
|
||||||
|
|
||||||
LOGIN_AUTO = 'auto'
|
LOGIN_AUTO = 'auto'
|
||||||
|
@ -118,6 +120,7 @@ class SystemUser(BaseUser):
|
||||||
login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=LOGIN_AUTO, max_length=10, verbose_name=_('Login mode'))
|
login_mode = models.CharField(choices=LOGIN_MODE_CHOICES, default=LOGIN_AUTO, max_length=10, verbose_name=_('Login mode'))
|
||||||
cmd_filters = models.ManyToManyField('CommandFilter', related_name='system_users', verbose_name=_("Command filter"), blank=True)
|
cmd_filters = models.ManyToManyField('CommandFilter', related_name='system_users', verbose_name=_("Command filter"), blank=True)
|
||||||
sftp_root = models.CharField(default='tmp', max_length=128, verbose_name=_("SFTP Root"))
|
sftp_root = models.CharField(default='tmp', max_length=128, verbose_name=_("SFTP Root"))
|
||||||
|
token = models.TextField(default='', verbose_name=_('Token'))
|
||||||
_prefer = 'system_user'
|
_prefer = 'system_user'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -33,13 +33,14 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
'login_mode', 'login_mode_display',
|
'login_mode', 'login_mode_display',
|
||||||
'priority', 'username_same_with_user',
|
'priority', 'username_same_with_user',
|
||||||
'auto_push', 'cmd_filters', 'sudo', 'shell', 'comment',
|
'auto_push', 'cmd_filters', 'sudo', 'shell', 'comment',
|
||||||
'auto_generate_key', 'sftp_root',
|
'auto_generate_key', 'sftp_root', 'token',
|
||||||
'assets_amount', 'date_created', 'created_by'
|
'assets_amount', 'date_created', 'created_by'
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'password': {"write_only": True},
|
'password': {"write_only": True},
|
||||||
'public_key': {"write_only": True},
|
'public_key': {"write_only": True},
|
||||||
'private_key': {"write_only": True},
|
'private_key': {"write_only": True},
|
||||||
|
'token': {"write_only": True},
|
||||||
'nodes_amount': {'label': _('Node')},
|
'nodes_amount': {'label': _('Node')},
|
||||||
'assets_amount': {'label': _('Asset')},
|
'assets_amount': {'label': _('Asset')},
|
||||||
'login_mode_display': {'label': _('Login mode display')},
|
'login_mode_display': {'label': _('Login mode display')},
|
||||||
|
@ -169,7 +170,7 @@ class SystemUserWithAuthInfoSerializer(SystemUserSerializer):
|
||||||
'login_mode', 'login_mode_display',
|
'login_mode', 'login_mode_display',
|
||||||
'priority', 'username_same_with_user',
|
'priority', 'username_same_with_user',
|
||||||
'auto_push', 'sudo', 'shell', 'comment',
|
'auto_push', 'sudo', 'shell', 'comment',
|
||||||
'auto_generate_key', 'sftp_root',
|
'auto_generate_key', 'sftp_root', 'token'
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'nodes_amount': {'label': _('Node')},
|
'nodes_amount': {'label': _('Node')},
|
||||||
|
|
Binary file not shown.
|
@ -21,15 +21,15 @@ msgstr ""
|
||||||
msgid "Custom"
|
msgid "Custom"
|
||||||
msgstr "自定义"
|
msgstr "自定义"
|
||||||
|
|
||||||
#: applications/models/database_app.py:18 applications/models/remote_app.py:21
|
#: applications/models/database_app.py:18 applications/models/k8s_app.py:11
|
||||||
#: assets/models/asset.py:145 assets/models/base.py:232
|
#: applications/models/remote_app.py:21 assets/models/asset.py:145
|
||||||
#: assets/models/cluster.py:18 assets/models/cmd_filter.py:21
|
#: assets/models/base.py:232 assets/models/cluster.py:18
|
||||||
#: assets/models/domain.py:20 assets/models/group.py:20
|
#: assets/models/cmd_filter.py:21 assets/models/domain.py:20
|
||||||
#: assets/models/label.py:18 ops/mixin.py:24 orgs/models.py:22
|
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
|
||||||
#: perms/models/base.py:48 settings/models.py:27 terminal/models.py:26
|
#: orgs/models.py:22 perms/models/base.py:48 settings/models.py:27
|
||||||
#: terminal/models.py:342 terminal/models.py:374 terminal/models.py:411
|
#: terminal/models.py:26 terminal/models.py:342 terminal/models.py:374
|
||||||
#: users/forms/profile.py:20 users/models/group.py:15 users/models/user.py:489
|
#: terminal/models.py:411 users/forms/profile.py:20 users/models/group.py:15
|
||||||
#: users/templates/users/_select_user_modal.html:13
|
#: users/models/user.py:489 users/templates/users/_select_user_modal.html:13
|
||||||
#: users/templates/users/user_asset_permission.html:37
|
#: users/templates/users/user_asset_permission.html:37
|
||||||
#: users/templates/users/user_asset_permission.html:154
|
#: users/templates/users/user_asset_permission.html:154
|
||||||
#: users/templates/users/user_database_app_permission.html:36
|
#: users/templates/users/user_database_app_permission.html:36
|
||||||
|
@ -46,8 +46,9 @@ msgstr "自定义"
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "名称"
|
msgstr "名称"
|
||||||
|
|
||||||
#: applications/models/database_app.py:22 assets/models/cmd_filter.py:52
|
#: applications/models/database_app.py:22 applications/models/k8s_app.py:14
|
||||||
#: terminal/models.py:376 terminal/models.py:413 tickets/models/ticket.py:40
|
#: assets/models/cmd_filter.py:52 terminal/models.py:376 terminal/models.py:413
|
||||||
|
#: tickets/models/ticket.py:40
|
||||||
#: users/templates/users/user_granted_database_app.html:35
|
#: users/templates/users/user_granted_database_app.html:35
|
||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "类型"
|
msgstr "类型"
|
||||||
|
@ -69,16 +70,16 @@ msgstr "数据库"
|
||||||
|
|
||||||
# msgid "Date created"
|
# msgid "Date created"
|
||||||
# msgstr "创建日期"
|
# msgstr "创建日期"
|
||||||
#: applications/models/database_app.py:33 applications/models/remote_app.py:45
|
#: applications/models/database_app.py:33 applications/models/k8s_app.py:18
|
||||||
#: assets/models/asset.py:150 assets/models/asset.py:226
|
#: applications/models/remote_app.py:45 assets/models/asset.py:150
|
||||||
#: assets/models/base.py:237 assets/models/cluster.py:29
|
#: assets/models/asset.py:226 assets/models/base.py:237
|
||||||
#: assets/models/cmd_filter.py:23 assets/models/cmd_filter.py:57
|
#: assets/models/cluster.py:29 assets/models/cmd_filter.py:23
|
||||||
#: assets/models/domain.py:21 assets/models/domain.py:54
|
#: assets/models/cmd_filter.py:57 assets/models/domain.py:21
|
||||||
#: assets/models/group.py:23 assets/models/label.py:23 ops/models/adhoc.py:37
|
#: assets/models/domain.py:54 assets/models/group.py:23
|
||||||
#: orgs/models.py:25 perms/models/base.py:56 settings/models.py:32
|
#: assets/models/label.py:23 ops/models/adhoc.py:37 orgs/models.py:25
|
||||||
#: terminal/models.py:36 terminal/models.py:381 terminal/models.py:418
|
#: perms/models/base.py:56 settings/models.py:32 terminal/models.py:36
|
||||||
#: users/models/group.py:16 users/models/user.py:522
|
#: terminal/models.py:381 terminal/models.py:418 users/models/group.py:16
|
||||||
#: users/templates/users/user_detail.html:115
|
#: users/models/user.py:522 users/templates/users/user_detail.html:115
|
||||||
#: users/templates/users/user_granted_database_app.html:38
|
#: users/templates/users/user_granted_database_app.html:38
|
||||||
#: users/templates/users/user_granted_remote_app.html:37
|
#: users/templates/users/user_granted_remote_app.html:37
|
||||||
#: users/templates/users/user_group_detail.html:62
|
#: users/templates/users/user_group_detail.html:62
|
||||||
|
@ -99,6 +100,19 @@ msgstr "备注"
|
||||||
msgid "DatabaseApp"
|
msgid "DatabaseApp"
|
||||||
msgstr "数据库应用"
|
msgstr "数据库应用"
|
||||||
|
|
||||||
|
#: applications/models/k8s_app.py:9
|
||||||
|
msgid "Kubernetes"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/models/k8s_app.py:16 assets/models/cluster.py:40
|
||||||
|
msgid "Cluster"
|
||||||
|
msgstr "集群"
|
||||||
|
|
||||||
|
#: applications/models/k8s_app.py:26 perms/models/k8s_app_permission.py:18
|
||||||
|
#: perms/utils/k8s_app_permission.py:70
|
||||||
|
msgid "KubernetesApp"
|
||||||
|
msgstr "Kubernetes应用"
|
||||||
|
|
||||||
#: applications/models/remote_app.py:23 assets/models/asset.py:352
|
#: applications/models/remote_app.py:23 assets/models/asset.py:352
|
||||||
#: assets/models/authbook.py:26 assets/models/gathered_user.py:14
|
#: assets/models/authbook.py:26 assets/models/gathered_user.py:14
|
||||||
#: assets/serializers/admin_user.py:32 assets/serializers/asset_user.py:47
|
#: assets/serializers/admin_user.py:32 assets/serializers/asset_user.py:47
|
||||||
|
@ -219,12 +233,12 @@ msgid "Hostname"
|
||||||
msgstr "主机名"
|
msgstr "主机名"
|
||||||
|
|
||||||
#: assets/models/asset.py:190 assets/models/domain.py:52
|
#: assets/models/asset.py:190 assets/models/domain.py:52
|
||||||
#: assets/models/user.py:114 terminal/serializers/session.py:29
|
#: assets/models/user.py:116 terminal/serializers/session.py:29
|
||||||
msgid "Protocol"
|
msgid "Protocol"
|
||||||
msgstr "协议"
|
msgstr "协议"
|
||||||
|
|
||||||
#: assets/models/asset.py:192 assets/serializers/asset.py:69
|
#: assets/models/asset.py:192 assets/serializers/asset.py:69
|
||||||
#: perms/serializers/user_permission.py:60
|
#: perms/serializers/user_permission.py:71
|
||||||
msgid "Protocols"
|
msgid "Protocols"
|
||||||
msgstr "协议组"
|
msgstr "协议组"
|
||||||
|
|
||||||
|
@ -233,7 +247,7 @@ msgstr "协议组"
|
||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
msgstr "网域"
|
msgstr "网域"
|
||||||
|
|
||||||
#: assets/models/asset.py:195 assets/models/user.py:109
|
#: assets/models/asset.py:195 assets/models/user.py:111
|
||||||
#: perms/models/asset_permission.py:91
|
#: perms/models/asset_permission.py:91
|
||||||
#: xpack/plugins/change_auth_plan/models.py:56
|
#: xpack/plugins/change_auth_plan/models.py:56
|
||||||
#: xpack/plugins/gathered_user/models.py:24
|
#: xpack/plugins/gathered_user/models.py:24
|
||||||
|
@ -427,10 +441,6 @@ msgstr "系统"
|
||||||
msgid "Default Cluster"
|
msgid "Default Cluster"
|
||||||
msgstr "默认Cluster"
|
msgstr "默认Cluster"
|
||||||
|
|
||||||
#: assets/models/cluster.py:40
|
|
||||||
msgid "Cluster"
|
|
||||||
msgstr "集群"
|
|
||||||
|
|
||||||
#: assets/models/cluster.py:56
|
#: assets/models/cluster.py:56
|
||||||
msgid "Beijing unicom"
|
msgid "Beijing unicom"
|
||||||
msgstr "北京联通"
|
msgstr "北京联通"
|
||||||
|
@ -443,7 +453,7 @@ msgstr "北京电信"
|
||||||
msgid "BGP full netcom"
|
msgid "BGP full netcom"
|
||||||
msgstr "BGP全网通"
|
msgstr "BGP全网通"
|
||||||
|
|
||||||
#: assets/models/cmd_filter.py:33 assets/models/user.py:119
|
#: assets/models/cmd_filter.py:33 assets/models/user.py:121
|
||||||
msgid "Command filter"
|
msgid "Command filter"
|
||||||
msgstr "命令过滤器"
|
msgstr "命令过滤器"
|
||||||
|
|
||||||
|
@ -468,7 +478,7 @@ msgstr "允许"
|
||||||
msgid "Filter"
|
msgid "Filter"
|
||||||
msgstr "过滤器"
|
msgstr "过滤器"
|
||||||
|
|
||||||
#: assets/models/cmd_filter.py:53 assets/models/user.py:113
|
#: assets/models/cmd_filter.py:53 assets/models/user.py:115
|
||||||
msgid "Priority"
|
msgid "Priority"
|
||||||
msgstr "优先级"
|
msgstr "优先级"
|
||||||
|
|
||||||
|
@ -597,57 +607,62 @@ msgstr "键"
|
||||||
msgid "Node"
|
msgid "Node"
|
||||||
msgstr "节点"
|
msgstr "节点"
|
||||||
|
|
||||||
#: assets/models/user.py:105
|
#: assets/models/user.py:107
|
||||||
msgid "Automatic login"
|
msgid "Automatic login"
|
||||||
msgstr "自动登录"
|
msgstr "自动登录"
|
||||||
|
|
||||||
#: assets/models/user.py:106
|
#: assets/models/user.py:108
|
||||||
msgid "Manually login"
|
msgid "Manually login"
|
||||||
msgstr "手动登录"
|
msgstr "手动登录"
|
||||||
|
|
||||||
#: assets/models/user.py:108
|
#: assets/models/user.py:110
|
||||||
msgid "Username same with user"
|
msgid "Username same with user"
|
||||||
msgstr "用户名与用户相同"
|
msgstr "用户名与用户相同"
|
||||||
|
|
||||||
#: assets/models/user.py:110 templates/_nav.html:39
|
#: assets/models/user.py:112 templates/_nav.html:39
|
||||||
#: xpack/plugins/change_auth_plan/models.py:52
|
#: xpack/plugins/change_auth_plan/models.py:52
|
||||||
msgid "Assets"
|
msgid "Assets"
|
||||||
msgstr "资产管理"
|
msgstr "资产管理"
|
||||||
|
|
||||||
#: assets/models/user.py:111 templates/_nav.html:17
|
#: assets/models/user.py:113 templates/_nav.html:17
|
||||||
#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
|
#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
|
||||||
msgid "Users"
|
msgid "Users"
|
||||||
msgstr "用户管理"
|
msgstr "用户管理"
|
||||||
|
|
||||||
#: assets/models/user.py:112 users/templates/users/user_group_list.html:90
|
#: assets/models/user.py:114 users/templates/users/user_group_list.html:90
|
||||||
#: users/templates/users/user_profile.html:124
|
#: users/templates/users/user_profile.html:124
|
||||||
msgid "User groups"
|
msgid "User groups"
|
||||||
msgstr "用户组"
|
msgstr "用户组"
|
||||||
|
|
||||||
#: assets/models/user.py:115
|
#: assets/models/user.py:117
|
||||||
msgid "Auto push"
|
msgid "Auto push"
|
||||||
msgstr "自动推送"
|
msgstr "自动推送"
|
||||||
|
|
||||||
#: assets/models/user.py:116
|
#: assets/models/user.py:118
|
||||||
msgid "Sudo"
|
msgid "Sudo"
|
||||||
msgstr "Sudo"
|
msgstr "Sudo"
|
||||||
|
|
||||||
#: assets/models/user.py:117
|
#: assets/models/user.py:119
|
||||||
msgid "Shell"
|
msgid "Shell"
|
||||||
msgstr "Shell"
|
msgstr "Shell"
|
||||||
|
|
||||||
#: assets/models/user.py:118
|
#: assets/models/user.py:120
|
||||||
msgid "Login mode"
|
msgid "Login mode"
|
||||||
msgstr "登录模式"
|
msgstr "登录模式"
|
||||||
|
|
||||||
#: assets/models/user.py:120
|
#: assets/models/user.py:122
|
||||||
msgid "SFTP Root"
|
msgid "SFTP Root"
|
||||||
msgstr "SFTP根路径"
|
msgstr "SFTP根路径"
|
||||||
|
|
||||||
#: assets/models/user.py:195 audits/models.py:39
|
#: assets/models/user.py:123 authentication/models.py:88
|
||||||
|
msgid "Token"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: assets/models/user.py:198 audits/models.py:39
|
||||||
#: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49
|
#: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49
|
||||||
#: perms/models/asset_permission.py:92
|
#: perms/models/asset_permission.py:92
|
||||||
#: perms/models/database_app_permission.py:22
|
#: perms/models/database_app_permission.py:22
|
||||||
|
#: perms/models/k8s_app_permission.py:22
|
||||||
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45
|
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45
|
||||||
#: terminal/backends/command/models.py:20
|
#: terminal/backends/command/models.py:20
|
||||||
#: terminal/backends/command/serializers.py:14 terminal/models.py:189
|
#: terminal/backends/command/serializers.py:14 terminal/models.py:189
|
||||||
|
@ -1212,10 +1227,6 @@ msgstr "登录复核"
|
||||||
msgid "City"
|
msgid "City"
|
||||||
msgstr "城市"
|
msgstr "城市"
|
||||||
|
|
||||||
#: authentication/models.py:88
|
|
||||||
msgid "Token"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: authentication/models.py:89
|
#: authentication/models.py:89
|
||||||
msgid "Expired"
|
msgid "Expired"
|
||||||
msgstr "过期时间"
|
msgstr "过期时间"
|
||||||
|
@ -1780,6 +1791,10 @@ msgstr "失效日期"
|
||||||
msgid "DatabaseApp permission"
|
msgid "DatabaseApp permission"
|
||||||
msgstr "数据库应用授权"
|
msgstr "数据库应用授权"
|
||||||
|
|
||||||
|
#: perms/models/k8s_app_permission.py:27
|
||||||
|
msgid "KubernetesApp permission"
|
||||||
|
msgstr "Kubernetes应用授权"
|
||||||
|
|
||||||
#: perms/models/remote_app_permission.py:20
|
#: perms/models/remote_app_permission.py:20
|
||||||
#: users/templates/users/_user_detail_nav_header.html:47
|
#: users/templates/users/_user_detail_nav_header.html:47
|
||||||
msgid "RemoteApp permission"
|
msgid "RemoteApp permission"
|
||||||
|
|
|
@ -12,3 +12,6 @@ from .database_app_permission import *
|
||||||
from .database_app_permission_relation import *
|
from .database_app_permission_relation import *
|
||||||
from .user_database_app_permission import *
|
from .user_database_app_permission import *
|
||||||
from .system_user_permission import *
|
from .system_user_permission import *
|
||||||
|
from .k8s_app_permission import *
|
||||||
|
from .k8s_app_permission_relation import *
|
||||||
|
from .user_k8s_app_permission import *
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
from orgs.mixins.api import OrgBulkModelViewSet
|
||||||
|
|
||||||
|
from .. import models, serializers
|
||||||
|
from common.permissions import IsOrgAdmin
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['K8sAppPermissionViewSet']
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionViewSet(OrgBulkModelViewSet):
|
||||||
|
model = models.K8sAppPermission
|
||||||
|
serializer_classes = {
|
||||||
|
'default': serializers.K8sAppPermissionSerializer,
|
||||||
|
'display': serializers.K8sAppPermissionListSerializer
|
||||||
|
}
|
||||||
|
filter_fields = ('name',)
|
||||||
|
search_fields = filter_fields
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
|
@ -0,0 +1,111 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
from rest_framework import generics
|
||||||
|
from django.db.models import F, Value
|
||||||
|
from django.db.models.functions import Concat
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from common.permissions import IsOrgAdmin
|
||||||
|
from .base import RelationViewSet
|
||||||
|
from .. import models, serializers
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionUserRelationViewSet(RelationViewSet):
|
||||||
|
serializer_class = serializers.K8sAppPermissionUserRelationSerializer
|
||||||
|
m2m_field = models.K8sAppPermission.users.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', 'user', 'k8sapppermission'
|
||||||
|
]
|
||||||
|
search_fields = ('user__name', 'user__username', 'k8sapppermission__name')
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset.annotate(user_display=F('user__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionUserGroupRelationViewSet(RelationViewSet):
|
||||||
|
serializer_class = serializers.K8sAppPermissionUserGroupRelationSerializer
|
||||||
|
m2m_field = models.K8sAppPermission.user_groups.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', "usergroup", "k8sapppermission"
|
||||||
|
]
|
||||||
|
search_fields = ["usergroup__name", "k8sapppermission__name"]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset \
|
||||||
|
.annotate(usergroup_display=F('usergroup__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionAllUserListApi(generics.ListAPIView):
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
serializer_class = serializers.K8sAppPermissionAllUserSerializer
|
||||||
|
filter_fields = ("username", "name")
|
||||||
|
search_fields = filter_fields
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
pk = self.kwargs.get("pk")
|
||||||
|
perm = get_object_or_404(models.K8sAppPermission, pk=pk)
|
||||||
|
users = perm.get_all_users().only(
|
||||||
|
*self.serializer_class.Meta.only_fields
|
||||||
|
)
|
||||||
|
return users
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionK8sAppRelationViewSet(RelationViewSet):
|
||||||
|
serializer_class = serializers.K8sAppPermissionK8sAppRelationSerializer
|
||||||
|
m2m_field = models.K8sAppPermission.k8s_apps.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', 'k8sapp', 'k8sapppermission',
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
"id", "k8sapp__name", "k8sapppermission__name"
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset \
|
||||||
|
.annotate(k8sapp_display=F('k8sapp__name'))
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionAllK8sAppListApi(generics.ListAPIView):
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
serializer_class = serializers.K8sAppPermissionAllK8sAppSerializer
|
||||||
|
filter_fields = ("name",)
|
||||||
|
search_fields = filter_fields
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
pk = self.kwargs.get("pk")
|
||||||
|
perm = get_object_or_404(models.K8sAppPermission, pk=pk)
|
||||||
|
database_apps = perm.get_all_k8s_apps().only(
|
||||||
|
*self.serializer_class.Meta.only_fields
|
||||||
|
)
|
||||||
|
return database_apps
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionSystemUserRelationViewSet(RelationViewSet):
|
||||||
|
serializer_class = serializers.K8sAppPermissionSystemUserRelationSerializer
|
||||||
|
m2m_field = models.K8sAppPermission.system_users.field
|
||||||
|
permission_classes = (IsOrgAdmin,)
|
||||||
|
filter_fields = [
|
||||||
|
'id', 'systemuser', 'k8sapppermission'
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
'k8sapppermission__name', 'systemuser__name', 'systemuser__username'
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
queryset = queryset.annotate(
|
||||||
|
systemuser_display=Concat(
|
||||||
|
F('systemuser__name'), Value('('), F('systemuser__username'),
|
||||||
|
Value(')')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return queryset
|
|
@ -0,0 +1,119 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from rest_framework.views import APIView, Response
|
||||||
|
from common.permissions import IsOrgAdminOrAppUser, IsValidUser
|
||||||
|
from common.tree import TreeNodeSerializer
|
||||||
|
from orgs.mixins import generics
|
||||||
|
from users.models import User, UserGroup
|
||||||
|
from applications.serializers import K8sAppSerializer
|
||||||
|
from applications.models import K8sApp
|
||||||
|
from assets.models import SystemUser
|
||||||
|
from .. import utils, serializers
|
||||||
|
from .mixin import UserPermissionMixin
|
||||||
|
|
||||||
|
|
||||||
|
class UserGrantedK8sAppsApi(generics.ListAPIView):
|
||||||
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
serializer_class = K8sAppSerializer
|
||||||
|
filter_fields = ['id', 'name', 'type', 'comment']
|
||||||
|
search_fields = ['name', 'comment']
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
user_id = self.kwargs.get('pk', '')
|
||||||
|
if user_id:
|
||||||
|
user = get_object_or_404(User, id=user_id)
|
||||||
|
else:
|
||||||
|
user = self.request.user
|
||||||
|
return user
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
util = utils.K8sAppPermissionUtil(self.get_object())
|
||||||
|
queryset = util.get_k8s_apps()
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_permissions(self):
|
||||||
|
if self.kwargs.get('pk') is None:
|
||||||
|
self.permission_classes = (IsValidUser,)
|
||||||
|
return super().get_permissions()
|
||||||
|
|
||||||
|
|
||||||
|
class UserGrantedK8sAppsAsTreeApi(UserGrantedK8sAppsApi):
|
||||||
|
serializer_class = TreeNodeSerializer
|
||||||
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
|
||||||
|
def get_serializer(self, k8s_apps, *args, **kwargs):
|
||||||
|
if k8s_apps is None:
|
||||||
|
k8s_apps = []
|
||||||
|
only_k8s_app = self.request.query_params.get('only', '0') == '1'
|
||||||
|
tree_root = None
|
||||||
|
data = []
|
||||||
|
if not only_k8s_app:
|
||||||
|
tree_root = utils.construct_k8s_apps_tree_root()
|
||||||
|
data.append(tree_root)
|
||||||
|
for k8s_app in k8s_apps:
|
||||||
|
node = utils.parse_k8s_app_to_tree_node(tree_root, k8s_app)
|
||||||
|
data.append(node)
|
||||||
|
data.sort()
|
||||||
|
return super().get_serializer(data, many=True)
|
||||||
|
|
||||||
|
|
||||||
|
class UserGrantedK8sAppSystemUsersApi(UserPermissionMixin, generics.ListAPIView):
|
||||||
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
serializer_class = serializers.K8sAppSystemUserSerializer
|
||||||
|
only_fields = serializers.K8sAppSystemUserSerializer.Meta.only_fields
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
util = utils.K8sAppPermissionUtil(self.obj)
|
||||||
|
k8s_app_id = self.kwargs.get('k8s_app_id')
|
||||||
|
k8s_app = get_object_or_404(K8sApp, id=k8s_app_id)
|
||||||
|
system_users = util.get_k8s_app_system_users(k8s_app)
|
||||||
|
return system_users
|
||||||
|
|
||||||
|
|
||||||
|
# Validate
|
||||||
|
|
||||||
|
class ValidateUserK8sAppPermissionApi(APIView):
|
||||||
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
user_id = request.query_params.get('user_id', '')
|
||||||
|
k8s_app_id = request.query_params.get('k8s_app_id', '')
|
||||||
|
system_user_id = request.query_params.get('system_user_id', '')
|
||||||
|
|
||||||
|
try:
|
||||||
|
user_id = uuid.UUID(user_id)
|
||||||
|
k8s_app_id = uuid.UUID(k8s_app_id)
|
||||||
|
system_user_id = uuid.UUID(system_user_id)
|
||||||
|
except ValueError:
|
||||||
|
return Response({'msg': False}, status=403)
|
||||||
|
|
||||||
|
user = get_object_or_404(User, id=user_id)
|
||||||
|
k8s_app = get_object_or_404(K8sApp, id=k8s_app_id)
|
||||||
|
system_user = get_object_or_404(SystemUser, id=system_user_id)
|
||||||
|
|
||||||
|
util = utils.K8sAppPermissionUtil(user)
|
||||||
|
system_users = util.get_k8s_app_system_users(k8s_app)
|
||||||
|
if system_user in system_users:
|
||||||
|
return Response({'msg': True}, status=200)
|
||||||
|
|
||||||
|
return Response({'msg': False}, status=403)
|
||||||
|
|
||||||
|
|
||||||
|
# UserGroup
|
||||||
|
|
||||||
|
class UserGroupGrantedK8sAppsApi(generics.ListAPIView):
|
||||||
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
serializer_class = K8sAppSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = []
|
||||||
|
user_group_id = self.kwargs.get('pk')
|
||||||
|
if not user_group_id:
|
||||||
|
return queryset
|
||||||
|
user_group = get_object_or_404(UserGroup, id=user_group_id)
|
||||||
|
util = utils.K8sAppPermissionUtil(user_group)
|
||||||
|
queryset = util.get_k8s_apps()
|
||||||
|
return queryset
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Generated by Django 2.2.13 on 2020-08-07 07:13
|
||||||
|
|
||||||
|
import common.utils.django
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.utils.timezone
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('assets', '0054_auto_20200807_1032'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('applications', '0005_k8sapp'),
|
||||||
|
('users', '0028_auto_20200728_1805'),
|
||||||
|
('perms', '0011_auto_20200721_1739'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='K8sAppPermission',
|
||||||
|
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)),
|
||||||
|
('name', models.CharField(max_length=128, verbose_name='Name')),
|
||||||
|
('is_active', models.BooleanField(default=True, verbose_name='Active')),
|
||||||
|
('date_start', models.DateTimeField(db_index=True, default=django.utils.timezone.now, verbose_name='Date start')),
|
||||||
|
('date_expired', models.DateTimeField(db_index=True, default=common.utils.django.date_expired_default, verbose_name='Date expired')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=128, verbose_name='Created by')),
|
||||||
|
('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date created')),
|
||||||
|
('comment', models.TextField(blank=True, verbose_name='Comment')),
|
||||||
|
('k8s_apps', models.ManyToManyField(blank=True, related_name='granted_by_permissions', to='applications.K8sApp', verbose_name='KubernetesApp')),
|
||||||
|
('system_users', models.ManyToManyField(related_name='granted_by_k8s_app_permissions', to='assets.SystemUser', verbose_name='System user')),
|
||||||
|
('user_groups', models.ManyToManyField(blank=True, to='users.UserGroup', verbose_name='User group')),
|
||||||
|
('users', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL, verbose_name='User')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'KubernetesApp permission',
|
||||||
|
'ordering': ('name',),
|
||||||
|
'unique_together': {('org_id', 'name')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -4,3 +4,4 @@
|
||||||
from .asset_permission import *
|
from .asset_permission import *
|
||||||
from .remote_app_permission import *
|
from .remote_app_permission import *
|
||||||
from .database_app_permission import *
|
from .database_app_permission import *
|
||||||
|
from .k8s_app_permission import *
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from common.utils import lazyproperty
|
||||||
|
from .base import BasePermission
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'K8sAppPermission',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermission(BasePermission):
|
||||||
|
k8s_apps = models.ManyToManyField(
|
||||||
|
'applications.K8sApp', related_name='granted_by_permissions',
|
||||||
|
blank=True, verbose_name=_("KubernetesApp")
|
||||||
|
)
|
||||||
|
system_users = models.ManyToManyField(
|
||||||
|
'assets.SystemUser', related_name='granted_by_k8s_app_permissions',
|
||||||
|
verbose_name=_("System user")
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = [('org_id', 'name')]
|
||||||
|
verbose_name = _('KubernetesApp permission')
|
||||||
|
ordering = ('name',)
|
||||||
|
|
||||||
|
def get_all_k8s_apps(self):
|
||||||
|
return self.k8s_apps.all()
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def k8s_apps_amount(self):
|
||||||
|
return self.k8s_apps.count()
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def system_users_amount(self):
|
||||||
|
return self.system_users.count()
|
|
@ -9,3 +9,5 @@ from .asset_permission_relation import *
|
||||||
from .database_app_permission import *
|
from .database_app_permission import *
|
||||||
from .database_app_permission_relation import *
|
from .database_app_permission_relation import *
|
||||||
from .base import *
|
from .base import *
|
||||||
|
from .k8s_app_permission import *
|
||||||
|
from .k8s_app_permission_relation import *
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
from django.db.models import Count
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
|
||||||
|
from .. import models
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'K8sAppPermissionSerializer', 'K8sAppPermissionListSerializer'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class AmountMixin:
|
||||||
|
@classmethod
|
||||||
|
def setup_eager_loading(cls, queryset):
|
||||||
|
""" Perform necessary eager loading of data. """
|
||||||
|
queryset = queryset.annotate(
|
||||||
|
users_amount=Count('users', distinct=True), user_groups_amount=Count('user_groups', distinct=True),
|
||||||
|
k8s_apps_amount=Count('k8s_apps', distinct=True),
|
||||||
|
system_users_amount=Count('system_users', distinct=True)
|
||||||
|
)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionSerializer(AmountMixin, BulkOrgResourceModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sAppPermission
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'users', 'user_groups', 'k8s_apps', 'system_users',
|
||||||
|
'comment', 'is_active', 'date_start', 'date_expired', 'is_valid',
|
||||||
|
'created_by', 'date_created', 'users_amount', 'user_groups_amount',
|
||||||
|
'k8s_apps_amount', 'system_users_amount',
|
||||||
|
]
|
||||||
|
read_only_fields = [
|
||||||
|
'created_by', 'date_created', 'users_amount', 'user_groups_amount',
|
||||||
|
'k8s_apps_amount', 'system_users_amount', 'id'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionListSerializer(AmountMixin, BulkOrgResourceModelSerializer):
|
||||||
|
is_expired = serializers.BooleanField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sAppPermission
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'comment', 'is_active', 'users_amount', 'user_groups_amount',
|
||||||
|
'date_start', 'date_expired', 'is_valid', 'k8s_apps_amount', 'system_users_amount',
|
||||||
|
'created_by', 'date_created', 'is_expired'
|
||||||
|
]
|
|
@ -0,0 +1,73 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
from perms.serializers.base import PermissionAllUserSerializer
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from common.drf.serializers import BulkModelSerializer
|
||||||
|
|
||||||
|
from .. import models
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionUserRelationSerializer(BulkModelSerializer):
|
||||||
|
user_display = serializers.ReadOnlyField()
|
||||||
|
k8sapppermission_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sAppPermission.users.through
|
||||||
|
fields = [
|
||||||
|
'id', 'user', 'user_display', 'k8sapppermission',
|
||||||
|
'k8sapppermission_display'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionUserGroupRelationSerializer(BulkModelSerializer):
|
||||||
|
usergroup_display = serializers.ReadOnlyField()
|
||||||
|
k8sapppermission_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sAppPermission.user_groups.through
|
||||||
|
fields = [
|
||||||
|
'id', 'usergroup', 'usergroup_display', 'k8sapppermission',
|
||||||
|
'k8sapppermission_display'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionAllUserSerializer(PermissionAllUserSerializer):
|
||||||
|
class Meta(PermissionAllUserSerializer.Meta):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionK8sAppRelationSerializer(BulkModelSerializer):
|
||||||
|
k8sapp_display = serializers.ReadOnlyField()
|
||||||
|
k8sapppermission_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sAppPermission.k8s_apps.through
|
||||||
|
fields = [
|
||||||
|
'id', "k8sapp", "k8sapp_display", 'k8sapppermission',
|
||||||
|
'k8sapppermission_display'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionAllK8sAppSerializer(serializers.Serializer):
|
||||||
|
k8sapp = serializers.UUIDField(read_only=True, source='id')
|
||||||
|
k8sapp_display = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
only_fields = ['id', 'name']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_k8sapp_display(obj):
|
||||||
|
return str(obj)
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionSystemUserRelationSerializer(BulkModelSerializer):
|
||||||
|
systemuser_display = serializers.ReadOnlyField()
|
||||||
|
k8sapppermission_display = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.K8sAppPermission.system_users.through
|
||||||
|
fields = [
|
||||||
|
'id', 'systemuser', 'systemuser_display', 'k8sapppermission',
|
||||||
|
'k8sapppermission_display'
|
||||||
|
]
|
|
@ -14,6 +14,7 @@ __all__ = [
|
||||||
'ActionsSerializer', 'AssetSystemUserSerializer',
|
'ActionsSerializer', 'AssetSystemUserSerializer',
|
||||||
'RemoteAppSystemUserSerializer',
|
'RemoteAppSystemUserSerializer',
|
||||||
'DatabaseAppSystemUserSerializer',
|
'DatabaseAppSystemUserSerializer',
|
||||||
|
'K8sAppSystemUserSerializer',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,6 +54,16 @@ class DatabaseAppSystemUserSerializer(serializers.ModelSerializer):
|
||||||
read_only_fields = fields
|
read_only_fields = fields
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppSystemUserSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = SystemUser
|
||||||
|
only_fields = (
|
||||||
|
'id', 'name', 'username', 'priority', 'protocol', 'login_mode',
|
||||||
|
)
|
||||||
|
fields = list(only_fields)
|
||||||
|
read_only_fields = fields
|
||||||
|
|
||||||
|
|
||||||
class AssetGrantedSerializer(serializers.ModelSerializer):
|
class AssetGrantedSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
被授权资产的数据结构
|
被授权资产的数据结构
|
||||||
|
|
|
@ -6,6 +6,7 @@ from .asset_permission import asset_permission_urlpatterns
|
||||||
from .remote_app_permission import remote_app_permission_urlpatterns
|
from .remote_app_permission import remote_app_permission_urlpatterns
|
||||||
from .database_app_permission import database_app_permission_urlpatterns
|
from .database_app_permission import database_app_permission_urlpatterns
|
||||||
from .system_user_permission import system_users_permission_urlpatterns
|
from .system_user_permission import system_users_permission_urlpatterns
|
||||||
|
from .k8s_app_permission import k8s_app_permission_urlpatterns
|
||||||
|
|
||||||
app_name = 'perms'
|
app_name = 'perms'
|
||||||
|
|
||||||
|
@ -16,5 +17,6 @@ old_version_urlpatterns = [
|
||||||
urlpatterns = asset_permission_urlpatterns + \
|
urlpatterns = asset_permission_urlpatterns + \
|
||||||
remote_app_permission_urlpatterns + \
|
remote_app_permission_urlpatterns + \
|
||||||
database_app_permission_urlpatterns + \
|
database_app_permission_urlpatterns + \
|
||||||
|
k8s_app_permission_urlpatterns + \
|
||||||
old_version_urlpatterns + \
|
old_version_urlpatterns + \
|
||||||
system_users_permission_urlpatterns
|
system_users_permission_urlpatterns
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.urls import path, include
|
||||||
|
from rest_framework_bulk.routes import BulkRouter
|
||||||
|
from .. import api
|
||||||
|
|
||||||
|
|
||||||
|
router = BulkRouter()
|
||||||
|
router.register('k8s-app-permissions', api.K8sAppPermissionViewSet, 'k8s-app-permission')
|
||||||
|
router.register('k8s-app-permissions-users-relations', api.K8sAppPermissionUserRelationViewSet, 'k8s-app-permissions-users-relation')
|
||||||
|
router.register('k8s-app-permissions-user-groups-relations', api.K8sAppPermissionUserGroupRelationViewSet, 'k8s-app-permissions-user-groups-relation')
|
||||||
|
router.register('k8s-app-permissions-k8s-apps-relations', api.K8sAppPermissionK8sAppRelationViewSet, 'k8s-app-permissions-k8s-apps-relation')
|
||||||
|
router.register('k8s-app-permissions-system-users-relations', api.K8sAppPermissionSystemUserRelationViewSet, 'k8s-app-permissions-system-users-relation')
|
||||||
|
|
||||||
|
user_permission_urlpatterns = [
|
||||||
|
path('<uuid:pk>/k8s-apps/', api.UserGrantedK8sAppsApi.as_view(), name='user-k8s-apps'),
|
||||||
|
path('k8s-apps/', api.UserGrantedK8sAppsApi.as_view(), name='my-k8s-apps'),
|
||||||
|
|
||||||
|
# k8sApps as tree
|
||||||
|
path('<uuid:pk>/k8s-apps/tree/', api.UserGrantedK8sAppsAsTreeApi.as_view(), name='user-k8ss-apps-tree'),
|
||||||
|
path('k8s-apps/tree/', api.UserGrantedK8sAppsAsTreeApi.as_view(), name='my-k8ss-apps-tree'),
|
||||||
|
|
||||||
|
path('<uuid:pk>/k8s-apps/<uuid:k8s_app_id>/system-users/', api.UserGrantedK8sAppSystemUsersApi.as_view(), name='user-k8s-app-system-users'),
|
||||||
|
path('k8s-apps/<uuid:k8s_app_id>/system-users/', api.UserGrantedK8sAppSystemUsersApi.as_view(), name='user-k8s-app-system-users'),
|
||||||
|
]
|
||||||
|
|
||||||
|
user_group_permission_urlpatterns = [
|
||||||
|
path('<uuid:pk>/k8s-apps/', api.UserGroupGrantedK8sAppsApi.as_view(), name='user-group-k8s-apps'),
|
||||||
|
]
|
||||||
|
|
||||||
|
permission_urlpatterns = [
|
||||||
|
path('<uuid:pk>/users/all/', api.K8sAppPermissionAllUserListApi.as_view(), name='k8s-app-permission-all-users'),
|
||||||
|
path('<uuid:pk>/k8s-apps/all/', api.K8sAppPermissionAllK8sAppListApi.as_view(), name='k8s-app-permission-all-k8s-apps'),
|
||||||
|
|
||||||
|
path('user/validate/', api.ValidateUserK8sAppPermissionApi.as_view(), name='validate-user-k8s-app-permission'),
|
||||||
|
]
|
||||||
|
|
||||||
|
k8s_app_permission_urlpatterns = [
|
||||||
|
path('users/', include(user_permission_urlpatterns)),
|
||||||
|
path('user-groups/', include(user_group_permission_urlpatterns)),
|
||||||
|
path('k8s-app-permissions/', include(permission_urlpatterns))
|
||||||
|
]
|
||||||
|
|
||||||
|
k8s_app_permission_urlpatterns += router.urls
|
|
@ -4,3 +4,4 @@
|
||||||
from .asset_permission import *
|
from .asset_permission import *
|
||||||
from .remote_app_permission import *
|
from .remote_app_permission import *
|
||||||
from .database_app_permission import *
|
from .database_app_permission import *
|
||||||
|
from .k8s_app_permission import *
|
|
@ -0,0 +1,93 @@
|
||||||
|
# coding: utf-8
|
||||||
|
#
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from orgs.utils import set_to_root_org
|
||||||
|
from ..models import K8sAppPermission
|
||||||
|
from common.tree import TreeNode
|
||||||
|
from applications.models import K8sApp
|
||||||
|
from assets.models import SystemUser
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_k8s_app_permissions(user, include_group=True):
|
||||||
|
if include_group:
|
||||||
|
groups = user.groups.all()
|
||||||
|
arg = Q(users=user) | Q(user_groups__in=groups)
|
||||||
|
else:
|
||||||
|
arg = Q(users=user)
|
||||||
|
return K8sAppPermission.objects.all().valid().filter(arg)
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_group_k8s_app_permission(user_group):
|
||||||
|
return K8sAppPermission.objects.all().valid().filter(
|
||||||
|
user_groups=user_group
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class K8sAppPermissionUtil:
|
||||||
|
get_permissions_map = {
|
||||||
|
'User': get_user_k8s_app_permissions,
|
||||||
|
'UserGroup': get_user_group_k8s_app_permission
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, obj):
|
||||||
|
self.object = obj
|
||||||
|
self.change_org_if_need()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def change_org_if_need():
|
||||||
|
set_to_root_org()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def permissions(self):
|
||||||
|
obj_class = self.object.__class__.__name__
|
||||||
|
func = self.get_permissions_map[obj_class]
|
||||||
|
_permissions = func(self.object)
|
||||||
|
return _permissions
|
||||||
|
|
||||||
|
def get_k8s_apps(self):
|
||||||
|
k8s_apps = K8sApp.objects.filter(
|
||||||
|
granted_by_permissions__in=self.permissions
|
||||||
|
).distinct()
|
||||||
|
return k8s_apps
|
||||||
|
|
||||||
|
def get_k8s_app_system_users(self, k8s_app):
|
||||||
|
queryset = self.permissions
|
||||||
|
kwargs = {'k8s_apps': k8s_app}
|
||||||
|
queryset = queryset.filter(**kwargs)
|
||||||
|
system_users_ids = queryset.values_list('system_users', flat=True)
|
||||||
|
system_users_ids = system_users_ids.distinct()
|
||||||
|
system_users = SystemUser.objects.filter(id__in=system_users_ids)
|
||||||
|
system_users = system_users.order_by('-priority')
|
||||||
|
return system_users
|
||||||
|
|
||||||
|
|
||||||
|
def construct_k8s_apps_tree_root():
|
||||||
|
tree_root = {
|
||||||
|
'id': 'ID_K8S_APP_ROOT',
|
||||||
|
'name': _('KubernetesApp'),
|
||||||
|
'title': 'K8sApp',
|
||||||
|
'pId': '',
|
||||||
|
'open': False,
|
||||||
|
'isParent': True,
|
||||||
|
'iconSkin': '',
|
||||||
|
'meta': {'type': 'k8s_app'}
|
||||||
|
}
|
||||||
|
return TreeNode(**tree_root)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_k8s_app_to_tree_node(parent, k8s_app):
|
||||||
|
pid = parent.id if parent else ''
|
||||||
|
tree_node = {
|
||||||
|
'id': k8s_app.id,
|
||||||
|
'name': k8s_app.name,
|
||||||
|
'title': k8s_app.name,
|
||||||
|
'pId': pid,
|
||||||
|
'open': False,
|
||||||
|
'isParent': False,
|
||||||
|
'iconSkin': 'file',
|
||||||
|
'meta': {'type': 'k8s_app'}
|
||||||
|
}
|
||||||
|
return TreeNode(**tree_node)
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.2.13 on 2020-08-10 09:35
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('terminal', '0024_auto_20200715_1713'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='session',
|
||||||
|
name='protocol',
|
||||||
|
field=models.CharField(choices=[('ssh', 'ssh'), ('rdp', 'rdp'), ('vnc', 'vnc'), ('telnet', 'telnet'), ('mysql', 'mysql'), ('k8s', 'kubernetes')], db_index=True, default='ssh', max_length=8),
|
||||||
|
),
|
||||||
|
]
|
|
@ -179,6 +179,7 @@ class Session(OrgModelMixin):
|
||||||
('vnc', 'vnc'),
|
('vnc', 'vnc'),
|
||||||
('telnet', 'telnet'),
|
('telnet', 'telnet'),
|
||||||
('mysql', 'mysql'),
|
('mysql', 'mysql'),
|
||||||
|
('k8s', 'kubernetes')
|
||||||
)
|
)
|
||||||
|
|
||||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||||
|
|
Loading…
Reference in New Issue