win_iis_webbinding rewrite (#33958)
* Begin rewrite of win_iis_webbinding
Add integration testing, check mode and idempotency
Add support for SNI
Fix replacing SSL cert on existing bindings
* finished up initial rewrite of win_iis_webbinding
* updated test to remove tests as filters
* updated win_iis_webbinding docs
* fix more doc/formatting issues win_iis_webbinding
* Removed string empty defaults for certs. Added a few new helpful
comments.
* Revert "Removed string empty defaults for certs. Added a few new helpful"
This reverts commit 48f35faea8
.
This commit is contained in:
parent
e3b49a7aeb
commit
0a3da471f5
11 changed files with 2153 additions and 171 deletions
|
@ -1,131 +1,454 @@
|
||||||
#!powershell
|
#!powershell
|
||||||
|
|
||||||
# (c) 2015, Henrik Wallström <henrik@wallstroms.nu>
|
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
|
||||||
#
|
# Copyright: (c) 2015, Henrik Wallström <henrik@wallstroms.nu>
|
||||||
# This file is part of Ansible
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
#Requires -Module Ansible.ModuleUtils.Legacy
|
||||||
|
|
||||||
# WANT_JSON
|
$params = Parse-Args -arguments $args -supports_check_mode $true
|
||||||
# POWERSHELL_COMMON
|
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
|
||||||
|
|
||||||
$params = Parse-Args $args;
|
$name = Get-AnsibleParam $params -name "name" -type str -failifempty $true -aliases 'website'
|
||||||
|
|
||||||
$name = Get-AnsibleParam $params -name "name" -failifempty $true
|
|
||||||
$state = Get-AnsibleParam $params "state" -default "present" -validateSet "present","absent"
|
$state = Get-AnsibleParam $params "state" -default "present" -validateSet "present","absent"
|
||||||
$host_header = Get-AnsibleParam $params -name "host_header"
|
$host_header = Get-AnsibleParam $params -name "host_header" -type str
|
||||||
$protocol = Get-AnsibleParam $params -name "protocol"
|
$protocol = Get-AnsibleParam $params -name "protocol" -type str -default 'http'
|
||||||
$port = Get-AnsibleParam $params -name "port"
|
$port = Get-AnsibleParam $params -name "port" -default '80'
|
||||||
$ip = Get-AnsibleParam $params -name "ip"
|
$ip = Get-AnsibleParam $params -name "ip" -default '*'
|
||||||
$certificatehash = Get-AnsibleParam $params -name "certificate_hash" -default $false
|
$certificateHash = Get-AnsibleParam $params -name "certificate_hash" -type str -default ([string]::Empty)
|
||||||
$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -default "MY"
|
$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -type str -default ([string]::Empty)
|
||||||
|
$sslFlags = Get-AnsibleParam $params -name "ssl_flags" -default '0' -ValidateSet '0','1','2','3'
|
||||||
|
|
||||||
$binding_parameters = @{
|
|
||||||
Name = $name
|
|
||||||
};
|
|
||||||
|
|
||||||
If ($host_header) {
|
|
||||||
$binding_parameters.HostHeader = $host_header
|
|
||||||
}
|
|
||||||
|
|
||||||
If ($protocol) {
|
|
||||||
$binding_parameters.Protocol = $protocol
|
|
||||||
}
|
|
||||||
|
|
||||||
If ($port) {
|
|
||||||
$binding_parameters.Port = $port
|
|
||||||
}
|
|
||||||
|
|
||||||
If ($ip) {
|
|
||||||
$binding_parameters.IPAddress = $ip
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure WebAdministration module is loaded
|
|
||||||
if ((Get-Module "WebAdministration" -ErrorAction SilentlyContinue) -eq $null){
|
|
||||||
Import-Module WebAdministration
|
|
||||||
}
|
|
||||||
|
|
||||||
function Create-Binding-Info {
|
|
||||||
return @{
|
|
||||||
"bindingInformation" = $args[0].bindingInformation
|
|
||||||
"certificateHash" = $args[0].certificateHash
|
|
||||||
"certificateStoreName" = $args[0].certificateStoreName
|
|
||||||
"isDsMapperEnabled" = $args[0].isDsMapperEnabled
|
|
||||||
"protocol" = $args[0].protocol
|
|
||||||
"sslFlags" = $args[0].sslFlags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Result
|
|
||||||
$result = @{
|
$result = @{
|
||||||
changed = $false
|
changed = $false
|
||||||
parameters = $binding_parameters
|
}
|
||||||
matched = @()
|
|
||||||
removed = @()
|
#################
|
||||||
added = @()
|
### Functions ###
|
||||||
};
|
#################
|
||||||
|
function Create-BindingInfo {
|
||||||
|
$ht = @{
|
||||||
|
'bindingInformation' = $args[0].bindingInformation
|
||||||
|
'ip' = $args[0].bindingInformation.split(':')[0]
|
||||||
|
'port' = [int]$args[0].bindingInformation.split(':')[1]
|
||||||
|
'hostheader' = $args[0].bindingInformation.split(':')[2]
|
||||||
|
#'isDsMapperEnabled' = $args[0].isDsMapperEnabled
|
||||||
|
'protocol' = $args[0].protocol
|
||||||
|
'certificateStoreName' = $args[0].certificateStoreName
|
||||||
|
'certificateHash' = $args[0].certificateHash
|
||||||
|
}
|
||||||
|
|
||||||
|
#handle sslflag support
|
||||||
|
If ([version][System.Environment]::OSVersion.Version -lt [version]'6.2')
|
||||||
|
{
|
||||||
|
$ht.sslFlags = 'not supported'
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$ht.sslFlags = [int]$args[0].sslFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
Return $ht
|
||||||
|
}
|
||||||
|
|
||||||
|
# Used instead of get-webbinding to ensure we always return a single binding
|
||||||
|
# pass it $binding_parameters hashtable
|
||||||
|
function Get-SingleWebBinding {
|
||||||
|
$bind_search_splat = @{
|
||||||
|
'name' = $args[0].name
|
||||||
|
'protocol' = $args[0].protocol
|
||||||
|
'port' = $args[0].port
|
||||||
|
'ip' = $args[0].ip
|
||||||
|
'hostheader' = $args[0].hostheader
|
||||||
|
}
|
||||||
|
|
||||||
|
# if no bindings exist, get-webbinding fails with an error that can't be ignored via error actions on older systems
|
||||||
|
# let's ignore that specific error
|
||||||
|
If (-not $bind_search_splat['hostheader'])
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Get-WebBinding @bind_search_splat | Where-Object {$_.BindingInformation.Split(':')[-1] -eq [string]::Empty}
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
|
||||||
|
{
|
||||||
|
Throw $_.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Get-WebBinding @bind_search_splat
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
|
||||||
|
{
|
||||||
|
Throw $_.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-CertificateSubjects {
|
||||||
|
Param (
|
||||||
|
[string]$CertPath
|
||||||
|
)
|
||||||
|
If (-Not (Test-Path $CertPath) )
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "Unable to locate certificate at $CertPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
$cert = get-item $CertPath
|
||||||
|
|
||||||
|
If ([version][System.Environment]::OSVersion.Version -ge [version]6.2)
|
||||||
|
{
|
||||||
|
$cert.DnsNameList.unicode
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$san = $cert.extensions | Where-Object {$_.Oid.FriendlyName -eq 'Subject Alternative Name'}
|
||||||
|
If ($san)
|
||||||
|
{
|
||||||
|
$san.Format(1) -split '\r\n' | Where-Object {$_} | ForEach-Object {
|
||||||
|
($_ -split '=')[-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
If ($cert.subject -like "*,*")
|
||||||
|
{
|
||||||
|
($cert.Subject | Select-String "CN=(.*?),?").matches.groups[-1].value
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$cert.subject -replace "CN=",''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#############################
|
||||||
|
### Pre-Action Validation ###
|
||||||
|
#############################
|
||||||
|
$os_version = [version][System.Environment]::OSVersion.Version
|
||||||
|
|
||||||
|
# Ensure WebAdministration module is loaded
|
||||||
|
If ($os_version -lt [version]'6.1')
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Add-PSSnapin WebAdministration
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "The WebAdministration snap-in is not present. Please make sure it is installed."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Import-Module WebAdministration
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to load WebAdministration module. Is IIS installed? $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ensure website targetted exists. -Name filter doesn't work on 2k8r2 so do where-object instead
|
||||||
|
$website_check = get-website | Where-Object {$_.name -eq $name}
|
||||||
|
If (-not $website_check)
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "Unable to retrieve website with name $Name. Make sure the website name is valid and exists."
|
||||||
|
}
|
||||||
|
|
||||||
|
# if OS older than 2012 (6.2) and ssl flags are set, fail. Otherwise toggle sni_support
|
||||||
|
If ($os_version -lt [version]'6.2')
|
||||||
|
{
|
||||||
|
If ($sslFlags -ne 0)
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "SNI and Certificate Store support is not available for systems older than 2012 (6.2)"
|
||||||
|
}
|
||||||
|
$sni_support = $false #will cause the sslflags check later to skip
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$sni_support = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
# make sure ssl flags only specified with https protocol
|
||||||
|
If ($protocol -ne 'https' -and $sslFlags -gt 0)
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "SSLFlags can only be set for HTTPS protocol"
|
||||||
|
}
|
||||||
|
|
||||||
|
# validate certificate details if provided
|
||||||
|
# we don't do anything with cert on state: absent, so only validate present
|
||||||
|
If ($certificateHash -and $state -eq 'present')
|
||||||
|
{
|
||||||
|
If ($protocol -ne 'https')
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "You can only provide a certificate thumbprint when protocol is set to https"
|
||||||
|
}
|
||||||
|
|
||||||
|
#apply default for cert store name
|
||||||
|
If (-Not $certificateStoreName)
|
||||||
|
{
|
||||||
|
$certificateStoreName = 'my'
|
||||||
|
}
|
||||||
|
|
||||||
|
#validate cert path
|
||||||
|
$cert_path = "cert:\LocalMachine\$certificateStoreName\$certificateHash"
|
||||||
|
If (-Not (Test-Path $cert_path) )
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "Unable to locate certificate at $cert_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
#check if cert is wildcard and update results with useful info.
|
||||||
|
$cert_subjects = Get-CertificateSubjects $cert_path
|
||||||
|
$result.certificate_subjects = $cert_subjects
|
||||||
|
If ($cert_subjects | Where-Object {$_ -match '^\*'})
|
||||||
|
{
|
||||||
|
$cert_is_wildcard = $true
|
||||||
|
$result.cert_is_wildcard = $cert_is_wildcard
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$cert_is_wildcard = $false
|
||||||
|
$result.cert_is_wildcard = $cert_is_wildcard
|
||||||
|
}
|
||||||
|
|
||||||
|
If ($os_version -lt [version]6.2 -and $host_header -and -not $cert_is_wildcard)
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "You cannot specify host headers with SSL unless it is a wildcard certificate."
|
||||||
|
}
|
||||||
|
Elseif ($os_version -ge [version]6.2 -and $host_header -and (-not $cert_is_wildcard -and $sslFlags -eq 0))
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "You cannot specify host headers with SSL unless it is a wildcard certificate or SNI is enabled."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# make sure binding info is valid for central cert store if sslflags -gt 1
|
||||||
|
If ($sslFlags -gt 1 -and ($certificateHash -ne [string]::Empty -or $certificateStoreName -ne [string]::Empty))
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "You set sslFlags to $sslFlags. This indicates you wish to use the Central Certificate Store feature.
|
||||||
|
This cannot be used in combination with certficiate_hash and certificate_store_name. When using the Central Certificate Store feature,
|
||||||
|
the certificate is automatically retrieved from the store rather than manually assigned to the binding."
|
||||||
|
}
|
||||||
|
|
||||||
|
# make sure host_header: '*' only present when state: absent
|
||||||
|
If ($host_header -match '^\*$' -and $state -ne 'absent')
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "host_header: '*' can only be used in combinaiton with state: absent"
|
||||||
|
}
|
||||||
|
|
||||||
|
##########################
|
||||||
|
### start action items ###
|
||||||
|
##########################
|
||||||
|
|
||||||
|
# create binding search splat
|
||||||
|
$binding_parameters = @{
|
||||||
|
Name = $name
|
||||||
|
Protocol = $protocol
|
||||||
|
Port = $port
|
||||||
|
IPAddress = $ip
|
||||||
|
}
|
||||||
|
|
||||||
|
# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip)
|
||||||
|
If ($host_header)
|
||||||
|
{
|
||||||
|
$binding_parameters.HostHeader = $host_header
|
||||||
|
}
|
||||||
|
|
||||||
# Get bindings matching parameters
|
# Get bindings matching parameters
|
||||||
$curent_bindings = Get-WebBinding @binding_parameters
|
Try {
|
||||||
$curent_bindings | Foreach {
|
$current_bindings = Get-SingleWebBinding $binding_parameters
|
||||||
$result.matched += Create-Binding-Info $_
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to retrieve bindings with Get-SingleWebBinding - $($_.Exception.Message)"
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
################################################
|
||||||
# Add
|
### Remove binding or exit if already absent ###
|
||||||
if (-not $curent_bindings -and $state -eq 'present') {
|
################################################
|
||||||
New-WebBinding @binding_parameters -Force
|
If ($current_bindings -and $state -eq 'absent')
|
||||||
|
{
|
||||||
# Select certificate
|
Try {
|
||||||
if($certificateHash -ne $FALSE) {
|
# will remove multiple objects in the case of * host header
|
||||||
|
$current_bindings | Remove-WebBinding -WhatIf:$check_mode
|
||||||
$ip = $binding_parameters["IPAddress"]
|
$result.changed = $true
|
||||||
if((!$ip) -or ($ip -eq "*")) {
|
}
|
||||||
$ip = "0.0.0.0"
|
Catch {
|
||||||
}
|
Fail-Json -obj $result -message "Failed to remove the binding from IIS - $($_.Exception.Message)"
|
||||||
|
|
||||||
$port = $binding_parameters["Port"]
|
|
||||||
if(!$port) {
|
|
||||||
$port = 443
|
|
||||||
}
|
|
||||||
|
|
||||||
$result.port = $port
|
|
||||||
$result.ip = $ip
|
|
||||||
|
|
||||||
Push-Location IIS:\SslBindings\
|
|
||||||
Get-Item Cert:\LocalMachine\$certificateStoreName\$certificateHash | New-Item "$($ip)!$($port)"
|
|
||||||
Pop-Location
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result.added += Create-Binding-Info (Get-WebBinding @binding_parameters)
|
# removing bindings from iis may not also remove them from iis:\sslbindings
|
||||||
$result.changed = $true
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove
|
$result.operation_type = 'removed'
|
||||||
if ($curent_bindings -and $state -eq 'absent') {
|
$result.binding_info = $current_bindings | ForEach-Object {Create-BindingInfo $_}
|
||||||
$curent_bindings | foreach {
|
Exit-Json -obj $result
|
||||||
Remove-WebBinding -InputObject $_
|
}
|
||||||
$result.removed += Create-Binding-Info $_
|
ElseIf (-Not $current_bindings -and $state -eq 'absent')
|
||||||
|
{
|
||||||
|
# exit changed: false since it's already gone
|
||||||
|
Exit-Json -obj $result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
################################
|
||||||
|
### Modify existing bindings ###
|
||||||
|
################################
|
||||||
|
<#
|
||||||
|
since we have already.binding_info the parameters available to get-webbinding,
|
||||||
|
we just need to check here for the ones that are not available which are the
|
||||||
|
ssl settings (hash, store, sslflags). If they aren't set we update here, or
|
||||||
|
exit with changed: false
|
||||||
|
#>
|
||||||
|
ElseIf ($current_bindings)
|
||||||
|
{
|
||||||
|
#ran into a strange edge case in testing where I was able to retrieve bindings but not expand all the properties
|
||||||
|
#when adding a self-signed wildcard cert to a binding. it seemed to permanently break the binding. only removing it
|
||||||
|
#would cause the error to stop.
|
||||||
|
Try {
|
||||||
|
$null = $current_bindings | Select-Object *
|
||||||
}
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Found a matching binding, but failed to expand it's properties (get-binding | FL *). In testing, this was caused by using a self-signed wildcard certificate. $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# check if there is a match on the ssl parameters
|
||||||
|
If ( ($current_bindings.sslFlags -ne $sslFlags -and $sni_support) -or
|
||||||
|
$current_bindings.certificateHash -ne $certificateHash -or
|
||||||
|
$current_bindings.certificateStoreName -ne $certificateStoreName)
|
||||||
|
{
|
||||||
|
# match/update SNI
|
||||||
|
If ($current_bindings.sslFlags -ne $sslFlags -and $sni_support)
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Set-WebBinding -Name $name -IPAddress $ip -Port $port -HostHeader $host_header -PropertyName sslFlags -value $sslFlags -whatif:$check_mode
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to update sslFlags on binding - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Refresh the binding object since it has been changed
|
||||||
|
Try {
|
||||||
|
$current_bindings = Get-SingleWebBinding $binding_parameters
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to refresh bindings after setting sslFlags - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# match/update certificate
|
||||||
|
If ($current_bindings.certificateHash -ne $certificateHash -or $current_bindings.certificateStoreName -ne $certificateStoreName)
|
||||||
|
{
|
||||||
|
If (-Not $check_mode)
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
$current_bindings.AddSslCertificate($certificateHash,$certificateStoreName)
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to set new SSL certificate - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
$result.operation_type = 'updated'
|
||||||
|
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
|
||||||
|
$result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters)
|
||||||
|
Exit-Json -obj $result #exit changed true
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$result.operation_type = 'matched'
|
||||||
|
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
|
||||||
|
$result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters)
|
||||||
|
Exit-Json -obj $result #exit changed false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
########################
|
||||||
|
### Add new bindings ###
|
||||||
|
########################
|
||||||
|
ElseIf (-not $current_bindings -and $state -eq 'present')
|
||||||
|
{
|
||||||
|
If ($certificateHash)
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
Make sure a valid binding is specified. It's possible for another site to have a binding on the same IP:PORT. If
|
||||||
|
we bind to that same ip port without hostheader/sni it will cause a collision. Note, this check only matters for
|
||||||
|
https. Http will generate an error when new-webbinding is called if there is a conflict, unlike https.
|
||||||
|
|
||||||
|
I couldn't think of a good way to handle scenarios involving wildcards. There's just too many to think about and I
|
||||||
|
wouldn't want to potentially hard fail valid scenarios here that I did not consider...so those can still collide. We just skip
|
||||||
|
validation anytime an existing binding is a wildcard.
|
||||||
|
|
||||||
|
If a collision does occur, the website will be stopped. To help with this we'll return the website state into results.
|
||||||
|
#>
|
||||||
|
|
||||||
|
#use this instead of get-webbinding. on 2k8r2 get-webbinding fails with an error if a site with no bindings exists
|
||||||
|
$binding_matches = (Get-Website).bindings.collection | Where-Object {$_.BindingInformation -eq "$ip`:$port`:"}
|
||||||
|
|
||||||
|
#get dns names for all certs in matching bindings
|
||||||
|
$subjects = Foreach ($binding in $binding_matches)
|
||||||
|
{
|
||||||
|
$cert_path = "cert:\localmachine\$($binding.certificatestorename)\$($binding.certificatehash)"
|
||||||
|
Get-CertificateSubjects $cert_path
|
||||||
|
}
|
||||||
|
|
||||||
|
#skip validating scenarios where existing certs are wildcard
|
||||||
|
If (-not ($subjects | Where-Object {$_ -match "^\*"}))
|
||||||
|
{
|
||||||
|
If ($sslFlags -eq 0 -and $binding_matches -and $os_version -gt [version]6.2)
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "A conflicting binding has been found on the same ip $ip and port $port. To continue, you will either have to remove the offending binding or enable sni"
|
||||||
|
}
|
||||||
|
ElseIf ($binding_matches -and $os_version -lt [version]6.2)
|
||||||
|
{
|
||||||
|
Fail-Json -obj $result -message "A conflicting binding has been found on the same ip $ip and port $port. To continue you will need to remove the existing binding or assign a new IP or Port to this one"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# add binding. this creates the binding, but does not apply a certificate to it.
|
||||||
|
Try
|
||||||
|
{
|
||||||
|
If (-not $check_mode)
|
||||||
|
{
|
||||||
|
If ($sni_support)
|
||||||
|
{
|
||||||
|
New-WebBinding @binding_parameters -SslFlags $sslFlags -Force
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
New-WebBinding @binding_parameters -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result.changed = $true
|
||||||
|
}
|
||||||
|
Catch
|
||||||
|
{
|
||||||
|
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
|
||||||
|
Fail-Json -obj $result -message "Failed at creating new binding (note: creating binding and adding ssl are separate steps) - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# add certificate to binding
|
||||||
|
If ($certificateHash -and -not $check_mode)
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
$new_binding = get-webbinding -Name $name -IPAddress $ip -port $port -Protocol $protocol -hostheader $host_header
|
||||||
|
$new_binding.addsslcertificate($certificateHash,$certificateStoreName)
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
|
||||||
|
Fail-Json -obj $result -message "Failed to set new SSL certificate - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$result.changed = $true
|
$result.changed = $true
|
||||||
}
|
$result.operation_type = 'added'
|
||||||
|
$result.website_state = (Get-Website | Where-Object {$_.Name -eq $Name}).State
|
||||||
|
$result.binding_info = Create-BindingInfo (Get-SingleWebBinding $binding_parameters)
|
||||||
|
Exit-Json $result
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
Fail-Json $result $_.Exception.Message
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit-Json $result
|
|
||||||
|
|
|
@ -1,22 +1,9 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# (c) 2015, Henrik Wallström <henrik@wallstroms.nu>
|
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
|
||||||
#
|
# Copyright: (c) 2017, Henrik Wallström <henrik@wallstroms.nu>
|
||||||
# This file is part of Ansible
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||||
|
@ -28,7 +15,7 @@ DOCUMENTATION = r'''
|
||||||
---
|
---
|
||||||
module: win_iis_webbinding
|
module: win_iis_webbinding
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
short_description: Configures a IIS Web site.
|
short_description: Configures a IIS Web site binding.
|
||||||
description:
|
description:
|
||||||
- Creates, Removes and configures a binding to an existing IIS Web site
|
- Creates, Removes and configures a binding to an existing IIS Web site
|
||||||
options:
|
options:
|
||||||
|
@ -36,66 +23,51 @@ options:
|
||||||
description:
|
description:
|
||||||
- Names of web site
|
- Names of web site
|
||||||
required: true
|
required: true
|
||||||
default: null
|
aliases: [website]
|
||||||
aliases: []
|
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- State of the binding
|
- State of the binding
|
||||||
choices:
|
choices:
|
||||||
- present
|
- present
|
||||||
- absent
|
- absent
|
||||||
required: false
|
default: present
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
port:
|
port:
|
||||||
description:
|
description:
|
||||||
- The port to bind to / use for the new site.
|
- The port to bind to / use for the new site.
|
||||||
required: false
|
default: 80
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
ip:
|
ip:
|
||||||
description:
|
description:
|
||||||
- The IP address to bind to / use for the new site.
|
- The IP address to bind to / use for the new site.
|
||||||
required: false
|
default: '*'
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
host_header:
|
host_header:
|
||||||
description:
|
description:
|
||||||
- The host header to bind to / use for the new site.
|
- The host header to bind to / use for the new site.
|
||||||
required: false
|
- For state absent, you can use c('*') here to remove all bindings for a particular
|
||||||
default: null
|
protocol/ip/port combination.
|
||||||
aliases: []
|
|
||||||
protocol:
|
protocol:
|
||||||
description:
|
description:
|
||||||
- The protocol to be used for the Web binding (usually HTTP, HTTPS, or FTP).
|
- The protocol to be used for the Web binding (usually HTTP, HTTPS, or FTP).
|
||||||
required: false
|
default: http
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
certificate_hash:
|
certificate_hash:
|
||||||
description:
|
description:
|
||||||
- Certificate hash for the SSL binding. The certificate hash is the unique identifier for the certificate.
|
- Certificate hash (thumbprint) for the SSL binding. The certificate hash is the unique identifier for the certificate.
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
aliases: []
|
|
||||||
certificate_store_name:
|
certificate_store_name:
|
||||||
description:
|
description:
|
||||||
- Name of the certificate store where the certificate for the binding is located.
|
- Name of the certificate store where the certificate for the binding is located.
|
||||||
required: false
|
default: "my"
|
||||||
default: "My"
|
ssl_flags:
|
||||||
aliases: []
|
description:
|
||||||
author: Henrik Wallström
|
- This parameter is only valid on Server 2012 and newer.
|
||||||
|
- Primarily used for enabling and disabling server name indication (SNI).
|
||||||
|
- Set to c(0) to disable SNI.
|
||||||
|
- Set to c(1) to enable SNI.
|
||||||
|
version_added: "2.5"
|
||||||
|
author:
|
||||||
|
- Noah Sparks (@nwsparks)
|
||||||
|
- Henrik Wallström
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Return binding information for an existing host
|
|
||||||
win_iis_webbinding:
|
|
||||||
name: Default Web Site
|
|
||||||
|
|
||||||
- name: Return the HTTPS binding information for an existing host
|
|
||||||
win_iis_webbinding:
|
|
||||||
name: Default Web Site
|
|
||||||
protocol: https
|
|
||||||
|
|
||||||
- name: Add a HTTP binding on port 9090
|
- name: Add a HTTP binding on port 9090
|
||||||
win_iis_webbinding:
|
win_iis_webbinding:
|
||||||
name: Default Web Site
|
name: Default Web Site
|
||||||
|
@ -112,20 +84,76 @@ EXAMPLES = r'''
|
||||||
win_iis_webbinding:
|
win_iis_webbinding:
|
||||||
name: Default Web Site
|
name: Default Web Site
|
||||||
protocol: https
|
protocol: https
|
||||||
state: present
|
port: 443
|
||||||
|
|
||||||
- name: Add a HTTPS binding and select certificate to use
|
|
||||||
win_iis_webbinding:
|
|
||||||
name: Default Web Site
|
|
||||||
protocol: https
|
|
||||||
certificate_hash: B0D0FA8408FC67B230338FCA584D03792DA73F4C
|
certificate_hash: B0D0FA8408FC67B230338FCA584D03792DA73F4C
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Website https biding to specific port
|
- name: Add a HTTPS binding with host header and SNI enabled
|
||||||
win_iis_webbinding:
|
win_iis_webbinding:
|
||||||
name: Default Web Site
|
name: Default Web Site
|
||||||
protocol: https
|
protocol: https
|
||||||
port: 443
|
port: 443
|
||||||
|
host_header: test.com
|
||||||
|
ssl_flags: 1
|
||||||
certificate_hash: D1A3AF8988FD32D1A3AF8988FD323792DA73F4C
|
certificate_hash: D1A3AF8988FD32D1A3AF8988FD323792DA73F4C
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Remove all https bindings on port 443
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: Default Web Site
|
||||||
|
protocol: https
|
||||||
|
port: 443
|
||||||
|
host_header: '*'
|
||||||
|
state: absent
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
cert_is_wildcard:
|
||||||
|
description:
|
||||||
|
- Tells you if the certificate you are using is a wildcard
|
||||||
|
returned: when certificate_hash is defined
|
||||||
|
type: boolean
|
||||||
|
sample: false
|
||||||
|
version_added: "2.5"
|
||||||
|
certificate_subjects:
|
||||||
|
description:
|
||||||
|
- All of the subject names for the certificate you are using
|
||||||
|
returned: when certificate_hash is defined
|
||||||
|
type: list
|
||||||
|
sample: ["*.test.com","test.com"]
|
||||||
|
version_added: "2.5"
|
||||||
|
website_state:
|
||||||
|
description:
|
||||||
|
- The state of the website being targetted
|
||||||
|
- Can be helpful in case you accidentally cause a binding collision
|
||||||
|
which can result in the targetted site being stopped
|
||||||
|
returned: always
|
||||||
|
type: string
|
||||||
|
sample: "Started"
|
||||||
|
version_added: "2.5"
|
||||||
|
operation_type:
|
||||||
|
description:
|
||||||
|
- The type of operation performed
|
||||||
|
- Can be removed, updated, matched, or added
|
||||||
|
returned: on success
|
||||||
|
type: string
|
||||||
|
sample: "removed"
|
||||||
|
version_added: "2.5"
|
||||||
|
binding_info:
|
||||||
|
description:
|
||||||
|
- Information on the binding being manipulated
|
||||||
|
returned: on success
|
||||||
|
type: dictionary
|
||||||
|
sample: |-
|
||||||
|
"binding_info": {
|
||||||
|
"bindingInformation": "127.0.0.1:443:",
|
||||||
|
"certificateHash": "FF3910CE089397F1B5A77EB7BAFDD8F44CDE77DD",
|
||||||
|
"certificateStoreName": "MY",
|
||||||
|
"hostheader": "",
|
||||||
|
"ip": "127.0.0.1",
|
||||||
|
"port": 443,
|
||||||
|
"protocol": "https",
|
||||||
|
"sslFlags": "not supported"
|
||||||
|
}
|
||||||
|
version_added: "2.5"
|
||||||
'''
|
'''
|
||||||
|
|
1
test/integration/targets/win_iis_webbinding/aliases
Normal file
1
test/integration/targets/win_iis_webbinding/aliases
Normal file
|
@ -0,0 +1 @@
|
||||||
|
windows/ci/group2
|
|
@ -0,0 +1,30 @@
|
||||||
|
test_iis_site_name: default web site
|
||||||
|
|
||||||
|
http_vars:
|
||||||
|
protocol: http
|
||||||
|
port: 80
|
||||||
|
ip: '*'
|
||||||
|
|
||||||
|
http_header_vars:
|
||||||
|
protocol: http
|
||||||
|
port: 80
|
||||||
|
ip: '*'
|
||||||
|
header: test.com
|
||||||
|
|
||||||
|
https_vars:
|
||||||
|
protocol: https
|
||||||
|
port: 443
|
||||||
|
ip: '*'
|
||||||
|
|
||||||
|
https_header_vars:
|
||||||
|
protocol: https
|
||||||
|
port: 443
|
||||||
|
ip: '*'
|
||||||
|
header: test.com
|
||||||
|
ssl_flags: 1
|
||||||
|
|
||||||
|
https_wc_vars:
|
||||||
|
protocol: https
|
||||||
|
port: 443
|
||||||
|
ip: '127.0.0.1'
|
||||||
|
header: wc.test.com
|
|
@ -0,0 +1,122 @@
|
||||||
|
#!powershell
|
||||||
|
|
||||||
|
# Copyright: (c) 2017, Noah Sparks <nsparks@outlook.com>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
#Requires -Module Ansible.ModuleUtils.Legacy
|
||||||
|
#
|
||||||
|
$params = Parse-Args -arguments $args -supports_check_mode $true
|
||||||
|
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
|
||||||
|
|
||||||
|
$name = Get-AnsibleParam $params -name "name" -type str -failifempty $true -aliases 'website'
|
||||||
|
#$state = Get-AnsibleParam $params "state" -default "present" -validateSet "present","absent"
|
||||||
|
$host_header = Get-AnsibleParam $params -name "host_header" -type str
|
||||||
|
$protocol = Get-AnsibleParam $params -name "protocol" -type str -default 'http'
|
||||||
|
$port = Get-AnsibleParam $params -name "port" -type int -default '80'
|
||||||
|
$ip = Get-AnsibleParam $params -name "ip" -default '*'
|
||||||
|
$certificateHash = Get-AnsibleParam $params -name "certificate_hash" -type str
|
||||||
|
$certificateStoreName = Get-AnsibleParam $params -name "certificate_store_name" -type str
|
||||||
|
$sslFlags = Get-AnsibleParam $params -name "ssl_flags" -type int -default '0' -ValidateSet '0','1','2','3'
|
||||||
|
|
||||||
|
$result = @{
|
||||||
|
changed = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
function Create-BindingInfo {
|
||||||
|
$ht = @{
|
||||||
|
'bindingInformation' = $args[0].bindingInformation
|
||||||
|
'ip' = $args[0].bindingInformation.split(':')[0]
|
||||||
|
'port' = [int]$args[0].bindingInformation.split(':')[1]
|
||||||
|
'hostheader' = $args[0].bindingInformation.split(':')[2]
|
||||||
|
'isDsMapperEnabled' = $args[0].isDsMapperEnabled
|
||||||
|
'protocol' = $args[0].protocol
|
||||||
|
'certificateStoreName' = $args[0].certificateStoreName
|
||||||
|
'certificateHash' = $args[0].certificateHash
|
||||||
|
}
|
||||||
|
|
||||||
|
#handle sslflag support
|
||||||
|
If ([version][System.Environment]::OSVersion.Version -lt [version]'6.2')
|
||||||
|
{
|
||||||
|
$ht.sslFlags = 'not supported'
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
$ht.sslFlags = [int]$args[0].sslFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
Return $ht
|
||||||
|
}
|
||||||
|
|
||||||
|
# Used instead of get-webbinding to ensure we always return a single binding
|
||||||
|
# pass it $binding_parameters hashtable
|
||||||
|
function Get-SingleWebBinding {
|
||||||
|
$bind_search_splat = @{
|
||||||
|
'name' = $args[0].name
|
||||||
|
'protocol' = $args[0].protocol
|
||||||
|
'port' = $args[0].port
|
||||||
|
'ip' = $args[0].ip
|
||||||
|
'hostheader' = $args[0].hostheader
|
||||||
|
}
|
||||||
|
|
||||||
|
# if no bindings exist, get-webbinding fails with an error that can't be ignored via error actions on older systems
|
||||||
|
# let's ignore that specific error
|
||||||
|
If (-not $bind_search_splat['hostheader'])
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Get-WebBinding @bind_search_splat | Where-Object {$_.BindingInformation.Split(':')[-1] -eq [string]::Empty}
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
|
||||||
|
{
|
||||||
|
Throw $_.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Else
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
Get-WebBinding @bind_search_splat
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
If (-not $_.Exception.Message.CompareTo('Cannot process argument because the value of argument "obj" is null. Change the value of argument "obj" to a non-null value'))
|
||||||
|
{
|
||||||
|
Throw $_.Exception.Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# create binding search splat
|
||||||
|
$binding_parameters = @{
|
||||||
|
Name = $name
|
||||||
|
Protocol = $protocol
|
||||||
|
Port = $port
|
||||||
|
IPAddress = $ip
|
||||||
|
}
|
||||||
|
|
||||||
|
# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip)
|
||||||
|
If ($host_header)
|
||||||
|
{
|
||||||
|
$binding_parameters.HostHeader = $host_header
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get bindings matching parameters
|
||||||
|
Try {
|
||||||
|
$current_bindings = Get-SingleWebBinding $binding_parameters
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to retrieve bindings with Get-SingleWebBinding - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
If ($current_bindings)
|
||||||
|
{
|
||||||
|
Try {
|
||||||
|
$binding_info = Create-BindingInfo $current_bindings
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
Fail-Json -obj $result -message "Failed to create binding info - $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
|
||||||
|
$result.binding = $binding_info
|
||||||
|
}
|
||||||
|
exit-json -obj $result
|
|
@ -0,0 +1,74 @@
|
||||||
|
- name: failure check bind with host header but no wc or sni
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: test.com
|
||||||
|
protocol: https
|
||||||
|
ip: '*'
|
||||||
|
port: 443
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
ssl_flags: 0
|
||||||
|
register: failure
|
||||||
|
failed_when:
|
||||||
|
- failure.msg != "You cannot specify host headers with SSL unless it is a wildcard certificate."
|
||||||
|
- failure.msg != "You cannot specify host headers with SSL unless it is a wildcard certificate or SNI is enabled."
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
var: failure
|
||||||
|
verbosity: 1
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: get all websites from server
|
||||||
|
raw: powershell.exe "(get-website).name"
|
||||||
|
register: existing_sites
|
||||||
|
|
||||||
|
- name: ensure all sites are removed for clean testing
|
||||||
|
win_iis_website:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "{{ existing_sites.stdout_lines }}"
|
||||||
|
|
||||||
|
- name: add sites
|
||||||
|
win_iis_website:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
state: started
|
||||||
|
ip: 127.0.0.1
|
||||||
|
port: "{{ item.port }}"
|
||||||
|
physical_path: c:\inetpub\wwwroot
|
||||||
|
with_items:
|
||||||
|
- {name: testconflict1, port: 8080}
|
||||||
|
- {name: testconflict2, port: 8081}
|
||||||
|
|
||||||
|
- name: add https binding to testconflict1
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: testconflict1
|
||||||
|
state: present
|
||||||
|
protocol: https
|
||||||
|
port: 443
|
||||||
|
ip: 127.0.0.1
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
- name: add https binding to testconflict2 (expect failure)
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: testconflict2
|
||||||
|
state: present
|
||||||
|
protocol: https
|
||||||
|
ip: 127.0.0.1
|
||||||
|
port: 443
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: failure
|
||||||
|
failed_when: '"A conflicting binding has been found on the same ip" not in failure.msg'
|
||||||
|
|
||||||
|
- debug:
|
||||||
|
var: failure
|
||||||
|
verbosity: 1
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: remove websites
|
||||||
|
win_iis_website:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- testconflict1
|
||||||
|
- testconflict2
|
372
test/integration/targets/win_iis_webbinding/tasks/http.yml
Normal file
372
test/integration/targets/win_iis_webbinding/tasks/http.yml
Normal file
|
@ -0,0 +1,372 @@
|
||||||
|
#cm add
|
||||||
|
#changed true, check nothing present
|
||||||
|
- name: CM add http binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: http_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: CM get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: get_http_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM add http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: http_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: CM get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: get_http_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM assert changed, but not added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_no_header is changed
|
||||||
|
- http_no_header.binding_info is none
|
||||||
|
- get_http_no_header.binding is not defined
|
||||||
|
- http_header is changed
|
||||||
|
- http_header.binding_info is none
|
||||||
|
- get_http_header.binding is not defined
|
||||||
|
|
||||||
|
#add
|
||||||
|
#changed true, new bindings present
|
||||||
|
- name: add http binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: http_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: get_http_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: add http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: http_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: get_http_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: assert changed and added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_no_header is changed
|
||||||
|
- http_no_header.binding_info is defined
|
||||||
|
- http_no_header.operation_type == 'added'
|
||||||
|
- http_no_header.binding_info.ip == "{{ http_vars.ip }}"
|
||||||
|
- http_no_header.binding_info.port == {{ http_vars.port }}
|
||||||
|
- http_no_header.binding_info.protocol == "{{ http_vars.protocol }}"
|
||||||
|
- http_header is changed
|
||||||
|
- http_header.binding_info is defined
|
||||||
|
- http_header.operation_type == 'added'
|
||||||
|
- http_header.binding_info.ip == "{{ http_header_vars.ip }}"
|
||||||
|
- http_header.binding_info.port == {{ http_header_vars.port }}
|
||||||
|
- http_header.binding_info.protocol == "{{ http_header_vars.protocol }}"
|
||||||
|
- http_header.binding_info.hostheader == "{{ http_header_vars.header }}"
|
||||||
|
|
||||||
|
#add idem
|
||||||
|
#changed false
|
||||||
|
- name: idem add http binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: http_no_header
|
||||||
|
|
||||||
|
- name: idem add http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: http_header
|
||||||
|
|
||||||
|
- name: idem assert not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_no_header is not changed
|
||||||
|
- http_header is not changed
|
||||||
|
|
||||||
|
#modify
|
||||||
|
#can't test modify for http, it will add a new binding instead since
|
||||||
|
#there's no way to match existing bindings against the new parameters
|
||||||
|
|
||||||
|
#cm remove
|
||||||
|
#changed true, bindings still present
|
||||||
|
- name: cm remove http binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: http_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: get_http_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: cm remove http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: http_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: get_http_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: cm remove assert changed, but still present
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_no_header is changed
|
||||||
|
- http_no_header.binding_info is defined
|
||||||
|
- http_no_header.operation_type == 'removed'
|
||||||
|
- http_no_header.binding_info.ip == "{{ http_vars.ip }}"
|
||||||
|
- http_no_header.binding_info.port == {{ http_vars.port }}
|
||||||
|
- http_no_header.binding_info.protocol == "{{ http_vars.protocol }}"
|
||||||
|
- get_http_no_header.binding is defined
|
||||||
|
- get_http_no_header.binding.ip == "{{ http_vars.ip }}"
|
||||||
|
- get_http_no_header.binding.port == {{ http_vars.port }}
|
||||||
|
- get_http_no_header.binding.protocol == "{{ http_vars.protocol }}"
|
||||||
|
- http_header is changed
|
||||||
|
- http_header.binding_info is defined
|
||||||
|
- http_header.operation_type == 'removed'
|
||||||
|
- http_header.binding_info.ip == "{{ http_header_vars.ip }}"
|
||||||
|
- http_header.binding_info.port == {{ http_header_vars.port }}
|
||||||
|
- http_header.binding_info.protocol == "{{ http_header_vars.protocol }}"
|
||||||
|
- http_header.binding_info.hostheader == "{{ http_header_vars.header }}"
|
||||||
|
- get_http_header.binding is defined
|
||||||
|
- get_http_header.binding.ip == "{{ http_header_vars.ip }}"
|
||||||
|
- get_http_header.binding.port == {{ http_header_vars.port }}
|
||||||
|
- get_http_header.binding.protocol == "{{ http_header_vars.protocol }}"
|
||||||
|
- get_http_header.binding.hostheader == "{{ http_header_vars.header }}"
|
||||||
|
|
||||||
|
|
||||||
|
#remove
|
||||||
|
#changed true, bindings gone
|
||||||
|
- name: remove http binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: http_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: get_http_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: remove http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: http_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: get_http_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: remove assert changed and gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_no_header is changed
|
||||||
|
- http_no_header.operation_type == 'removed'
|
||||||
|
- http_no_header.binding_info is defined
|
||||||
|
- http_no_header.binding_info.ip == "{{ http_vars.ip }}"
|
||||||
|
- http_no_header.binding_info.port == {{ http_vars.port }}
|
||||||
|
- http_no_header.binding_info.protocol == "{{ http_vars.protocol }}"
|
||||||
|
- get_http_no_header.binding is not defined
|
||||||
|
- http_header is changed
|
||||||
|
- http_header.binding_info is defined
|
||||||
|
- http_header.operation_type == 'removed'
|
||||||
|
- http_header.binding_info.ip == "{{ http_header_vars.ip }}"
|
||||||
|
- http_header.binding_info.port == {{ http_header_vars.port }}
|
||||||
|
- http_header.binding_info.protocol == "{{ http_header_vars.protocol }}"
|
||||||
|
- http_header.binding_info.hostheader == "{{ http_header_vars.header }}"
|
||||||
|
- get_http_header.binding is not defined
|
||||||
|
|
||||||
|
#remove idem
|
||||||
|
#change false, bindings gone
|
||||||
|
- name: idem remove http binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: http_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ http_vars.protocol }}"
|
||||||
|
ip: "{{ http_vars.ip }}"
|
||||||
|
port: "{{ http_vars.port }}"
|
||||||
|
register: get_http_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: idem remove http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: http_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ http_header_vars.header }}"
|
||||||
|
protocol: "{{ http_header_vars.protocol }}"
|
||||||
|
ip: "{{ http_header_vars.ip }}"
|
||||||
|
port: "{{ http_header_vars.port }}"
|
||||||
|
register: get_http_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: idem remove assert changed and gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_no_header is not changed
|
||||||
|
- http_no_header.binding_info is not defined
|
||||||
|
- get_http_no_header.binding is not defined
|
||||||
|
- http_header is not changed
|
||||||
|
- http_header.binding_info is not defined
|
||||||
|
- get_http_header.binding is not defined
|
||||||
|
|
||||||
|
#bulk remove cm
|
||||||
|
#add multiple bindings - verify they're present
|
||||||
|
- name: bulk add http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ item }}"
|
||||||
|
protocol: http
|
||||||
|
ip: '*'
|
||||||
|
port: 80
|
||||||
|
register: http_header
|
||||||
|
with_items:
|
||||||
|
- test1.com
|
||||||
|
- test2.com
|
||||||
|
- test3.com
|
||||||
|
|
||||||
|
- name: assert that 3 bindings were added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_header is changed
|
||||||
|
- http_header | json_query('results[*].binding_info') | length == 3
|
||||||
|
|
||||||
|
#cm remove with host_header: '*' - verify changed true and that bulk remove tries to get them all
|
||||||
|
#remove with host_header: '*'
|
||||||
|
|
||||||
|
- name: bulk remove http binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: '*'
|
||||||
|
protocol: http
|
||||||
|
ip: '*'
|
||||||
|
port: 80
|
||||||
|
register: http_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ item }}"
|
||||||
|
protocol: http
|
||||||
|
ip: '*'
|
||||||
|
port: 80
|
||||||
|
register: get_http_header
|
||||||
|
changed_when: false
|
||||||
|
with_items:
|
||||||
|
- test1.com
|
||||||
|
- test2.com
|
||||||
|
- test3.com
|
||||||
|
|
||||||
|
- name: bulk remove assert that bindings are gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- http_header is changed
|
||||||
|
- http_header.binding_info | length == 3
|
|
@ -0,0 +1,459 @@
|
||||||
|
##############
|
||||||
|
### CM Add ###
|
||||||
|
##############
|
||||||
|
#changed true, check nothing present
|
||||||
|
- name: CM add https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: CM get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM add https binding with header and SNI
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
ssl_flags: 1
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: CM get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM assert changed, but not added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'added'
|
||||||
|
- https_no_header.binding_info is none
|
||||||
|
- get_https_no_header.binding is not defined
|
||||||
|
- https_header is changed
|
||||||
|
- https_header.operation_type == 'added'
|
||||||
|
- https_header.binding_info is none
|
||||||
|
- get_https_header.binding is not defined
|
||||||
|
|
||||||
|
###########
|
||||||
|
### Add ###
|
||||||
|
###########
|
||||||
|
#changed true, new bindings present
|
||||||
|
- name: add https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: add https binding with header SNI
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
ssl_flags: 1
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: assert changed and added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'added'
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.hostheader == ''
|
||||||
|
- https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- https_header is changed
|
||||||
|
- https_header.operation_type == 'added'
|
||||||
|
- https_header.binding_info is defined
|
||||||
|
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- https_header.binding_info.port == {{ https_header_vars.port }}
|
||||||
|
- https_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- https_header.binding_info.sslFlags == 1
|
||||||
|
|
||||||
|
################
|
||||||
|
### Idem Add ###
|
||||||
|
################
|
||||||
|
#changed false
|
||||||
|
- name: idem add https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: https
|
||||||
|
ip: '*'
|
||||||
|
port: 443
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: idem add https binding with header and SNI
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: test.com
|
||||||
|
protocol: https
|
||||||
|
ip: '*'
|
||||||
|
port: 443
|
||||||
|
ssl_flags: 1
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: idem assert not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is not changed
|
||||||
|
- https_header is not changed
|
||||||
|
|
||||||
|
#################
|
||||||
|
### CM Modify ###
|
||||||
|
#################
|
||||||
|
# changed true, verify no changes occurred
|
||||||
|
|
||||||
|
#modify sni
|
||||||
|
- name: CM modify https binding with header, change cert
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
ssl_flags: 1
|
||||||
|
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM assert changed but old cert
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_header is changed
|
||||||
|
- https_header.operation_type == 'updated'
|
||||||
|
- https_header.binding_info is defined
|
||||||
|
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- https_header.binding_info.port == {{ https_header_vars.port }}
|
||||||
|
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- https_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- https_header.binding_info.sslFlags == 1
|
||||||
|
- get_https_header.binding is defined
|
||||||
|
- get_https_header.binding.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- get_https_header.binding.port == {{ https_header_vars.port }}
|
||||||
|
- get_https_header.binding.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- get_https_header.binding.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- get_https_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- get_https_header.binding.sslFlags == 1
|
||||||
|
|
||||||
|
##############
|
||||||
|
### Modify ###
|
||||||
|
##############
|
||||||
|
# modify ssl flags
|
||||||
|
- name: modify https binding with header, change cert
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
ssl_flags: 1
|
||||||
|
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: modify assert changed and new cert
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_header is changed
|
||||||
|
- https_header.operation_type == 'updated'
|
||||||
|
- https_header.binding_info is defined
|
||||||
|
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- https_header.binding_info.port == {{ https_header_vars.port }}
|
||||||
|
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- https_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
- https_header.binding_info.sslFlags == 1
|
||||||
|
- get_https_header.binding is defined
|
||||||
|
- get_https_header.binding.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- get_https_header.binding.port == {{ https_header_vars.port }}
|
||||||
|
- get_https_header.binding.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- get_https_header.binding.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- get_https_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
- get_https_header.binding.sslFlags == 1
|
||||||
|
|
||||||
|
###################
|
||||||
|
### Idem Modify ###
|
||||||
|
###################
|
||||||
|
#changed false
|
||||||
|
|
||||||
|
#idem modify ssl flags
|
||||||
|
- name: idem modify https binding with header, enable SNI and change cert
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
ssl_flags: 1
|
||||||
|
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: idem assert not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_header is not changed
|
||||||
|
|
||||||
|
#################
|
||||||
|
### CM Remove ###
|
||||||
|
#################
|
||||||
|
#changed true, bindings still present
|
||||||
|
- name: cm remove https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: https_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: cm remove https binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: https_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: cm remove assert changed, but still present
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'removed'
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding is defined
|
||||||
|
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
|
||||||
|
- get_https_no_header.binding.port == {{ https_vars.port }}
|
||||||
|
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- https_header is changed
|
||||||
|
- https_header.binding_info is defined
|
||||||
|
- https_header.operation_type == 'removed'
|
||||||
|
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- https_header.binding_info.port == {{ https_header_vars.port }}
|
||||||
|
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- get_https_header.binding is defined
|
||||||
|
- get_https_header.binding.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- get_https_header.binding.port == {{ https_header_vars.port }}
|
||||||
|
- get_https_header.binding.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- get_https_header.binding.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- get_https_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
##############
|
||||||
|
### remove ###
|
||||||
|
##############
|
||||||
|
#changed true, bindings gone
|
||||||
|
- name: remove https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: remove https binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: remove assert changed and gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.operation_type == 'removed'
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding is not defined
|
||||||
|
- https_header is changed
|
||||||
|
- https_header.binding_info is defined
|
||||||
|
- https_header.operation_type == 'removed'
|
||||||
|
- https_header.binding_info.ip == "{{ https_header_vars.ip }}"
|
||||||
|
- https_header.binding_info.port == {{ https_header_vars.port }}
|
||||||
|
- https_header.binding_info.protocol == "{{ https_header_vars.protocol }}"
|
||||||
|
- https_header.binding_info.hostheader == "{{ https_header_vars.header }}"
|
||||||
|
- get_https_header.binding is not defined
|
||||||
|
|
||||||
|
###################
|
||||||
|
### remove idem ###
|
||||||
|
###################
|
||||||
|
#change false, bindings gone
|
||||||
|
- name: idem remove https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: idem remove https binding with header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
host_header: "{{ https_header_vars.header }}"
|
||||||
|
protocol: "{{ https_header_vars.protocol }}"
|
||||||
|
ip: "{{ https_header_vars.ip }}"
|
||||||
|
port: "{{ https_header_vars.port }}"
|
||||||
|
register: get_https_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: idem remove assert changed and gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is not changed
|
||||||
|
- https_no_header.binding_info is not defined
|
||||||
|
- get_https_no_header.binding is not defined
|
||||||
|
- https_header is not changed
|
||||||
|
- https_header.binding_info is not defined
|
||||||
|
- get_https_header.binding is not defined
|
|
@ -0,0 +1,423 @@
|
||||||
|
##############
|
||||||
|
### CM Add ###
|
||||||
|
##############
|
||||||
|
#changed true, check nothing present
|
||||||
|
- name: CM add https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: CM get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM assert changed, but not added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'added'
|
||||||
|
- https_no_header.binding_info is none
|
||||||
|
- get_https_no_header.binding is not defined
|
||||||
|
|
||||||
|
###########
|
||||||
|
### Add ###
|
||||||
|
###########
|
||||||
|
#changed true, new bindings present
|
||||||
|
- name: add https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: assert changed and added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.operation_type == 'added'
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- https_no_header.binding_info.hostheader == ''
|
||||||
|
- https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
################
|
||||||
|
### Idem Add ###
|
||||||
|
################
|
||||||
|
#changed false
|
||||||
|
- name: idem add https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: idem assert not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is not changed
|
||||||
|
|
||||||
|
#################
|
||||||
|
### CM Modify ###
|
||||||
|
#################
|
||||||
|
# changed true, verify no changes occurred
|
||||||
|
|
||||||
|
#modify sni
|
||||||
|
- name: CM modify https binding change cert
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: CM assert changed but old cert
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'updated'
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- https_no_header.binding_info.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- get_https_no_header.binding is defined
|
||||||
|
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
|
||||||
|
- get_https_no_header.binding.port == {{ https_vars.port }}
|
||||||
|
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding.certificateHash == "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
##############
|
||||||
|
### Modify ###
|
||||||
|
##############
|
||||||
|
# modify ssl flags
|
||||||
|
- name: modify https binding, change cert
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: get binding info header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: modify assert changed and new cert
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'updated'
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- https_no_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
- get_https_no_header.binding is defined
|
||||||
|
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
|
||||||
|
- get_https_no_header.binding.port == {{ https_vars.port }}
|
||||||
|
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding.hostheader == ''
|
||||||
|
- get_https_no_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
###################
|
||||||
|
### Idem Modify ###
|
||||||
|
###################
|
||||||
|
#changed false
|
||||||
|
|
||||||
|
#idem modify ssl flags
|
||||||
|
- name: idem modify https binding and change cert
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: present
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
certificate_hash: "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
register: https_header
|
||||||
|
|
||||||
|
- name: idem assert not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_header is not changed
|
||||||
|
|
||||||
|
#################
|
||||||
|
### CM Remove ###
|
||||||
|
#################
|
||||||
|
#changed true, bindings still present
|
||||||
|
- name: cm remove https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: https_no_header
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: cm remove assert changed, but still present
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'removed'
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- https_no_header.binding_info.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
- get_https_no_header.binding is defined
|
||||||
|
- get_https_no_header.binding.ip == "{{ https_vars.ip }}"
|
||||||
|
- get_https_no_header.binding.port == {{ https_vars.port }}
|
||||||
|
- get_https_no_header.binding.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding.certificateHash == "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
##############
|
||||||
|
### remove ###
|
||||||
|
##############
|
||||||
|
#changed true, bindings gone
|
||||||
|
- name: remove https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: remove assert changed and gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is changed
|
||||||
|
- https_no_header.operation_type == 'removed'
|
||||||
|
- https_no_header.binding_info is defined
|
||||||
|
- https_no_header.binding_info.ip == "{{ https_vars.ip }}"
|
||||||
|
- https_no_header.binding_info.port == {{ https_vars.port }}
|
||||||
|
- https_no_header.binding_info.protocol == "{{ https_vars.protocol }}"
|
||||||
|
- get_https_no_header.binding is not defined
|
||||||
|
|
||||||
|
###################
|
||||||
|
### remove idem ###
|
||||||
|
###################
|
||||||
|
#change false, bindings gone
|
||||||
|
- name: idem remove https binding no header
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: https_no_header
|
||||||
|
|
||||||
|
- name: get binding info no header
|
||||||
|
test_get_webbindings:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
protocol: "{{ https_vars.protocol }}"
|
||||||
|
ip: "{{ https_vars.ip }}"
|
||||||
|
port: "{{ https_vars.port }}"
|
||||||
|
register: get_https_no_header
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: idem remove assert changed and gone
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- https_no_header is not changed
|
||||||
|
- https_no_header.binding_info is not defined
|
||||||
|
- get_https_no_header.binding is not defined
|
||||||
|
|
||||||
|
|
||||||
|
##################
|
||||||
|
### WC Testing ###
|
||||||
|
##################
|
||||||
|
|
||||||
|
# Unfortunately this does not work due to some strange errors
|
||||||
|
# that are caused when using a self signed wildcard cert.
|
||||||
|
# I'm leaving this here in case someone finds a solution in the
|
||||||
|
# future.
|
||||||
|
|
||||||
|
# - name: add https binding wildcard with header
|
||||||
|
# win_iis_webbinding:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# state: present
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# certificate_hash: "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
# register: https_header
|
||||||
|
|
||||||
|
# - name: assert changed and added
|
||||||
|
# assert:
|
||||||
|
# that:
|
||||||
|
# - https_header is changed
|
||||||
|
# - https_header.added is defined
|
||||||
|
# - https_header.added.ip == "{{ https_wc_vars.ip }}"
|
||||||
|
# - https_header.added.port == {{ https_wc_vars.port }}
|
||||||
|
# - https_header.added.protocol == "{{ https_wc_vars.protocol }}"
|
||||||
|
# - https_header.added.hostheader == "{{ https_wc_vars.header }}"
|
||||||
|
# - https_header.added.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
|
||||||
|
# - name: idem add https binding wildcard with header
|
||||||
|
# win_iis_webbinding:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# state: present
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# certificate_hash: "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
# register: https_header
|
||||||
|
|
||||||
|
|
||||||
|
# - name: cm remove wildcard https binding
|
||||||
|
# win_iis_webbinding:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# state: absent
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# register: https_header
|
||||||
|
# check_mode: yes
|
||||||
|
|
||||||
|
# - name: get binding info header
|
||||||
|
# test_get_webbindings:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# register: get_https_header
|
||||||
|
# changed_when: false
|
||||||
|
|
||||||
|
# - name: cm remove assert changed, but still present
|
||||||
|
# assert:
|
||||||
|
# that:
|
||||||
|
# - https_header is changed
|
||||||
|
# - https_header.removed is defined
|
||||||
|
# - https_header.removed.ip == "{{ https_wc_vars.ip }}"
|
||||||
|
# - https_header.removed.port == {{ https_wc_vars.port }}
|
||||||
|
# - https_header.removed.protocol == "{{ https_wc_vars.protocol }}"
|
||||||
|
# - https_header.removed.hostheader == "{{ https_wc_vars.header }}"
|
||||||
|
# - https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
# - get_https_header.binding is defined
|
||||||
|
# - get_https_header.removed.ip == "{{ https_wc_vars.ip }}"
|
||||||
|
# - get_https_header.removed.port == {{ https_wc_vars.port }}
|
||||||
|
# - get_https_header.removed.protocol == "{{ https_wc_vars.protocol }}"
|
||||||
|
# - get_https_header.removed.hostheader == "{{ https_wc_vars.header }}"
|
||||||
|
# - get_https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
# - name: remove wildcard https binding
|
||||||
|
# win_iis_webbinding:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# state: absent
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# register: https_header
|
||||||
|
|
||||||
|
# - name: get binding info header
|
||||||
|
# test_get_webbindings:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# register: get_https_header
|
||||||
|
# changed_when: false
|
||||||
|
|
||||||
|
|
||||||
|
# - name: remove assert changed and gone
|
||||||
|
# assert:
|
||||||
|
# that:
|
||||||
|
# - https_header is changed
|
||||||
|
# - https_header.removed is defined
|
||||||
|
# - https_header.removed.ip == "{{ https_wc_vars.ip }}"
|
||||||
|
# - https_header.removed.port == {{ https_wc_vars.port }}
|
||||||
|
# - https_header.removed.protocol == "{{ https_wc_vars.protocol }}"
|
||||||
|
# - https_header.removed.hostheader == "{{ https_wc_vars.header }}"
|
||||||
|
# - https_header.removed.certificateHash == "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
# - get_https_header.binding is not defined
|
||||||
|
|
||||||
|
# - name: idem remove wildcard https binding
|
||||||
|
# win_iis_webbinding:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# state: absent
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# register: https_header
|
||||||
|
|
||||||
|
# - name: get binding info header
|
||||||
|
# test_get_webbindings:
|
||||||
|
# name: "{{ test_iis_site_name }}"
|
||||||
|
# host_header: "{{ https_wc_vars.header }}"
|
||||||
|
# protocol: "{{ https_wc_vars.protocol }}"
|
||||||
|
# ip: "{{ https_wc_vars.ip }}"
|
||||||
|
# port: "{{ https_wc_vars.port }}"
|
||||||
|
# register: get_https_header
|
||||||
|
# changed_when: false
|
||||||
|
|
||||||
|
# - name: idem remove assert changed and gone
|
||||||
|
# assert:
|
||||||
|
# that:
|
||||||
|
# - https_header is not changed
|
||||||
|
# - https_header.removed is not defined
|
||||||
|
# - get_https_header.binding is not defined
|
62
test/integration/targets/win_iis_webbinding/tasks/main.yml
Normal file
62
test/integration/targets/win_iis_webbinding/tasks/main.yml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
---
|
||||||
|
# Cannot use win_feature to install IIS on Server 2008.
|
||||||
|
# Run a brief check and skip hosts that don't support
|
||||||
|
# that operation
|
||||||
|
#seems "raw" is the only module that works on 2008 non-r2. win_command and win_shell both failed
|
||||||
|
- name: register os version (seems integration tests don't gather this fact)
|
||||||
|
raw: powershell.exe "gwmi Win32_OperatingSystem | select -expand version"
|
||||||
|
register: os_version
|
||||||
|
changed_when: False
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- include_tasks: setup.yml
|
||||||
|
- include_tasks: http.yml
|
||||||
|
- include_tasks: https-lt6.2.yml
|
||||||
|
when: os_version.stdout_lines[0] | version_compare('6.2','lt')
|
||||||
|
- include_tasks: https-ge6.2.yml
|
||||||
|
when: os_version.stdout_lines[0] | version_compare('6.2','ge')
|
||||||
|
- include_tasks: failures.yml
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: get all websites from server
|
||||||
|
raw: powershell.exe "(get-website).name"
|
||||||
|
register: existing_sites
|
||||||
|
|
||||||
|
- name: ensure all sites are removed for clean testing
|
||||||
|
win_iis_website:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "{{ existing_sites.stdout_lines }}"
|
||||||
|
|
||||||
|
- name: cleanup certreq files
|
||||||
|
win_file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- c:\windows\temp\certreq1.txt
|
||||||
|
- c:\windows\temp\certreq2.txt
|
||||||
|
- c:\windows\temp\certreqwc.txt
|
||||||
|
- c:\windows\temp\certreqresp1.txt
|
||||||
|
- c:\windows\temp\certreqresp2.txt
|
||||||
|
- c:\windows\temp\certreqrespwc.txt
|
||||||
|
|
||||||
|
- name: remove certs
|
||||||
|
raw: 'remove-item cert:\localmachine\my\{{ item }} -force -ea silentlycontinue'
|
||||||
|
with_items:
|
||||||
|
- "{{ thumbprint1.stdout_lines[0] }}"
|
||||||
|
- "{{ thumbprint2.stdout_lines[0] }}"
|
||||||
|
- "{{ thumbprint_wc.stdout_lines[0] }}"
|
||||||
|
|
||||||
|
- name: remove IIS features after test
|
||||||
|
win_feature:
|
||||||
|
name: Web-Server
|
||||||
|
state: absent
|
||||||
|
includ_sub_features: True
|
||||||
|
include_management_tools: True
|
||||||
|
register: feature_uninstall
|
||||||
|
|
||||||
|
- name: reboot after feature install
|
||||||
|
win_reboot:
|
||||||
|
when: feature_uninstall.reboot_required
|
||||||
|
when: os_version.stdout_lines[0] | version_compare('6.1','gt')
|
88
test/integration/targets/win_iis_webbinding/tasks/setup.yml
Normal file
88
test/integration/targets/win_iis_webbinding/tasks/setup.yml
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
- name: reboot before feature install to ensure server is in clean state
|
||||||
|
win_reboot:
|
||||||
|
|
||||||
|
- name: ensure IIS features are installed
|
||||||
|
win_feature:
|
||||||
|
name: Web-Server
|
||||||
|
state: present
|
||||||
|
includ_sub_features: True
|
||||||
|
include_management_tools: True
|
||||||
|
register: feature_install
|
||||||
|
|
||||||
|
- name: reboot after feature install
|
||||||
|
win_reboot:
|
||||||
|
when: feature_install.reboot_required
|
||||||
|
|
||||||
|
- name: get all websites from server
|
||||||
|
raw: powershell.exe "(get-website).name"
|
||||||
|
register: existing_sites
|
||||||
|
|
||||||
|
- name: ensure all sites are removed for clean testing
|
||||||
|
win_iis_website:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "{{ existing_sites.stdout_lines }}"
|
||||||
|
|
||||||
|
- name: add testing site {{ test_iis_site_name }}
|
||||||
|
win_iis_website:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
physical_path: c:\inetpub\wwwroot
|
||||||
|
|
||||||
|
- name: ensure all bindings are removed prior to starting testing
|
||||||
|
win_iis_webbinding:
|
||||||
|
name: "{{ test_iis_site_name }}"
|
||||||
|
state: absent
|
||||||
|
protocol: "{{ item.protocol }}"
|
||||||
|
port: "{{ item.port }}"
|
||||||
|
host_header: '*'
|
||||||
|
with_items:
|
||||||
|
- {protocol: http, port: 80}
|
||||||
|
- {protocol: https, port: 443}
|
||||||
|
|
||||||
|
- name: copy certreq file
|
||||||
|
win_copy:
|
||||||
|
content: |-
|
||||||
|
[NewRequest]
|
||||||
|
Subject = "CN={{ item.name }}"
|
||||||
|
KeyLength = 2048
|
||||||
|
KeyAlgorithm = RSA
|
||||||
|
MachineKeySet = true
|
||||||
|
RequestType = Cert
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
with_items:
|
||||||
|
- {name: test.com, dest: 'c:\windows\temp\certreq1.txt'}
|
||||||
|
- {name: test1.com, dest: 'c:\windows\temp\certreq2.txt'}
|
||||||
|
- {name: '*.test.com', dest: 'c:\windows\temp\certreqwc.txt'}
|
||||||
|
|
||||||
|
- name: make sure response files are absent
|
||||||
|
win_file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- 'c:\windows\temp\certreqresp1.txt'
|
||||||
|
- 'c:\windows\temp\certreqresp2.txt'
|
||||||
|
- 'c:\windows\temp\certreqrespwc.txt'
|
||||||
|
|
||||||
|
- name: create self signed cert from certreq
|
||||||
|
win_command: certreq -new -machine {{ item.req }} {{ item.resp }}
|
||||||
|
with_items:
|
||||||
|
- {req: 'c:\windows\temp\certreq1.txt', resp: 'c:\windows\temp\certreqresp1.txt'}
|
||||||
|
- {req: 'c:\windows\temp\certreq2.txt', resp: 'c:\windows\temp\certreqresp2.txt'}
|
||||||
|
- {req: 'c:\windows\temp\certreqwc.txt', resp: 'c:\windows\temp\certreqrespwc.txt'}
|
||||||
|
|
||||||
|
- name: register certificate thumbprint1
|
||||||
|
raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=test.com"})[0].Thumbprint'
|
||||||
|
register: thumbprint1
|
||||||
|
|
||||||
|
- name: register certificate thumbprint2
|
||||||
|
raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=test1.com"})[0].Thumbprint'
|
||||||
|
register: thumbprint2
|
||||||
|
|
||||||
|
- name: register certificate thumbprint_wc
|
||||||
|
raw: '(gci Cert:\LocalMachine\my | ? {$_.subject -eq "CN=*.test.com"})[0].Thumbprint'
|
||||||
|
register: thumbprint_wc
|
||||||
|
|
||||||
|
- debug: var=thumbprint1.stdout
|
||||||
|
- debug: var=thumbprint2.stdout
|
||||||
|
- debug: var=thumbprint_wc.stdout
|
Loading…
Reference in a new issue