Merge "Add per-build WinRM cert generation"
This commit is contained in:
commit
775729a4c0
@ -3,6 +3,7 @@ General Purpose Roles
|
||||
|
||||
.. zuul:autorole:: add-authorized-keys
|
||||
.. zuul:autorole:: add-build-sshkey
|
||||
.. zuul:autorole:: add-build-winrm-cert
|
||||
.. zuul:autorole:: add-gpgkey
|
||||
.. zuul:autorole:: add-sshkey
|
||||
.. zuul:autorole:: bindep
|
||||
@ -36,6 +37,7 @@ General Purpose Roles
|
||||
.. zuul:autorole:: prepare-workspace-git
|
||||
.. zuul:autorole:: prepare-workspace-openshift
|
||||
.. zuul:autorole:: remove-build-sshkey
|
||||
.. zuul:autorole:: remove-build-winrm-cert
|
||||
.. zuul:autorole:: remove-gpgkey
|
||||
.. zuul:autorole:: remove-sshkey
|
||||
.. zuul:autorole:: render-diff
|
||||
|
60
roles/add-build-winrm-cert/README.rst
Normal file
60
roles/add-build-winrm-cert/README.rst
Normal file
@ -0,0 +1,60 @@
|
||||
Generate and install a build-local WinRM certificate on all Windows hosts
|
||||
|
||||
This role is intended to be run on the Zuul Executor at the start of
|
||||
every job. It generates a self-signed certificate and installs the
|
||||
certificate on every Windows host in the inventory.
|
||||
|
||||
It then updates the host vars for each such host to use the new
|
||||
certificate. The original certificate used to initially connect to
|
||||
the host still remains on disk, but once the build-local certificate
|
||||
is in place, later untrusted playbooks no longer need it to be
|
||||
provided.
|
||||
|
||||
**Role Variables**
|
||||
|
||||
.. zuul:rolevar:: build_winrm_cert_credentials
|
||||
|
||||
A complex argument expected to be supplied from a Zuul secret.
|
||||
These are the Windows login credentials for the account to
|
||||
associate with the certificate.
|
||||
|
||||
.. zuul:rolevar:: username
|
||||
|
||||
The username of the account.
|
||||
|
||||
.. zuul:rolevar:: password
|
||||
|
||||
The password of the account.
|
||||
|
||||
.. zuul:rolevar:: build_winrm_cert_change_password
|
||||
:default: ``False``
|
||||
|
||||
If this is true, then change the password for the user to the value
|
||||
supplied before adding the certificate. This is useful if the
|
||||
initial account password is automatically generated and otherwise
|
||||
unknown.
|
||||
|
||||
.. zuul:rolevar:: zuul_temp_winrm_name
|
||||
:default: ``{{ zuul.build }}_winrm``
|
||||
|
||||
The base name of the certificate file.
|
||||
|
||||
.. zuul:rolevar:: zuul_temp_winrm_cert
|
||||
:default: ``{{ zuul.executor.work_root }}/{{ zuul_temp_winrm_name }}.crt``
|
||||
|
||||
File name for the the newly-generated certificate.
|
||||
|
||||
.. zuul:rolevar:: zuul_temp_winrm_key
|
||||
:default: ``{{ zuul.executor.work_root }}/{{ zuul_temp_winrm_name }}.key``
|
||||
|
||||
File name for the the newly-generated private key.
|
||||
|
||||
.. zuul:rolevar:: zuul_temp_winrm_pfx
|
||||
:default: ``{{ zuul.executor.work_root }}/{{ zuul_temp_winrm_name }}.pfx``
|
||||
|
||||
Executor-local file name for the the exported certificate.
|
||||
|
||||
.. zuul:rolevar:: zuul_temp_winrm_remote_tempfile
|
||||
:default: ``~/appdata/local/temp/{{ zuul_temp_winrm_name }}.pfx``
|
||||
|
||||
Remote temporary location for the certificate during import.
|
1
roles/add-build-winrm-cert/defaults/main.yaml
Normal file
1
roles/add-build-winrm-cert/defaults/main.yaml
Normal file
@ -0,0 +1 @@
|
||||
build_winrm_cert_change_password: false
|
49
roles/add-build-winrm-cert/tasks/create-key-and-replace.yaml
Normal file
49
roles/add-build-winrm-cert/tasks/create-key-and-replace.yaml
Normal file
@ -0,0 +1,49 @@
|
||||
- name: Create temp WinRM cert
|
||||
command: "openssl req -x509 -newkey rsa:2048 -keyout {{ zuul_temp_winrm_key }} -out {{ zuul_temp_winrm_cert }} -days 365 -nodes -subj '/C=US/ST=California/L=Oakland/O=Company Name/OU=Org/CN={{ zuul.build }}' -addext 'subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:{{ build_winrm_cert_credentials.username }}' -addext 'keyUsage = digitalSignature,keyEncipherment'"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Export temp WinRM cert
|
||||
command: "openssl pkcs12 -export -inkey {{ zuul_temp_winrm_key }} -in {{ zuul_temp_winrm_cert }} -out {{ zuul_temp_winrm_pfx }} -passout pass:{{ zuul_temp_winrm_password }}"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Change password
|
||||
when: build_winrm_cert_change_password
|
||||
win_shell: |
|
||||
net user {{ build_winrm_cert_credentials.username }} "{{ build_winrm_cert_credentials.password }}"
|
||||
|
||||
- name: Copy temp WinRM cert
|
||||
when: ansible_os_family == "Windows"
|
||||
win_copy:
|
||||
src: "{{ zuul_temp_winrm_pfx }}"
|
||||
dest: "{{ zuul_temp_winrm_remote_tempfile }}"
|
||||
|
||||
- name: Import temp WinRM cert
|
||||
when: ansible_os_family == "Windows"
|
||||
win_shell: |
|
||||
$cert = Import-PfxCertificate -FilePath {{ zuul_temp_winrm_remote_tempfile }} -CertStoreLocation Cert:\LocalMachine\root -Password (ConvertTo-SecureString -AsPlainText -String "{{ zuul_temp_winrm_password }}" -Force)
|
||||
|
||||
rm {{ zuul_temp_winrm_remote_tempfile }}
|
||||
|
||||
$password = ConvertTo-SecureString -AsPlainText -String "{{ build_winrm_cert_credentials.password }}" -Force
|
||||
|
||||
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist {{ build_winrm_cert_credentials.username }}, $password
|
||||
|
||||
New-Item -Path WSMan:\localhost\ClientCertificate -Subject {{ build_winrm_cert_credentials.username }} -URI * -Issuer $($cert.Thumbprint) -Force -Credential $cred
|
||||
|
||||
- name: Update WinRM key location
|
||||
when: ansible_os_family == "Windows"
|
||||
set_fact:
|
||||
cacheable: true
|
||||
ansible_winrm_cert_key_pem: "{{ zuul_temp_winrm_key }}"
|
||||
ansible_winrm_cert_pem: "{{ zuul_temp_winrm_cert }}"
|
||||
# These are likely already set to these values, but set them here
|
||||
# anyway to future-proof against potential changes in the executor
|
||||
# to support more initial connection methods.
|
||||
ansible_winrm_transport: certificate
|
||||
ansible_winrm_server_cert_validation: ignore
|
||||
|
||||
- name: Verify we can still connect to all nodes
|
||||
when: ansible_os_family == "Windows"
|
||||
win_ping:
|
17
roles/add-build-winrm-cert/tasks/main.yaml
Normal file
17
roles/add-build-winrm-cert/tasks/main.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
- name: Check to see if WinRM cert was already created for this build
|
||||
stat:
|
||||
path: "{{ zuul_temp_winrm_key }}"
|
||||
register: zuul_temp_winrm_key_stat
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
failed_when: false
|
||||
|
||||
- name: Generate WinRM export password
|
||||
set_fact:
|
||||
zuul_temp_winrm_password: "{{ lookup('password', '/dev/null') }}"
|
||||
no_log: true
|
||||
when: not zuul_temp_winrm_key_stat.stat.exists
|
||||
|
||||
- name: Create a new key in workspace based on build UUID
|
||||
include_tasks: create-key-and-replace.yaml
|
||||
when: not zuul_temp_winrm_key_stat.stat.exists
|
5
roles/add-build-winrm-cert/vars/main.yaml
Normal file
5
roles/add-build-winrm-cert/vars/main.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
zuul_temp_winrm_name: "{{ zuul.build }}_winrm"
|
||||
zuul_temp_winrm_cert: "{{ zuul.executor.work_root }}/{{ zuul_temp_winrm_name }}.crt"
|
||||
zuul_temp_winrm_key: "{{ zuul.executor.work_root }}/{{ zuul_temp_winrm_name }}.key"
|
||||
zuul_temp_winrm_pfx: "{{ zuul.executor.work_root }}/{{ zuul_temp_winrm_name }}.pfx"
|
||||
zuul_temp_winrm_remote_tempfile: "~/appdata/local/temp/{{ zuul_temp_winrm_name }}.pfx"
|
4
roles/remove-build-winrm-cert/README.rst
Normal file
4
roles/remove-build-winrm-cert/README.rst
Normal file
@ -0,0 +1,4 @@
|
||||
Remove the per-build WinRM certificate from all hosts
|
||||
|
||||
The complement to :zuul:role:`add-build-winrm-cert`. It removes the
|
||||
build's WinRM certificate from WSMan registry of all Windows hosts.
|
11
roles/remove-build-winrm-cert/tasks/main.yaml
Normal file
11
roles/remove-build-winrm-cert/tasks/main.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
- name: Remove the build WinRM cert
|
||||
when: ansible_os_family == "Windows"
|
||||
# The script itself may succeed, but we're unable to obtain the
|
||||
# result due to the lost credentials.
|
||||
ignore_errors: true # noqa ignore-errors
|
||||
win_shell: |
|
||||
$cert = get-childitem cert:/localmachine/root | where-object {$_.Subject -match "{{ zuul.build }}"}
|
||||
|
||||
get-childitem wsman:/localhost/clientcertificate | where-object {$_.Keys -match "Issuer=$($cert.Thumbprint)"} | remove-item -recurse
|
||||
|
||||
get-childitem cert:/localmachine/root | where-object {$_.Subject -match "{{ zuul.build }}"} | remove-item
|
Loading…
x
Reference in New Issue
Block a user