mirror of https://github.com/jumpserver/jumpserver
perf: 支持发布机卸载远程应用
parent
a5e8792092
commit
0589f7fe33
|
@ -11,9 +11,14 @@ from common.permissions import IsServiceAccount
|
||||||
from orgs.utils import tmp_to_builtin_org
|
from orgs.utils import tmp_to_builtin_org
|
||||||
from terminal.models import AppletHost, AppletHostDeployment
|
from terminal.models import AppletHost, AppletHostDeployment
|
||||||
from terminal.serializers import (
|
from terminal.serializers import (
|
||||||
AppletHostSerializer, AppletHostDeploymentSerializer, AppletHostStartupSerializer
|
AppletHostSerializer, AppletHostDeploymentSerializer,
|
||||||
|
AppletHostStartupSerializer, AppletSetupSerializer
|
||||||
|
)
|
||||||
|
from terminal.tasks import (
|
||||||
|
run_applet_host_deployment,
|
||||||
|
run_applet_host_deployment_install_applet,
|
||||||
|
run_applet_host_deployment_uninstall_applet
|
||||||
)
|
)
|
||||||
from terminal.tasks import run_applet_host_deployment, run_applet_host_deployment_install_applet
|
|
||||||
|
|
||||||
__all__ = ['AppletHostViewSet', 'AppletHostDeploymentViewSet']
|
__all__ = ['AppletHostViewSet', 'AppletHostDeploymentViewSet']
|
||||||
|
|
||||||
|
@ -56,6 +61,7 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
|
||||||
filterset_fields = ['host', ]
|
filterset_fields = ['host', ]
|
||||||
rbac_perms = (
|
rbac_perms = (
|
||||||
('applets', 'terminal.view_AppletHostDeployment'),
|
('applets', 'terminal.view_AppletHostDeployment'),
|
||||||
|
('uninstall', 'terminal.change_applethost'),
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -90,7 +96,29 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
|
||||||
transaction.on_commit(lambda: self.start_install_applet(applet_host_deployment_ids, applet_id, task_id))
|
transaction.on_commit(lambda: self.start_install_applet(applet_host_deployment_ids, applet_id, task_id))
|
||||||
return Response({'task': task_id}, status=201)
|
return Response({'task': task_id}, status=201)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False)
|
||||||
|
def uninstall(self, request, *args, **kwargs):
|
||||||
|
serializer = AppletSetupSerializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
validated_data = serializer.validated_data
|
||||||
|
hosts = validated_data.pop('hosts', [])
|
||||||
|
applet_id = validated_data.pop('applet_id', '')
|
||||||
|
hosts_qs = AppletHost.objects.filter(id__in=hosts)
|
||||||
|
if not hosts_qs.exists():
|
||||||
|
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||||
|
task_id = str(uuid.uuid4())
|
||||||
|
objs = [AppletHostDeployment(host=host, task=task_id) for host in hosts_qs]
|
||||||
|
applet_host_deployments = AppletHostDeployment.objects.bulk_create(objs)
|
||||||
|
applet_host_deployment_ids = [str(obj.id) for obj in applet_host_deployments]
|
||||||
|
transaction.on_commit(lambda: self.start_uninstall_applet(applet_host_deployment_ids, applet_id, task_id))
|
||||||
|
return Response({'task': task_id}, status=201)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def start_install_applet(applet_host_deployment_ids, applet_id, task_id):
|
def start_install_applet(applet_host_deployment_ids, applet_id, task_id):
|
||||||
run_applet_host_deployment_install_applet.apply_async((applet_host_deployment_ids, applet_id),
|
run_applet_host_deployment_install_applet.apply_async((applet_host_deployment_ids, applet_id),
|
||||||
task_id=str(task_id))
|
task_id=str(task_id))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def start_uninstall_applet(applet_host_deployment_ids, applet_id, task_id):
|
||||||
|
run_applet_host_deployment_uninstall_applet.apply_async((applet_host_deployment_ids, applet_id),
|
||||||
|
task_id=str(task_id))
|
||||||
|
|
|
@ -36,6 +36,9 @@ class DeployAppletHostManager:
|
||||||
def install_applet(self, **kwargs):
|
def install_applet(self, **kwargs):
|
||||||
self._run(self._run_install_applet, **kwargs)
|
self._run(self._run_install_applet, **kwargs)
|
||||||
|
|
||||||
|
def uninstall_applet(self, **kwargs):
|
||||||
|
self._run(self._run_uninstall_applet, **kwargs)
|
||||||
|
|
||||||
def _run_initial_deploy(self, **kwargs):
|
def _run_initial_deploy(self, **kwargs):
|
||||||
playbook = self.generate_initial_playbook
|
playbook = self.generate_initial_playbook
|
||||||
return self._run_playbook(playbook, **kwargs)
|
return self._run_playbook(playbook, **kwargs)
|
||||||
|
@ -47,6 +50,13 @@ class DeployAppletHostManager:
|
||||||
generate_playbook = self.generate_install_all_playbook
|
generate_playbook = self.generate_install_all_playbook
|
||||||
return self._run_playbook(generate_playbook, **kwargs)
|
return self._run_playbook(generate_playbook, **kwargs)
|
||||||
|
|
||||||
|
def _run_uninstall_applet(self, **kwargs):
|
||||||
|
if self.applet:
|
||||||
|
generate_playbook = self.generate_uninstall_applet_playbook
|
||||||
|
else:
|
||||||
|
raise ValueError("applet is required for uninstall_applet")
|
||||||
|
return self._run_playbook(generate_playbook, **kwargs)
|
||||||
|
|
||||||
def generate_initial_playbook(self):
|
def generate_initial_playbook(self):
|
||||||
site_url = settings.SITE_URL
|
site_url = settings.SITE_URL
|
||||||
download_host = settings.APPLET_DOWNLOAD_HOST
|
download_host = settings.APPLET_DOWNLOAD_HOST
|
||||||
|
@ -92,6 +102,16 @@ class DeployAppletHostManager:
|
||||||
|
|
||||||
return self._generate_playbook("install_applet.yml", handler)
|
return self._generate_playbook("install_applet.yml", handler)
|
||||||
|
|
||||||
|
def generate_uninstall_applet_playbook(self):
|
||||||
|
applet_name = self.applet.name
|
||||||
|
|
||||||
|
def handler(plays):
|
||||||
|
for play in plays:
|
||||||
|
play["vars"]["applet_name"] = applet_name
|
||||||
|
return plays
|
||||||
|
|
||||||
|
return self._generate_playbook("uninstall_applet.yml", handler)
|
||||||
|
|
||||||
def generate_inventory(self):
|
def generate_inventory(self):
|
||||||
inventory = JMSInventory(
|
inventory = JMSInventory(
|
||||||
[self.deployment.host], account_policy="privileged_only"
|
[self.deployment.host], account_policy="privileged_only"
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
vars:
|
||||||
|
applet_name: chrome
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: uninstall applet
|
||||||
|
ansible.windows.win_powershell:
|
||||||
|
script: |
|
||||||
|
tinkerd uninstall --name {{ applet_name }}
|
|
@ -168,6 +168,16 @@ class AppletHostDeployment(JMSBaseModel):
|
||||||
manager = DeployAppletHostManager(self, applet=applet)
|
manager = DeployAppletHostManager(self, applet=applet)
|
||||||
manager.install_applet(**kwargs)
|
manager.install_applet(**kwargs)
|
||||||
|
|
||||||
|
def uninstall_applet(self, applet_id, **kwargs):
|
||||||
|
from ...automations.deploy_applet_host import DeployAppletHostManager
|
||||||
|
from .applet import Applet
|
||||||
|
if applet_id:
|
||||||
|
applet = Applet.objects.get(id=applet_id)
|
||||||
|
else:
|
||||||
|
applet = None
|
||||||
|
manager = DeployAppletHostManager(self, applet=applet)
|
||||||
|
manager.uninstall_applet(**kwargs)
|
||||||
|
|
||||||
def save_task(self, task):
|
def save_task(self, task):
|
||||||
self.task = task
|
self.task = task
|
||||||
self.save(update_fields=['task'])
|
self.save(update_fields=['task'])
|
||||||
|
|
|
@ -15,7 +15,7 @@ from ..models import AppletHost, AppletHostDeployment
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AppletHostSerializer', 'AppletHostDeploymentSerializer',
|
'AppletHostSerializer', 'AppletHostDeploymentSerializer',
|
||||||
'AppletHostAccountSerializer', 'AppletHostAppletReportSerializer',
|
'AppletHostAccountSerializer', 'AppletHostAppletReportSerializer',
|
||||||
'AppletHostStartupSerializer'
|
'AppletHostStartupSerializer', 'AppletSetupSerializer'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ class AppletHostDeploymentSerializer(serializers.ModelSerializer):
|
||||||
'status', 'date_created', 'date_updated',
|
'status', 'date_created', 'date_updated',
|
||||||
'date_start', 'date_finished'
|
'date_start', 'date_finished'
|
||||||
]
|
]
|
||||||
write_only_fields = ['install_applets',]
|
write_only_fields = ['install_applets', ]
|
||||||
fields = fields_mini + ['comment'] + read_only_fields + write_only_fields
|
fields = fields_mini + ['comment'] + read_only_fields + write_only_fields
|
||||||
|
|
||||||
|
|
||||||
|
@ -161,3 +161,8 @@ class AppletHostAppletReportSerializer(serializers.Serializer):
|
||||||
|
|
||||||
class AppletHostStartupSerializer(serializers.Serializer):
|
class AppletHostStartupSerializer(serializers.Serializer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AppletSetupSerializer(serializers.Serializer):
|
||||||
|
hosts = serializers.ListField(child=serializers.UUIDField(label=_('Host ID')), label=_('Hosts'))
|
||||||
|
applet_id = serializers.UUIDField(label=_('Applet ID'))
|
||||||
|
|
|
@ -108,6 +108,17 @@ def run_applet_host_deployment_install_applet(ids, applet_id):
|
||||||
deployment.install_applet(applet_id)
|
deployment.install_applet(applet_id)
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task(
|
||||||
|
verbose_name=_('Uninstall applet'),
|
||||||
|
activity_callback=lambda self, ids, applet_id, *args, **kwargs: (ids,)
|
||||||
|
)
|
||||||
|
def run_applet_host_deployment_uninstall_applet(ids, applet_id):
|
||||||
|
with tmp_to_builtin_org(system=1):
|
||||||
|
for did in ids:
|
||||||
|
deployment = AppletHostDeployment.objects.get(id=did)
|
||||||
|
deployment.uninstall_applet(applet_id)
|
||||||
|
|
||||||
|
|
||||||
@shared_task(
|
@shared_task(
|
||||||
verbose_name=_('Generate applet host accounts'),
|
verbose_name=_('Generate applet host accounts'),
|
||||||
activity_callback=lambda self, host_id, *args, **kwargs: ([host_id],)
|
activity_callback=lambda self, host_id, *args, **kwargs: ([host_id],)
|
||||||
|
|
Loading…
Reference in New Issue