mirror of https://github.com/jumpserver/jumpserver
perf: add applets deployment
parent
8e1312e8ce
commit
d554e92d02
|
@ -2,16 +2,15 @@ from rest_framework import viewsets
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from common.permissions import IsServiceAccount
|
|
||||||
from common.drf.api import JMSModelViewSet
|
from common.drf.api import JMSModelViewSet
|
||||||
|
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.serializers import (
|
from terminal.serializers import (
|
||||||
AppletHostSerializer, AppletHostDeploymentSerializer,
|
AppletHostSerializer, AppletHostDeploymentSerializer,
|
||||||
AppletHostStartupSerializer
|
AppletHostStartupSerializer, AppletHostDeployAppletSerializer
|
||||||
)
|
)
|
||||||
from terminal.models import AppletHost, AppletHostDeployment
|
from terminal.tasks import run_applet_host_deployment, run_applet_host_deployment_install_applet
|
||||||
from terminal.tasks import run_applet_host_deployment
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['AppletHostViewSet', 'AppletHostDeploymentViewSet']
|
__all__ = ['AppletHostViewSet', 'AppletHostDeploymentViewSet']
|
||||||
|
|
||||||
|
@ -41,6 +40,9 @@ class AppletHostViewSet(JMSModelViewSet):
|
||||||
class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
|
class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
|
||||||
serializer_class = AppletHostDeploymentSerializer
|
serializer_class = AppletHostDeploymentSerializer
|
||||||
queryset = AppletHostDeployment.objects.all()
|
queryset = AppletHostDeployment.objects.all()
|
||||||
|
rbac_perms = (
|
||||||
|
('applets', 'terminal.view_AppletHostDeployment'),
|
||||||
|
)
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
serializer = self.get_serializer(data=request.data)
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
@ -49,3 +51,11 @@ class AppletHostDeploymentViewSet(viewsets.ModelViewSet):
|
||||||
task = run_applet_host_deployment.delay(instance.id)
|
task = run_applet_host_deployment.delay(instance.id)
|
||||||
return Response({'task': str(task.id)}, status=201)
|
return Response({'task': str(task.id)}, status=201)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, serializer_class=AppletHostDeployAppletSerializer)
|
||||||
|
def applets(self, request, *args, **kwargs):
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
applet_id = serializer.validated_data.get('applet_id')
|
||||||
|
instance = serializer.save()
|
||||||
|
task = run_applet_host_deployment_install_applet.delay(instance.id, applet_id)
|
||||||
|
return Response({'task': str(task.id)}, status=201)
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
import os
|
|
||||||
import datetime
|
import datetime
|
||||||
import shutil
|
import os
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from django.utils import timezone
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from common.utils import get_logger
|
|
||||||
from common.db.utils import safe_db_connection
|
from common.db.utils import safe_db_connection
|
||||||
|
from common.utils import get_logger
|
||||||
from ops.ansible import PlaybookRunner, JMSInventory
|
from ops.ansible import PlaybookRunner, JMSInventory
|
||||||
|
from terminal.models import Applet, AppletHostDeployment
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
class DeployAppletHostManager:
|
class DeployAppletHostManager:
|
||||||
def __init__(self, deployment):
|
def __init__(self, deployment: AppletHostDeployment, applet: Applet = None):
|
||||||
self.deployment = deployment
|
self.deployment = deployment
|
||||||
|
self.applet = applet
|
||||||
self.run_dir = self.get_run_dir()
|
self.run_dir = self.get_run_dir()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -25,29 +26,56 @@ class DeployAppletHostManager:
|
||||||
now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
||||||
return os.path.join(base, now)
|
return os.path.join(base, now)
|
||||||
|
|
||||||
def generate_playbook(self):
|
def run(self, **kwargs):
|
||||||
playbook_src = os.path.join(CURRENT_DIR, "playbook.yml")
|
self._run(self._run_initial_deploy, **kwargs)
|
||||||
base_site_url = settings.BASE_SITE_URL
|
|
||||||
|
def install_applet(self, **kwargs):
|
||||||
|
self._run(self._run_install_applet, **kwargs)
|
||||||
|
|
||||||
|
def _run_initial_deploy(self, **kwargs):
|
||||||
|
playbook = self.generate_initial_playbook
|
||||||
|
return self._run_playbook(playbook, **kwargs)
|
||||||
|
|
||||||
|
def _run_install_applet(self, **kwargs):
|
||||||
|
if self.applet:
|
||||||
|
generate_playbook = self.generate_install_applet_playbook
|
||||||
|
else:
|
||||||
|
generate_playbook = self.generate_install_all_playbook
|
||||||
|
return self._run_playbook(generate_playbook, **kwargs)
|
||||||
|
|
||||||
|
def generate_initial_playbook(self):
|
||||||
|
site_url = settings.SITE_URL
|
||||||
bootstrap_token = settings.BOOTSTRAP_TOKEN
|
bootstrap_token = settings.BOOTSTRAP_TOKEN
|
||||||
host_id = str(self.deployment.host.id)
|
host_id = str(self.deployment.host.id)
|
||||||
if not base_site_url:
|
if not site_url:
|
||||||
base_site_url = "http://localhost:8080"
|
site_url = "http://localhost:8080"
|
||||||
with open(playbook_src) as f:
|
options = self.deployment.host.deploy_options
|
||||||
plays = yaml.safe_load(f)
|
|
||||||
for play in plays:
|
|
||||||
play["vars"].update(self.deployment.host.deploy_options)
|
|
||||||
play["vars"]["DownloadHost"] = base_site_url + "/download"
|
|
||||||
play["vars"]["CORE_HOST"] = base_site_url
|
|
||||||
play["vars"]["BOOTSTRAP_TOKEN"] = bootstrap_token
|
|
||||||
play["vars"]["HOST_ID"] = host_id
|
|
||||||
play["vars"]["HOST_NAME"] = self.deployment.host.name
|
|
||||||
|
|
||||||
playbook_dir = os.path.join(self.run_dir, "playbook")
|
def handler(plays):
|
||||||
playbook_dst = os.path.join(playbook_dir, "main.yml")
|
for play in plays:
|
||||||
os.makedirs(playbook_dir, exist_ok=True)
|
play["vars"].update(options)
|
||||||
with open(playbook_dst, "w") as f:
|
play["vars"]["DownloadHost"] = site_url + "/download"
|
||||||
yaml.safe_dump(plays, f)
|
play["vars"]["CORE_HOST"] = site_url
|
||||||
return playbook_dst
|
play["vars"]["BOOTSTRAP_TOKEN"] = bootstrap_token
|
||||||
|
play["vars"]["HOST_ID"] = host_id
|
||||||
|
play["vars"]["HOST_NAME"] = self.deployment.host.name
|
||||||
|
|
||||||
|
return self._generate_playbook("playbook.yml", handler)
|
||||||
|
|
||||||
|
def generate_install_all_playbook(self):
|
||||||
|
return self._generate_playbook("install_all.yml")
|
||||||
|
|
||||||
|
def generate_install_applet_playbook(self):
|
||||||
|
applet_name = self.applet.name
|
||||||
|
options = self.deployment.host.deploy_options
|
||||||
|
|
||||||
|
def handler(plays):
|
||||||
|
for play in plays:
|
||||||
|
play["vars"].update(options)
|
||||||
|
play["vars"]["applet_name"] = applet_name
|
||||||
|
return plays
|
||||||
|
|
||||||
|
return self._generate_playbook("install_applet.yml", handler)
|
||||||
|
|
||||||
def generate_inventory(self):
|
def generate_inventory(self):
|
||||||
inventory = JMSInventory(
|
inventory = JMSInventory(
|
||||||
|
@ -58,18 +86,31 @@ class DeployAppletHostManager:
|
||||||
inventory.write_to_file(inventory_path)
|
inventory.write_to_file(inventory_path)
|
||||||
return inventory_path
|
return inventory_path
|
||||||
|
|
||||||
def _run(self, **kwargs):
|
def _generate_playbook(self, playbook_template_name, plays_handler: callable = None):
|
||||||
|
playbook_src = os.path.join(CURRENT_DIR, playbook_template_name)
|
||||||
|
with open(playbook_src) as f:
|
||||||
|
plays = yaml.safe_load(f)
|
||||||
|
if plays_handler:
|
||||||
|
plays = plays_handler(plays)
|
||||||
|
playbook_dir = os.path.join(self.run_dir, "playbook")
|
||||||
|
playbook_dst = os.path.join(playbook_dir, "main.yml")
|
||||||
|
os.makedirs(playbook_dir, exist_ok=True)
|
||||||
|
with open(playbook_dst, "w") as f:
|
||||||
|
yaml.safe_dump(plays, f)
|
||||||
|
return playbook_dst
|
||||||
|
|
||||||
|
def _run_playbook(self, generate_playbook: callable, **kwargs):
|
||||||
inventory = self.generate_inventory()
|
inventory = self.generate_inventory()
|
||||||
playbook = self.generate_playbook()
|
playbook = generate_playbook()
|
||||||
runner = PlaybookRunner(
|
runner = PlaybookRunner(
|
||||||
inventory=inventory, playbook=playbook, project_dir=self.run_dir
|
inventory=inventory, playbook=playbook, project_dir=self.run_dir
|
||||||
)
|
)
|
||||||
return runner.run(**kwargs)
|
return runner.run(**kwargs)
|
||||||
|
|
||||||
def run(self, **kwargs):
|
def _run(self, cb_func: callable, **kwargs):
|
||||||
try:
|
try:
|
||||||
self.deployment.date_start = timezone.now()
|
self.deployment.date_start = timezone.now()
|
||||||
cb = self._run(**kwargs)
|
cb = cb_func(**kwargs)
|
||||||
self.deployment.status = cb.status
|
self.deployment.status = cb.status
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Error: {}".format(e))
|
logger.error("Error: {}".format(e))
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Install all applets
|
||||||
|
ansible.windows.win_shell:
|
||||||
|
"tinkerd install all"
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
|
vars:
|
||||||
|
applet_name: chrome
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Install applet
|
||||||
|
ansible.windows.win_shell:
|
||||||
|
"tinkerd install --name {{ applet_name }}"
|
||||||
|
when: applet_name != 'all'
|
|
@ -3,7 +3,6 @@
|
||||||
- hosts: all
|
- hosts: all
|
||||||
vars:
|
vars:
|
||||||
DownloadHost: https://demo.jumpserver.org/download
|
DownloadHost: https://demo.jumpserver.org/download
|
||||||
Initial: 0
|
|
||||||
HOST_NAME: test
|
HOST_NAME: test
|
||||||
HOST_ID: 00000000-0000-0000-0000-000000000000
|
HOST_ID: 00000000-0000-0000-0000-000000000000
|
||||||
CORE_HOST: https://demo.jumpserver.org
|
CORE_HOST: https://demo.jumpserver.org
|
||||||
|
@ -17,166 +16,166 @@
|
||||||
TinkerInstaller: Tinker_Installer_v0.0.1.exe
|
TinkerInstaller: Tinker_Installer_v0.0.1.exe
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Install RDS-Licensing (RDS)
|
- name: Install RDS-Licensing (RDS)
|
||||||
ansible.windows.win_feature:
|
ansible.windows.win_feature:
|
||||||
name: RDS-Licensing
|
name: RDS-Licensing
|
||||||
state: present
|
state: present
|
||||||
include_management_tools: yes
|
include_management_tools: yes
|
||||||
when: RDS_Licensing
|
when: RDS_Licensing
|
||||||
|
|
||||||
- name: Install RDS-RD-Server (RDS)
|
- name: Install RDS-RD-Server (RDS)
|
||||||
ansible.windows.win_feature:
|
ansible.windows.win_feature:
|
||||||
name: RDS-RD-Server
|
name: RDS-RD-Server
|
||||||
state: present
|
state: present
|
||||||
include_management_tools: yes
|
include_management_tools: yes
|
||||||
register: rds_install
|
register: rds_install
|
||||||
|
|
||||||
- name: Download JumpServer Tinker installer (jumpserver)
|
- name: Download JumpServer Tinker installer (jumpserver)
|
||||||
ansible.windows.win_get_url:
|
ansible.windows.win_get_url:
|
||||||
url: "{{ DownloadHost }}/{{ TinkerInstaller }}"
|
url: "{{ DownloadHost }}/{{ TinkerInstaller }}"
|
||||||
dest: "{{ ansible_env.TEMP }}\\{{ TinkerInstaller }}"
|
dest: "{{ ansible_env.TEMP }}\\{{ TinkerInstaller }}"
|
||||||
|
|
||||||
- name: Install JumpServer Tinker (jumpserver)
|
- name: Install JumpServer Tinker (jumpserver)
|
||||||
ansible.windows.win_package:
|
ansible.windows.win_package:
|
||||||
path: "{{ ansible_env.TEMP }}\\{{ TinkerInstaller }}"
|
path: "{{ ansible_env.TEMP }}\\{{ TinkerInstaller }}"
|
||||||
arguments:
|
arguments:
|
||||||
- /VERYSILENT
|
- /VERYSILENT
|
||||||
- /SUPPRESSMSGBOXES
|
- /SUPPRESSMSGBOXES
|
||||||
- /NORESTART
|
- /NORESTART
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Set remote-server on the global system path (remote-server)
|
- name: Set remote-server on the global system path (remote-server)
|
||||||
ansible.windows.win_path:
|
ansible.windows.win_path:
|
||||||
elements:
|
elements:
|
||||||
- '%USERPROFILE%\AppData\Local\Programs\Tinker\'
|
- '%USERPROFILE%\AppData\Local\Programs\Tinker\'
|
||||||
scope: user
|
scope: user
|
||||||
|
|
||||||
- name: Download python-3.10.8
|
- name: Download python-3.10.8
|
||||||
ansible.windows.win_get_url:
|
ansible.windows.win_get_url:
|
||||||
url: "{{ DownloadHost }}/python-3.10.8-amd64.exe"
|
url: "{{ DownloadHost }}/python-3.10.8-amd64.exe"
|
||||||
dest: "{{ ansible_env.TEMP }}\\python-3.10.8-amd64.exe"
|
dest: "{{ ansible_env.TEMP }}\\python-3.10.8-amd64.exe"
|
||||||
|
|
||||||
- name: Install the python-3.10.8
|
- name: Install the python-3.10.8
|
||||||
ansible.windows.win_package:
|
ansible.windows.win_package:
|
||||||
path: "{{ ansible_env.TEMP }}\\python-3.10.8-amd64.exe"
|
path: "{{ ansible_env.TEMP }}\\python-3.10.8-amd64.exe"
|
||||||
product_id: '{371d0d73-d418-4ffe-b280-58c3e7987525}'
|
product_id: '{371d0d73-d418-4ffe-b280-58c3e7987525}'
|
||||||
arguments:
|
arguments:
|
||||||
- /quiet
|
- /quiet
|
||||||
- InstallAllUsers=1
|
- InstallAllUsers=1
|
||||||
- PrependPath=1
|
- PrependPath=1
|
||||||
- Include_test=0
|
- Include_test=0
|
||||||
- Include_launcher=0
|
- Include_launcher=0
|
||||||
state: present
|
state: present
|
||||||
register: win_install_python
|
register: win_install_python
|
||||||
|
|
||||||
- name: Reboot if installing requires it
|
- name: Reboot if installing requires it
|
||||||
ansible.windows.win_reboot:
|
ansible.windows.win_reboot:
|
||||||
post_reboot_delay: 10
|
post_reboot_delay: 10
|
||||||
test_command: whoami
|
test_command: whoami
|
||||||
when: rds_install.reboot_required or win_install_python.reboot_required
|
when: rds_install.reboot_required or win_install_python.reboot_required
|
||||||
|
|
||||||
- name: Set RDS LicenseServer (regedit)
|
- name: Set RDS LicenseServer (regedit)
|
||||||
ansible.windows.win_regedit:
|
ansible.windows.win_regedit:
|
||||||
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
||||||
name: LicenseServers
|
name: LicenseServers
|
||||||
data: "{{ RDS_LicenseServer }}"
|
data: "{{ RDS_LicenseServer }}"
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
- name: Set RDS LicensingMode (regedit)
|
- name: Set RDS LicensingMode (regedit)
|
||||||
ansible.windows.win_regedit:
|
ansible.windows.win_regedit:
|
||||||
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
||||||
name: LicensingMode
|
name: LicensingMode
|
||||||
data: "{{ RDS_LicensingMode }}"
|
data: "{{ RDS_LicensingMode }}"
|
||||||
type: dword
|
type: dword
|
||||||
|
|
||||||
- name: Set RDS fSingleSessionPerUser (regedit)
|
- name: Set RDS fSingleSessionPerUser (regedit)
|
||||||
ansible.windows.win_regedit:
|
ansible.windows.win_regedit:
|
||||||
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
||||||
name: fSingleSessionPerUser
|
name: fSingleSessionPerUser
|
||||||
data: "{{ RDS_fSingleSessionPerUser }}"
|
data: "{{ RDS_fSingleSessionPerUser }}"
|
||||||
type: dword
|
type: dword
|
||||||
|
|
||||||
- name: Set RDS MaxDisconnectionTime (regedit)
|
- name: Set RDS MaxDisconnectionTime (regedit)
|
||||||
ansible.windows.win_regedit:
|
ansible.windows.win_regedit:
|
||||||
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
||||||
name: MaxDisconnectionTime
|
name: MaxDisconnectionTime
|
||||||
data: "{{ RDS_MaxDisconnectionTime }}"
|
data: "{{ RDS_MaxDisconnectionTime }}"
|
||||||
type: dword
|
type: dword
|
||||||
when: RDS_MaxDisconnectionTime >= 60000
|
when: RDS_MaxDisconnectionTime >= 60000
|
||||||
|
|
||||||
- name: Set RDS RemoteAppLogoffTimeLimit (regedit)
|
- name: Set RDS RemoteAppLogoffTimeLimit (regedit)
|
||||||
ansible.windows.win_regedit:
|
ansible.windows.win_regedit:
|
||||||
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
|
||||||
name: RemoteAppLogoffTimeLimit
|
name: RemoteAppLogoffTimeLimit
|
||||||
data: "{{ RDS_RemoteAppLogoffTimeLimit }}"
|
data: "{{ RDS_RemoteAppLogoffTimeLimit }}"
|
||||||
type: dword
|
type: dword
|
||||||
|
|
||||||
- name: Download pip packages
|
- name: Download pip packages
|
||||||
ansible.windows.win_get_url:
|
ansible.windows.win_get_url:
|
||||||
url: "{{ DownloadHost }}/pip_packages_v0.0.1.zip"
|
url: "{{ DownloadHost }}/pip_packages_v0.0.1.zip"
|
||||||
dest: "{{ ansible_env.TEMP }}\\pip_packages_v0.0.1.zip"
|
dest: "{{ ansible_env.TEMP }}\\pip_packages_v0.0.1.zip"
|
||||||
|
|
||||||
- name: Unzip pip_packages
|
- name: Unzip pip_packages
|
||||||
community.windows.win_unzip:
|
community.windows.win_unzip:
|
||||||
src: "{{ ansible_env.TEMP }}\\pip_packages_v0.0.1.zip"
|
src: "{{ ansible_env.TEMP }}\\pip_packages_v0.0.1.zip"
|
||||||
dest: "{{ ansible_env.TEMP }}"
|
dest: "{{ ansible_env.TEMP }}"
|
||||||
|
|
||||||
- name: Install python requirements offline
|
- name: Install python requirements offline
|
||||||
ansible.windows.win_shell: >
|
ansible.windows.win_shell: >
|
||||||
pip install -r '{{ ansible_env.TEMP }}\pip_packages_v0.0.1\requirements.txt'
|
pip install -r '{{ ansible_env.TEMP }}\pip_packages_v0.0.1\requirements.txt'
|
||||||
--no-index --find-links='{{ ansible_env.TEMP }}\pip_packages_v0.0.1'
|
--no-index --find-links='{{ ansible_env.TEMP }}\pip_packages_v0.0.1'
|
||||||
|
|
||||||
- name: Download chromedriver (chrome)
|
- name: Download chromedriver (chrome)
|
||||||
ansible.windows.win_get_url:
|
ansible.windows.win_get_url:
|
||||||
url: "{{ DownloadHost }}/chromedriver_win32.107.zip"
|
url: "{{ DownloadHost }}/chromedriver_win32.107.zip"
|
||||||
dest: "{{ ansible_env.TEMP }}\\chromedriver_win32.107.zip"
|
dest: "{{ ansible_env.TEMP }}\\chromedriver_win32.107.zip"
|
||||||
|
|
||||||
- name: Unzip chromedriver (chrome)
|
- name: Unzip chromedriver (chrome)
|
||||||
community.windows.win_unzip:
|
community.windows.win_unzip:
|
||||||
src: "{{ ansible_env.TEMP }}\\chromedriver_win32.107.zip"
|
src: "{{ ansible_env.TEMP }}\\chromedriver_win32.107.zip"
|
||||||
dest: C:\Program Files\JumpServer\drivers
|
dest: C:\Program Files\JumpServer\drivers
|
||||||
|
|
||||||
- name: Set chromedriver on the global system path (chrome)
|
- name: Set chromedriver on the global system path (chrome)
|
||||||
ansible.windows.win_path:
|
ansible.windows.win_path:
|
||||||
elements:
|
elements:
|
||||||
- 'C:\Program Files\JumpServer\drivers'
|
- 'C:\Program Files\JumpServer\drivers'
|
||||||
|
|
||||||
- name: Download chrome msi package (chrome)
|
- name: Download chrome msi package (chrome)
|
||||||
ansible.windows.win_get_url:
|
ansible.windows.win_get_url:
|
||||||
url: "{{ DownloadHost }}/googlechromestandaloneenterprise64.msi"
|
url: "{{ DownloadHost }}/googlechromestandaloneenterprise64.msi"
|
||||||
dest: "{{ ansible_env.TEMP }}\\googlechromestandaloneenterprise64.msi"
|
dest: "{{ ansible_env.TEMP }}\\googlechromestandaloneenterprise64.msi"
|
||||||
|
|
||||||
- name: Install chrome (chrome)
|
- name: Install chrome (chrome)
|
||||||
ansible.windows.win_package:
|
ansible.windows.win_package:
|
||||||
path: "{{ ansible_env.TEMP }}\\googlechromestandaloneenterprise64.msi"
|
path: "{{ ansible_env.TEMP }}\\googlechromestandaloneenterprise64.msi"
|
||||||
state: present
|
state: present
|
||||||
arguments:
|
arguments:
|
||||||
- /quiet
|
- /quiet
|
||||||
|
|
||||||
- name: Generate tinkerd component config
|
- name: Generate tinkerd component config
|
||||||
ansible.windows.win_shell:
|
ansible.windows.win_shell:
|
||||||
"tinkerd config --hostname {{ HOST_NAME }} --core_host {{ CORE_HOST }}
|
"tinkerd config --hostname {{ HOST_NAME }} --core_host {{ CORE_HOST }}
|
||||||
--token {{ BOOTSTRAP_TOKEN }} --host_id {{ HOST_ID }}"
|
--token {{ BOOTSTRAP_TOKEN }} --host_id {{ HOST_ID }}"
|
||||||
|
|
||||||
- name: Install tinkerd service
|
- name: Install tinkerd service
|
||||||
ansible.windows.win_shell:
|
ansible.windows.win_shell:
|
||||||
"tinkerd service install"
|
"tinkerd service install"
|
||||||
|
|
||||||
- name: Start tinkerd service
|
- name: Start tinkerd service
|
||||||
ansible.windows.win_shell:
|
ansible.windows.win_shell:
|
||||||
"tinkerd service start"
|
"tinkerd service start"
|
||||||
|
|
||||||
- name: Wait Tinker api health
|
- name: Wait Tinker api health
|
||||||
ansible.windows.win_uri:
|
ansible.windows.win_uri:
|
||||||
url: http://localhost:6068/api/health/
|
url: http://localhost:6068/api/health/
|
||||||
status_code: 200
|
status_code: 200
|
||||||
method: GET
|
method: GET
|
||||||
register: _result
|
register: _result
|
||||||
until: _result.status_code == 200
|
until: _result.status_code == 200
|
||||||
retries: 30
|
retries: 30
|
||||||
delay: 5
|
delay: 5
|
||||||
|
|
||||||
- name: Sync all remote applets
|
- name: Sync all remote applets
|
||||||
ansible.windows.win_shell:
|
ansible.windows.win_shell:
|
||||||
"tinkerd install all"
|
"tinkerd install all"
|
||||||
|
|
||||||
|
|
|
@ -110,3 +110,13 @@ class AppletHostDeployment(JMSBaseModel):
|
||||||
from ...automations.deploy_applet_host import DeployAppletHostManager
|
from ...automations.deploy_applet_host import DeployAppletHostManager
|
||||||
manager = DeployAppletHostManager(self)
|
manager = DeployAppletHostManager(self)
|
||||||
manager.run(**kwargs)
|
manager.run(**kwargs)
|
||||||
|
|
||||||
|
def install_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.install_applet(**kwargs)
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
from rest_framework import serializers
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
from common.validators import ProjectUniqueValidator
|
|
||||||
from common.drf.fields import ObjectRelatedField, LabeledChoiceField
|
|
||||||
from assets.models import Platform, Account
|
from assets.models import Platform, Account
|
||||||
from assets.serializers import HostSerializer
|
from assets.serializers import HostSerializer
|
||||||
from ..models import AppletHost, AppletHostDeployment, Applet
|
from common.drf.fields import LabeledChoiceField
|
||||||
|
from common.validators import ProjectUniqueValidator
|
||||||
from .applet import AppletSerializer
|
from .applet import AppletSerializer
|
||||||
from .. import const
|
from .. import const
|
||||||
|
from ..models import AppletHost, AppletHostDeployment
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AppletHostSerializer', 'AppletHostDeploymentSerializer',
|
'AppletHostSerializer', 'AppletHostDeploymentSerializer',
|
||||||
'AppletHostAccountSerializer', 'AppletHostAppletReportSerializer',
|
'AppletHostAccountSerializer', 'AppletHostAppletReportSerializer',
|
||||||
'AppletHostStartupSerializer',
|
'AppletHostStartupSerializer', 'AppletHostDeployAppletSerializer'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,7 +28,8 @@ class DeployOptionsSerializer(serializers.Serializer):
|
||||||
RDS_Licensing = serializers.BooleanField(default=False, label=_("RDS Licensing"))
|
RDS_Licensing = serializers.BooleanField(default=False, label=_("RDS Licensing"))
|
||||||
RDS_LicenseServer = serializers.CharField(default='127.0.0.1', label=_('RDS License Server'), max_length=1024)
|
RDS_LicenseServer = serializers.CharField(default='127.0.0.1', label=_('RDS License Server'), max_length=1024)
|
||||||
RDS_LicensingMode = serializers.ChoiceField(choices=LICENSE_MODE_CHOICES, default=4, label=_('RDS Licensing Mode'))
|
RDS_LicensingMode = serializers.ChoiceField(choices=LICENSE_MODE_CHOICES, default=4, label=_('RDS Licensing Mode'))
|
||||||
RDS_fSingleSessionPerUser = serializers.ChoiceField(choices=SESSION_PER_USER, default=1, label=_("RDS fSingleSessionPerUser"))
|
RDS_fSingleSessionPerUser = serializers.ChoiceField(choices=SESSION_PER_USER, default=1,
|
||||||
|
label=_("RDS fSingleSessionPerUser"))
|
||||||
RDS_MaxDisconnectionTime = serializers.IntegerField(default=60000, label=_("RDS Max Disconnection Time"))
|
RDS_MaxDisconnectionTime = serializers.IntegerField(default=60000, label=_("RDS Max Disconnection Time"))
|
||||||
RDS_RemoteAppLogoffTimeLimit = serializers.IntegerField(default=0, label=_("RDS Remote App Logoff Time Limit"))
|
RDS_RemoteAppLogoffTimeLimit = serializers.IntegerField(default=0, label=_("RDS Remote App Logoff Time Limit"))
|
||||||
|
|
||||||
|
@ -94,6 +94,18 @@ class AppletHostDeploymentSerializer(serializers.ModelSerializer):
|
||||||
fields = fields_mini + ['comment'] + read_only_fields
|
fields = fields_mini + ['comment'] + read_only_fields
|
||||||
|
|
||||||
|
|
||||||
|
class AppletHostDeployAppletSerializer(AppletHostDeploymentSerializer):
|
||||||
|
applet_id = serializers.UUIDField(write_only=True, allow_null=True, required=False)
|
||||||
|
|
||||||
|
class Meta(AppletHostDeploymentSerializer.Meta):
|
||||||
|
fields = AppletHostDeploymentSerializer.Meta.fields + ['applet_id']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
applet_id = validated_data.pop('applet_id', None)
|
||||||
|
deployment = super().create(validated_data)
|
||||||
|
return deployment
|
||||||
|
|
||||||
|
|
||||||
class AppletHostAccountSerializer(serializers.ModelSerializer):
|
class AppletHostAccountSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Account
|
model = Account
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import datetime
|
|
||||||
|
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from celery.utils.log import get_task_logger
|
from celery.utils.log import get_task_logger
|
||||||
from django.utils import timezone
|
|
||||||
from django.core.files.storage import default_storage
|
from django.core.files.storage import default_storage
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from common.utils import get_log_keep_day
|
from common.utils import get_log_keep_day
|
||||||
from ops.celery.decorator import (
|
from ops.celery.decorator import (
|
||||||
register_as_period_task, after_app_ready_start,
|
register_as_period_task, after_app_ready_start,
|
||||||
after_app_shutdown_clean_periodic
|
after_app_shutdown_clean_periodic
|
||||||
)
|
)
|
||||||
from .models import (
|
|
||||||
Status, Session, Command, Task, AppletHost,
|
|
||||||
AppletHostDeployment
|
|
||||||
)
|
|
||||||
from orgs.utils import tmp_to_builtin_org
|
from orgs.utils import tmp_to_builtin_org
|
||||||
from .backends import server_replay_storage
|
from .backends import server_replay_storage
|
||||||
|
from .models import (
|
||||||
|
Status, Session, Command, Task, AppletHostDeployment
|
||||||
|
)
|
||||||
from .utils import find_session_replay_local
|
from .utils import find_session_replay_local
|
||||||
|
|
||||||
CACHE_REFRESH_INTERVAL = 10
|
CACHE_REFRESH_INTERVAL = 10
|
||||||
|
@ -57,7 +56,7 @@ def clean_orphan_session():
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
@register_as_period_task(interval=3600*24)
|
@register_as_period_task(interval=3600 * 24)
|
||||||
@after_app_ready_start
|
@after_app_ready_start
|
||||||
@after_app_shutdown_clean_periodic
|
@after_app_shutdown_clean_periodic
|
||||||
def clean_expired_session_period():
|
def clean_expired_session_period():
|
||||||
|
@ -114,3 +113,10 @@ def run_applet_host_deployment(did):
|
||||||
with tmp_to_builtin_org(system=1):
|
with tmp_to_builtin_org(system=1):
|
||||||
deployment = AppletHostDeployment.objects.get(id=did)
|
deployment = AppletHostDeployment.objects.get(id=did)
|
||||||
deployment.start()
|
deployment.start()
|
||||||
|
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def run_applet_host_deployment_install_applet(did, applet_id):
|
||||||
|
with tmp_to_builtin_org(system=1):
|
||||||
|
deployment = AppletHostDeployment.objects.get(id=did)
|
||||||
|
deployment.install_applet(applet_id)
|
||||||
|
|
Loading…
Reference in New Issue