mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-08 14:22:46 +00:00
win_iis_webbinding: Fix bug with ipaddress * returning multiple bindings (#34721)
* win_iis_webbinding: Fix bug with ipaddress * returning multiple bindings instead of only the ones defined as *. Address possible future issues around hostheader * by just disallowing it. Resolves 25473. Added new test for this case. Removed all validation for https binding collisions due to difficulty in validating all cases in which they could or could not collide. As a result, also removed return values relating to certificate data. Updated testing and docs appropriately * win_iis_webbinding: added break to remove binding loops
This commit is contained in:
@@ -4,24 +4,18 @@
|
||||
# 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
|
||||
@@ -50,48 +44,41 @@ function Create-BindingInfo {
|
||||
# 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
|
||||
|
||||
Try {
|
||||
$site_bindings = get-webbinding -name $args[0].name
|
||||
}
|
||||
Catch {
|
||||
# 2k8r2 throws this error when you run get-webbinding with no bindings in iis
|
||||
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 { return }
|
||||
}
|
||||
|
||||
# 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'])
|
||||
Foreach ($binding in $site_bindings)
|
||||
{
|
||||
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
|
||||
}
|
||||
$splits = $binding.bindingInformation -split ':'
|
||||
|
||||
if (
|
||||
$args[0].protocol -eq $binding.protocol -and
|
||||
$args[0].ipaddress -eq $splits[0] -and
|
||||
$args[0].port -eq $splits[1] -and
|
||||
$args[0].hostheader -eq $splits[2]
|
||||
)
|
||||
{
|
||||
Return $binding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# create binding search splat
|
||||
$binding_parameters = @{
|
||||
Name = $name
|
||||
Protocol = $protocol
|
||||
Port = $port
|
||||
IPAddress = $ip
|
||||
Name = $name
|
||||
Protocol = $protocol
|
||||
Port = $port
|
||||
IPAddress = $ip
|
||||
}
|
||||
|
||||
# insert host header to search if specified, otherwise it will return * (all bindings matching protocol/ip)
|
||||
@@ -99,6 +86,10 @@ If ($host_header)
|
||||
{
|
||||
$binding_parameters.HostHeader = $host_header
|
||||
}
|
||||
Else
|
||||
{
|
||||
$binding_parameters.HostHeader = [string]::Empty
|
||||
}
|
||||
|
||||
# Get bindings matching parameters
|
||||
Try {
|
||||
@@ -119,4 +110,4 @@ If ($current_bindings)
|
||||
|
||||
$result.binding = $binding_info
|
||||
}
|
||||
exit-json -obj $result
|
||||
exit-json -obj $result
|
||||
@@ -1,17 +1,12 @@
|
||||
- name: failure check bind with host header but no wc or sni
|
||||
- name: failure check define * for host header
|
||||
win_iis_webbinding:
|
||||
name: "{{ test_iis_site_name }}"
|
||||
state: present
|
||||
host_header: test.com
|
||||
protocol: https
|
||||
host_header: '*'
|
||||
protocol: http
|
||||
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."
|
||||
failed_when: failure.msg != "To make or remove a catch-all binding, please omit the host_header parameter entirely rather than specify host_header *"
|
||||
|
||||
- debug:
|
||||
var: failure
|
||||
@@ -29,46 +24,47 @@
|
||||
with_items:
|
||||
- "{{ existing_sites.stdout_lines }}"
|
||||
|
||||
- name: add sites
|
||||
- name: add testremove site
|
||||
win_iis_website:
|
||||
name: "{{ item.name }}"
|
||||
name: testremove
|
||||
state: started
|
||||
ip: 127.0.0.1
|
||||
port: "{{ item.port }}"
|
||||
physical_path: c:\inetpub\wwwroot
|
||||
|
||||
- name: add bindings to testremove
|
||||
win_iis_webbinding:
|
||||
name: testremove
|
||||
ip: "{{ item.ip }}"
|
||||
port: "{{ item.port }}"
|
||||
with_items:
|
||||
- {name: testconflict1, port: 8080}
|
||||
- {name: testconflict2, port: 8081}
|
||||
- {ip: 127.0.0.1, port: 80}
|
||||
- {ip: '*', port: 80}
|
||||
|
||||
- name: add https binding to testconflict1
|
||||
- name: remove ip * binding from testremove
|
||||
win_iis_webbinding:
|
||||
name: testconflict1
|
||||
state: present
|
||||
protocol: https
|
||||
port: 443
|
||||
ip: 127.0.0.1
|
||||
certificate_hash: "{{ thumbprint1.stdout_lines[0] }}"
|
||||
name: testremove
|
||||
state: absent
|
||||
port: 80
|
||||
ip: '*'
|
||||
|
||||
- name: add https binding to testconflict2 (expect failure)
|
||||
win_iis_webbinding:
|
||||
name: testconflict2
|
||||
state: present
|
||||
protocol: https
|
||||
- name: get the remaining binding from testremove
|
||||
test_get_webbindings:
|
||||
name: testremove
|
||||
port: 80
|
||||
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'
|
||||
register: test_result
|
||||
|
||||
- debug:
|
||||
var: failure
|
||||
var: test_result
|
||||
verbosity: 1
|
||||
|
||||
- name: assert that remove *:80 doesn't also remove 127.0.0.1:80
|
||||
assert:
|
||||
that:
|
||||
- test_result.binding.ip == '127.0.0.1'
|
||||
- test_result.binding.port == 80
|
||||
|
||||
always:
|
||||
- name: remove websites
|
||||
win_iis_website:
|
||||
name: "{{ item }}"
|
||||
name: testremove
|
||||
state: absent
|
||||
with_items:
|
||||
- testconflict1
|
||||
- testconflict2
|
||||
|
||||
@@ -315,58 +315,3 @@
|
||||
- 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
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
state: absent
|
||||
protocol: "{{ item.protocol }}"
|
||||
port: "{{ item.port }}"
|
||||
host_header: '*'
|
||||
with_items:
|
||||
- {protocol: http, port: 80}
|
||||
- {protocol: https, port: 443}
|
||||
@@ -83,6 +82,12 @@
|
||||
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
|
||||
- debug:
|
||||
var: thumbprint1.stdout
|
||||
verbosity: 1
|
||||
- debug:
|
||||
var: thumbprint2.stdout
|
||||
verbosity: 1
|
||||
- debug:
|
||||
var: thumbprint_wc.stdout
|
||||
verbosity: 1
|
||||
|
||||
Reference in New Issue
Block a user