mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-09-03 08:25:04 +00:00
pref: 添加 applet 创建 api
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
from .applet import *
|
||||
from .provider import *
|
||||
from .host import *
|
||||
|
@@ -1,3 +1,7 @@
|
||||
import yaml
|
||||
import os.path
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@@ -9,25 +13,69 @@ __all__ = ['Applet', 'AppletPublication']
|
||||
|
||||
class Applet(JMSBaseModel):
|
||||
class Type(models.TextChoices):
|
||||
app = 'app', _('App')
|
||||
general = 'general', _('General')
|
||||
web = 'web', _('Web')
|
||||
|
||||
class VCSType(models.TextChoices):
|
||||
manual = 'manual', _('Manual')
|
||||
git = 'git', _('Git')
|
||||
archive = 'archive', _('Remote gzip')
|
||||
|
||||
name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True)
|
||||
version = models.CharField(max_length=16, verbose_name=_('Version'))
|
||||
type = models.CharField(max_length=16, choices=Type.choices, verbose_name=_('Type'))
|
||||
icon = models.ImageField(upload_to='applet/icon', verbose_name=_('Icon'))
|
||||
author = models.CharField(max_length=128, verbose_name=_('Author'))
|
||||
path = models.FilePathField(verbose_name=_('Path'))
|
||||
type = models.CharField(max_length=16, verbose_name=_('Type'), default='general', choices=Type.choices)
|
||||
vcs_type = models.CharField(max_length=16, verbose_name=_('VCS type'), null=True)
|
||||
vcs_url = models.CharField(max_length=256, verbose_name=_('URL'), null=True)
|
||||
protocols = models.JSONField(default=list, verbose_name=_('Protocol'))
|
||||
tags = models.JSONField(default=list, verbose_name=_('Tags'))
|
||||
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@property
|
||||
def manifest(self):
|
||||
path = os.path.join(self.path, 'manifest.yml')
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
with open(path, 'r') as f:
|
||||
return yaml.safe_load(f)
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
path = os.path.join(self.path, 'icon.png')
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
with open(path, 'rb') as f:
|
||||
return f.read()
|
||||
|
||||
@classmethod
|
||||
def validate_manifest(cls, manifest):
|
||||
fields = ['name', 'display_name', 'version', 'author', 'type', 'tags', 'protocols']
|
||||
for field in fields:
|
||||
if field not in manifest:
|
||||
raise ValidationError(f'Missing field {field}')
|
||||
if manifest['type'] not in [i[0] for i in cls.Type.choices]:
|
||||
raise ValidationError('Invalid type')
|
||||
if not isinstance(manifest['protocols'], list):
|
||||
raise ValidationError('Invalid protocols')
|
||||
|
||||
@classmethod
|
||||
def create_by_manifest(cls, manifest):
|
||||
obj = cls()
|
||||
for k, v in manifest.items():
|
||||
setattr(obj, k, v)
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
|
||||
class AppletPublication(JMSBaseModel):
|
||||
applet = models.ForeignKey('Applet', on_delete=models.PROTECT, verbose_name=_('Applet'))
|
||||
provider = models.ForeignKey('AppletProvider', on_delete=models.PROTECT, verbose_name=_('Provider'))
|
||||
host = models.ForeignKey('AppletHost', on_delete=models.PROTECT, verbose_name=_('Host'))
|
||||
status = models.CharField(max_length=16, verbose_name=_('Status'))
|
||||
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
|
||||
|
||||
class Meta:
|
||||
unique_together = ('applet', 'provider')
|
||||
unique_together = ('applet', 'host')
|
||||
|
@@ -1,31 +1,34 @@
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from celery import current_app
|
||||
|
||||
from common.db.models import JMSBaseModel
|
||||
|
||||
|
||||
__all__ = ['AppletProvider', 'ProviderDeployment']
|
||||
__all__ = ['AppletHost', 'AppletHostDeployment']
|
||||
|
||||
|
||||
class AppletProvider(JMSBaseModel):
|
||||
name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True)
|
||||
asset = models.ForeignKey('assets.Asset', on_delete=models.PROTECT, verbose_name=_('Asset'))
|
||||
class AppletHost(JMSBaseModel):
|
||||
host = models.ForeignKey('assets.Host', on_delete=models.PROTECT, verbose_name=_('Host'))
|
||||
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
|
||||
account_automation = models.BooleanField(default=False, verbose_name=_('Account automation'))
|
||||
date_synced = models.DateTimeField(null=True, blank=True, verbose_name=_('Date synced'))
|
||||
status = models.CharField(max_length=16, verbose_name=_('Status'))
|
||||
applets = models.ManyToManyField(
|
||||
'Applet', verbose_name=_('Applet'),
|
||||
through='AppletPublication', through_fields=('provider', 'applet'),
|
||||
through='AppletPublication', through_fields=('host', 'applet'),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.host.name
|
||||
|
||||
class ProviderDeployment(JMSBaseModel):
|
||||
provider = models.ForeignKey('AppletProvider', on_delete=models.CASCADE, verbose_name=_('Provider'))
|
||||
|
||||
class AppletHostDeployment(JMSBaseModel):
|
||||
host = models.ForeignKey('AppletHost', on_delete=models.CASCADE, verbose_name=_('Hosting'))
|
||||
status = models.CharField(max_length=16, verbose_name=_('Status'))
|
||||
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
|
||||
|
||||
def install(self):
|
||||
def __str__(self):
|
||||
return self.host
|
||||
|
||||
def start(self):
|
||||
pass
|
Reference in New Issue
Block a user