mirror of https://github.com/jumpserver/jumpserver
				
				
				
			
		
			
				
	
	
		
			342 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			YAML
		
	
	
			
		
		
	
	
			342 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			YAML
		
	
	
---
 | 
						|
- hosts: all
 | 
						|
  vars:
 | 
						|
    APPLET_DOWNLOAD_HOST: https://demo.example.com
 | 
						|
    IGNORE_VERIFY_CERTS: true
 | 
						|
    HOST_NAME: test
 | 
						|
    HOST_ID: 00000000-0000-0000-0000-000000000000
 | 
						|
    CORE_HOST: https://demo.example.com
 | 
						|
    BOOTSTRAP_TOKEN: PleaseChangeMe
 | 
						|
    RDS_Licensing: false
 | 
						|
    RDS_LicenseServer: 127.0.0.1
 | 
						|
    RDS_LicensingMode: 4
 | 
						|
    RDS_fSingleSessionPerUser: 1
 | 
						|
    RDS_MaxDisconnectionTime: 60000
 | 
						|
    RDS_RemoteAppLogoffTimeLimit: 0
 | 
						|
    INSTALL_APPLETS: true
 | 
						|
    PYTHON_VERSION: 3.11.11
 | 
						|
    CHROME_VERSION: 118.0.5993.118
 | 
						|
    CHROME_DRIVER_VERSION: 118.0.5993.70
 | 
						|
    TINKER_VERSION: v0.2.2
 | 
						|
 | 
						|
  tasks:
 | 
						|
    - block:
 | 
						|
        - name: Check if CORE_HOST is redirects
 | 
						|
          ansible.windows.win_uri:
 | 
						|
            url: "{{ CORE_HOST }}"
 | 
						|
            method: GET
 | 
						|
            follow_redirects: none
 | 
						|
            status_code: [200, 301, 302, 303, 307, 308]
 | 
						|
            validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
 | 
						|
          register: core_host_redirects
 | 
						|
 | 
						|
        - name: Check failed
 | 
						|
          fail:
 | 
						|
            msg: "CORE_HOST {{ CORE_HOST }} is redirecting to {{ core_host_redirects.location }}, please use the final url"
 | 
						|
          when: core_host_redirects.status_code >= 300 and core_host_redirects.status_code < 400
 | 
						|
 | 
						|
        - name: Create Tinker keyfile
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
 | 
						|
              function New-RandomString {
 | 
						|
                  param (
 | 
						|
                      [int]$Length = 16
 | 
						|
                  )
 | 
						|
                  $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
 | 
						|
                  $random = -join ((1..$Length) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
 | 
						|
                  return $random
 | 
						|
              }
 | 
						|
              $targetPath = "$env:USERPROFILE\AppData\Local\Programs\Tinker\data\keys\access_key"
 | 
						|
              if (Test-Path -Path $targetPath) {
 | 
						|
                Write-Output "access_key already exists at $targetPath"
 | 
						|
                return
 | 
						|
                }
 | 
						|
              $randomStr = New-RandomString -Length 7
 | 
						|
              $dir = [System.IO.Path]::GetDirectoryName($targetPath)
 | 
						|
              if (-not (Test-Path -Path $dir)) {
 | 
						|
                New-Item -ItemType Directory -Path $dir -Force | Out-Null
 | 
						|
              }
 | 
						|
              $url = "{{ CORE_HOST }}/api/v1/terminal/terminal-registrations/"
 | 
						|
 | 
						|
              $body = @{
 | 
						|
                "name" = "[Tinker]-{{ HOST_NAME }}-$randomStr"
 | 
						|
                "comment" = "tinker"
 | 
						|
                "type" = "tinker"
 | 
						|
                }| ConvertTo-Json
 | 
						|
              $headers = @{
 | 
						|
                  "Authorization" = "BootstrapToken {{ BOOTSTRAP_TOKEN }}"
 | 
						|
                  "Content-Type"  = "application/json"
 | 
						|
              }
 | 
						|
              $response = Invoke-RestMethod -Uri $url -Method Post -Body $body -Headers $headers
 | 
						|
              Write-Output "Response: $($response | ConvertTo-Json -Depth 5)"
 | 
						|
              $accessKey = $response.service_account.access_key.id
 | 
						|
              $accessSecret = $response.service_account.access_key.secret
 | 
						|
              if ($accessKey -and $accessSecret) {
 | 
						|
                  $utf8NoBOM = New-Object System.Text.UTF8Encoding($false)
 | 
						|
                  [System.IO.File]::WriteAllText($targetPath, "${accessKey}:${accessSecret}", $utf8NoBOM)
 | 
						|
                  Write-Output "access_key save to $targetPath"
 | 
						|
              } else {
 | 
						|
                  Write-Error "Failed to get access_key or access_secret。"
 | 
						|
              }              
 | 
						|
        - name: Install RDS-RD-Server (RDS)
 | 
						|
          ansible.windows.win_feature:
 | 
						|
            name: RDS-RD-Server
 | 
						|
            state: present
 | 
						|
            include_management_tools: yes
 | 
						|
          register: rds_install
 | 
						|
 | 
						|
        - name: Stop Tinker before install
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              if (Get-Process -Name 'tinker' -ErrorAction SilentlyContinue) {
 | 
						|
                TASKKILL /F /IM tinker.exe /T
 | 
						|
              }
 | 
						|
              else {
 | 
						|
               $Ansible.Changed = $false
 | 
						|
              }              
 | 
						|
 | 
						|
        - name: Download JumpServer Tinker installer
 | 
						|
          ansible.windows.win_get_url:
 | 
						|
            url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/Tinker_Installer_{{ TINKER_VERSION }}.exe"
 | 
						|
            dest: "{{ ansible_env.TEMP }}\\Tinker_Installer_{{ TINKER_VERSION }}.exe"
 | 
						|
            validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
 | 
						|
 | 
						|
        - name: Install JumpServer Tinker
 | 
						|
          ansible.windows.win_package:
 | 
						|
            path: "{{ ansible_env.TEMP }}\\Tinker_Installer_{{ TINKER_VERSION }}.exe"
 | 
						|
            arguments:
 | 
						|
              - /VERYSILENT
 | 
						|
              - /SUPPRESSMSGBOXES
 | 
						|
              - /NORESTART
 | 
						|
            state: present
 | 
						|
 | 
						|
        - name: Set Tinkerd on the global system path
 | 
						|
          ansible.windows.win_path:
 | 
						|
            elements:
 | 
						|
              - '%USERPROFILE%\AppData\Local\Programs\Tinker\'
 | 
						|
            scope: user
 | 
						|
 | 
						|
        - name: Download python-{{ PYTHON_VERSION }}
 | 
						|
          ansible.windows.win_get_url:
 | 
						|
            url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/jumpserver-tinker-python-{{ PYTHON_VERSION }}-win64.zip"
 | 
						|
            dest: "{{ ansible_env.TEMP }}\\jumpserver-tinker-python-{{ PYTHON_VERSION }}-win64.zip"
 | 
						|
            validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
 | 
						|
 | 
						|
        - name: Install the python-{{ PYTHON_VERSION }}
 | 
						|
          community.windows.win_unzip:
 | 
						|
            src: "{{ ansible_env.TEMP }}\\jumpserver-tinker-python-{{ PYTHON_VERSION }}-win64.zip"
 | 
						|
            dest: "%ProgramFiles%\\JumpServer\\applications"
 | 
						|
 | 
						|
        - name: Check and Clean global system path (Python)
 | 
						|
          ansible.windows.win_path:
 | 
						|
            elements:
 | 
						|
              - 'C:\Program Files\Python310\Scripts'
 | 
						|
              - 'C:\Program Files\Python310'
 | 
						|
              - 'C:\Program Files\Python311\Scripts'
 | 
						|
              - 'C:\Program Files\Python311'
 | 
						|
            state: absent
 | 
						|
 | 
						|
        - name: Set python-{{ PYTHON_VERSION }} on the global system path
 | 
						|
          ansible.windows.win_path:
 | 
						|
            elements:
 | 
						|
              - '%ProgramFiles%\JumpServer\applications\Python'
 | 
						|
              - '%ProgramFiles%\JumpServer\applications\Python\Scripts'
 | 
						|
 | 
						|
        - name: Set python-{{ PYTHON_VERSION }} on the global system python path
 | 
						|
          ansible.windows.win_path:
 | 
						|
            name: PYTHONPATH
 | 
						|
            scope: machine
 | 
						|
            elements:
 | 
						|
              - '%ProgramFiles%\JumpServer\applications\Python\packages'
 | 
						|
              - '%ProgramFiles%\JumpServer\applications\Python\Lib\site-packages'
 | 
						|
 | 
						|
        - name: Reboot if installing requires it
 | 
						|
          ansible.windows.win_reboot:
 | 
						|
            post_reboot_delay: 10
 | 
						|
            test_command: whoami
 | 
						|
          when: rds_install.reboot_required
 | 
						|
 | 
						|
        - name: Set RDS LicenseServer (regedit)
 | 
						|
          ansible.windows.win_regedit:
 | 
						|
            path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
 | 
						|
            name: LicenseServers
 | 
						|
            data: "{{ RDS_LicenseServer }}"
 | 
						|
            type: string
 | 
						|
          when: RDS_Licensing
 | 
						|
 | 
						|
        - name: Set RDS LicensingMode (regedit)
 | 
						|
          ansible.windows.win_regedit:
 | 
						|
            path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
 | 
						|
            name: LicensingMode
 | 
						|
            data: "{{ RDS_LicensingMode }}"
 | 
						|
            type: dword
 | 
						|
          when: RDS_Licensing
 | 
						|
 | 
						|
        - name: Set RDS fSingleSessionPerUser (regedit)
 | 
						|
          ansible.windows.win_regedit:
 | 
						|
            path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
 | 
						|
            name: fSingleSessionPerUser
 | 
						|
            data: "{{ RDS_fSingleSessionPerUser }}"
 | 
						|
            type: dword
 | 
						|
          when: RDS_Licensing
 | 
						|
 | 
						|
        - name: Set RDS MaxDisconnectionTime (regedit)
 | 
						|
          ansible.windows.win_regedit:
 | 
						|
            path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
 | 
						|
            name: MaxDisconnectionTime
 | 
						|
            data: "{{ RDS_MaxDisconnectionTime }}"
 | 
						|
            type: dword
 | 
						|
          when: RDS_MaxDisconnectionTime >= 60000
 | 
						|
 | 
						|
        - name: Set RDS RemoteAppLogoffTimeLimit (regedit)
 | 
						|
          ansible.windows.win_regedit:
 | 
						|
            path: HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
 | 
						|
            name: RemoteAppLogoffTimeLimit
 | 
						|
            data: "{{ RDS_RemoteAppLogoffTimeLimit }}"
 | 
						|
            type: dword
 | 
						|
 | 
						|
        - name: Stop chromedriver before install
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              if (Get-Process -Name 'chromedriver' -ErrorAction SilentlyContinue) {
 | 
						|
                TASKKILL /F /IM chromedriver.exe /T
 | 
						|
              }
 | 
						|
              else {
 | 
						|
               $Ansible.Changed = $false
 | 
						|
              }              
 | 
						|
 | 
						|
        - name: Remove old chromedriver (Chrome)
 | 
						|
          ansible.windows.win_file:
 | 
						|
            path: "{{ item }}"
 | 
						|
            state: absent
 | 
						|
          with_items:
 | 
						|
            - 'C:\Program Files\JumpServer\drivers\chromedriver-win32'
 | 
						|
            - 'C:\Program Files\JumpServer\drivers\chromedriver_win32'
 | 
						|
            - 'C:\Program Files\JumpServer\drivers\chromedriver-win64'
 | 
						|
            - 'C:\Program Files\JumpServer\drivers\chromedriver_win64'
 | 
						|
 | 
						|
        - name: Download chromedriver (Chrome)
 | 
						|
          ansible.windows.win_get_url:
 | 
						|
            url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/chromedriver-{{ CHROME_DRIVER_VERSION }}-win64.zip"
 | 
						|
            dest: "{{ ansible_env.TEMP }}\\chromedriver-{{ CHROME_DRIVER_VERSION }}-win64.zip"
 | 
						|
            validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
 | 
						|
 | 
						|
        - name: Unzip chromedriver (Chrome)
 | 
						|
          community.windows.win_unzip:
 | 
						|
            src: "{{ ansible_env.TEMP }}\\chromedriver-{{ CHROME_DRIVER_VERSION }}-win64.zip"
 | 
						|
            dest: "%ProgramFiles%\\JumpServer\\drivers"
 | 
						|
 | 
						|
        - name: Download Chrome zip package (Chrome)
 | 
						|
          ansible.windows.win_get_url:
 | 
						|
            url: "{{ APPLET_DOWNLOAD_HOST }}/download/applets/chrome-{{ CHROME_VERSION }}-win.zip"
 | 
						|
            dest: "{{ ansible_env.TEMP }}\\chrome-{{ CHROME_VERSION }}-win.zip"
 | 
						|
            validate_certs: "{{ not IGNORE_VERIFY_CERTS }}"
 | 
						|
 | 
						|
        - name: Stop Chrome before install
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              if (Get-Process -Name 'chrome' -ErrorAction SilentlyContinue) {
 | 
						|
                TASKKILL /F /IM chrome.exe /T
 | 
						|
              }
 | 
						|
              else {
 | 
						|
               $Ansible.Changed = $false
 | 
						|
              }              
 | 
						|
 | 
						|
        - name: Remove old Chrome (Chrome)
 | 
						|
          ansible.windows.win_file:
 | 
						|
            path: "{{ item }}"
 | 
						|
            state: absent
 | 
						|
          with_items:
 | 
						|
            - 'C:\Program Files\JumpServer\applications\Chrome'
 | 
						|
            - 'C:\Program Files\Chrome\chrome-win32'
 | 
						|
            - 'C:\Program Files\Chrome\chrome-win'
 | 
						|
            - 'C:\Program Files\chrome-win'
 | 
						|
 | 
						|
        - name: Unzip Chrome (Chrome)
 | 
						|
          community.windows.win_unzip:
 | 
						|
            src: "{{ ansible_env.TEMP }}\\chrome-{{ CHROME_VERSION }}-win.zip"
 | 
						|
            dest: "%ProgramFiles%\\JumpServer\\applications"
 | 
						|
 | 
						|
        - name: Check and Clean global system path (Chrome)
 | 
						|
          ansible.windows.win_path:
 | 
						|
            elements:
 | 
						|
              - 'C:\Program Files\JumpServer\drivers\chromedriver-win32'
 | 
						|
              - 'C:\Program Files\JumpServer\drivers\chromedriver_win32'
 | 
						|
              - 'C:\Program Files\Chrome\chrome-win32'
 | 
						|
              - 'C:\Program Files\Chrome\chrome-win'
 | 
						|
              - 'C:\Program Files\chrome-win'
 | 
						|
            state: absent
 | 
						|
 | 
						|
        - name: Set Chrome and driver on the global system path (Chrome)
 | 
						|
          ansible.windows.win_path:
 | 
						|
            elements:
 | 
						|
              - '%ProgramFiles%\JumpServer\applications\Chrome\Application'
 | 
						|
              - '%ProgramFiles%\JumpServer\drivers\chromedriver-win64'
 | 
						|
 | 
						|
        - name: Set Chrome variables disable Google Api (Chrome)
 | 
						|
          ansible.windows.win_environment:
 | 
						|
            level: machine
 | 
						|
            variables:
 | 
						|
              GOOGLE_API_KEY: ""
 | 
						|
              GOOGLE_DEFAULT_CLIENT_ID: ""
 | 
						|
              GOOGLE_DEFAULT_CLIENT_SECRET: ""
 | 
						|
 | 
						|
        - name: Generate tinkerd component config
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              tinkerd config --hostname {{ HOST_NAME }} --core_host {{ CORE_HOST }} --token {{ BOOTSTRAP_TOKEN }} --host_id {{ HOST_ID }} --ignore-verify-certs {{ IGNORE_VERIFY_CERTS }}              
 | 
						|
 | 
						|
        - name: Rename tinkerd keyfile
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              $source = "$env:USERPROFILE\AppData\Local\Programs\Tinker\data\keys\access_key"
 | 
						|
              $destination = "$env:USERPROFILE\AppData\Local\Programs\Tinker\data\keys\.access_key"
 | 
						|
              if (Test-Path $destination) {
 | 
						|
                $timestamp = Get-Date -Format "yyyyMMddHHmmss"
 | 
						|
                  Rename-Item -Path $destination -NewName (Split-Path -Leaf "$destination.bak.$timestamp" )
 | 
						|
              }
 | 
						|
              if (Test-Path $source) {
 | 
						|
                  Rename-Item -Path $source -NewName (Split-Path -Leaf $destination)
 | 
						|
              }              
 | 
						|
 | 
						|
        - name: Install tinkerd service
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              tinkerd service install              
 | 
						|
 | 
						|
        - name: Start tinkerd service
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              tinkerd service start              
 | 
						|
 | 
						|
        - name: Wait Tinker api health
 | 
						|
          ansible.windows.win_uri:
 | 
						|
            url: http://localhost:6068/api/health/
 | 
						|
            status_code: 200
 | 
						|
            method: GET
 | 
						|
          register: _result
 | 
						|
          until: _result.status_code == 200
 | 
						|
          retries: 30
 | 
						|
          delay: 5
 | 
						|
 | 
						|
        - name: Sync all remote applets
 | 
						|
          ansible.windows.win_powershell:
 | 
						|
            script: |
 | 
						|
              tinkerd install all
 | 
						|
              $exitCode = $LASTEXITCODE
 | 
						|
              if ($exitCode -ne 0) {
 | 
						|
                  Write-Host "Failed to install applets"
 | 
						|
                  Write-Host "Exit code: $exitCode"
 | 
						|
                  $Ansible.Failed = $true
 | 
						|
                  exit 1
 | 
						|
              }              
 | 
						|
          register: sync_remote_applets
 | 
						|
          when: INSTALL_APPLETS
 | 
						|
 | 
						|
      rescue:
 | 
						|
        - debug:
 | 
						|
            var: ansible_failed_result
 | 
						|
        - fail:
 | 
						|
            msg: "Failed to deploy applet host"
 |