Skip to content

Commit

Permalink
Migrate win_iis_webapplication module to new microsoft.iis repository
Browse files Browse the repository at this point in the history
  • Loading branch information
ronger4 committed Dec 25, 2024
1 parent 7035882 commit bc56e7b
Show file tree
Hide file tree
Showing 7 changed files with 422 additions and 0 deletions.
140 changes: 140 additions & 0 deletions plugins/modules/web_application.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#!powershell

# Copyright: (c) 2015, Henrik Wallström <[email protected]>
# 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 $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false

$name = Get-AnsibleParam -obj $params -name "name" -type "str" -failifempty $true
$site = Get-AnsibleParam -obj $params -name "site" -type "str" -failifempty $true
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent", "present"
$physical_path = Get-AnsibleParam -obj $params -name "physical_path" -type "str" -aliases "path"
$application_pool = Get-AnsibleParam -obj $params -name "application_pool" -type "str"
$connect_as = Get-AnsibleParam -obj $params -name 'connect_as' -type 'str' -validateset 'specific_user', 'pass_through'
$username = Get-AnsibleParam -obj $params -name "username" -type "str" -failifempty ($connect_as -eq 'specific_user')
$password = Get-AnsibleParam -obj $params -name "password" -type "str" -failifempty ($connect_as -eq 'specific_user')

$result = @{
application_pool = $application_pool
changed = $false
physical_path = $physical_path
}

# Ensure WebAdministration module is loaded
if ($null -eq (Get-Module "WebAdministration" -ErrorAction SilentlyContinue)) {
Import-Module WebAdministration
}

# Application info
$application = Get-WebApplication -Site $site -Name $name
$website = Get-Website -Name $site

# Set ApplicationPool to current if not specified
if (!$application_pool) {
$application_pool = $website.applicationPool
}

try {
# Add application
if (($state -eq 'present') -and (-not $application)) {
if (-not $physical_path) {
Fail-Json $result "missing required arguments: path"
}
if (-not (Test-Path -LiteralPath $physical_path)) {
Fail-Json $result "specified folder must already exist: path"
}

$application_parameters = @{
Name = $name
PhysicalPath = $physical_path
Site = $site
}

if ($application_pool) {
$application_parameters.ApplicationPool = $application_pool
}

if (-not $check_mode) {
$application = New-WebApplication @application_parameters -Force
}
$result.changed = $true
}

# Remove application
if ($state -eq 'absent' -and $application) {
$application = Remove-WebApplication -Site $site -Name $name -WhatIf:$check_mode
$result.changed = $true
}

$application = Get-WebApplication -Site $site -Name $name
if ($application) {

# Change Physical Path if needed
if ($physical_path) {
if (-not (Test-Path -LiteralPath $physical_path)) {
Fail-Json $result "specified folder must already exist: path"
}

$folder = Get-Item -LiteralPath $physical_path
if ($folder.FullName -ne $application.PhysicalPath) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -name physicalPath -value $physical_path -WhatIf:$check_mode
$result.changed = $true
}
}

# Change Application Pool if needed
if ($application_pool) {
if ($application_pool -ne $application.applicationPool) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -name applicationPool -value $application_pool -WhatIf:$check_mode
$result.changed = $true
}
}

# Change username and password if needed
$app_user = Get-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName'
$app_pass = Get-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'password'
if ($connect_as -eq 'pass_through') {
if ($app_user -ne '') {
Clear-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName' -WhatIf:$check_mode
$result.changed = $true
}
if ($app_pass -ne '') {
Clear-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'password' -WhatIf:$check_mode
$result.changed = $true
}
}
elseif ($connect_as -eq 'specific_user') {
if ($app_user -ne $username) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName' -Value $username -WhatIf:$check_mode
$result.changed = $true
}
if ($app_pass -ne $password) {
Set-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'password' -Value $password -WhatIf:$check_mode
$result.changed = $true
}
}
}
}
catch {
Fail-Json $result $_.Exception.Message
}

# When in check-mode or on removal, this may fail
$application = Get-WebApplication -Site $site -Name $name
if ($application) {
$app_user = Get-ItemProperty -LiteralPath "IIS:\Sites\$($site)\$($name)" -Name 'userName'
if ($app_user -eq '') {
$result.connect_as = 'pass_through'
}
else {
$result.connect_as = 'specific_user'
}

$result.physical_path = $application.PhysicalPath
$result.application_pool = $application.ApplicationPool
}

Exit-Json $result
91 changes: 91 additions & 0 deletions plugins/modules/web_application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright: (c) 2015, Henrik Wallström <[email protected]>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

DOCUMENTATION = r'''
---
module: web_application
short_description: Configures IIS web applications
description:
- Creates, removes, and configures IIS web applications.
options:
name:
description:
- Name of the web application.
type: str
required: yes
site:
description:
- Name of the site on which the application is created.
type: str
required: yes
state:
description:
- State of the web application.
type: str
choices: [ absent, present ]
default: present
physical_path:
description:
- The physical path on the remote host to use for the new application.
- The specified folder must already exist.
type: str
application_pool:
description:
- The application pool in which the new site executes.
- If not specified, the application pool of the current website will be used.
type: str
connect_as:
description:
- The type of authentication to use for this application. Either C(pass_through) or C(specific_user)
- If C(pass_through), IIS will use the identity of the user or application pool identity to access the file system or network.
- If C(specific_user), IIS will use the credentials provided in I(username) and I(password) to access the file system or network.
type: str
choices: [pass_through, specific_user]
username:
description:
- Specifies the user name of an account that can access configuration files and content for this application.
- Required when I(connect_as) is set to C(specific_user).
type: str
password:
description:
- The password associated with I(username).
- Required when I(connect_as) is set to C(specific_user).
type: str
seealso:
- module: community.windows.win_iis_virtualdirectory
- module: community.windows.win_iis_webapppool
- module: community.windows.win_iis_webbinding
- module: community.windows.win_iis_website
author:
- Henrik Wallström (@henrikwallstrom)
'''

EXAMPLES = r'''
- name: Add ACME webapplication on IIS.
microsoft.iis.web_application:
name: api
site: acme
state: present
physical_path: C:\apps\acme\api
'''

RETURN = r'''
application_pool:
description: The used/implemented application_pool value.
returned: success
type: str
sample: DefaultAppPool
physical_path:
description: The used/implemented physical_path value.
returned: success
type: str
sample: C:\apps\acme\api
connect_as:
description: How IIS will try to authenticate to the physical_path.
returned: when the application exists
type: str
sample: specific_user
'''
3 changes: 3 additions & 0 deletions tests/integration/targets/web_application/aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
windows
shippable/windows/group4
# unstable - Random IIS configuration errors
10 changes: 10 additions & 0 deletions tests/integration/targets/web_application/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
test_app_name: TestApp

test_site_name: 'Test Site'

test_user: testuser
test_password: testpass

test_physical_path: "{{ remote_tmp_dir }}"
test_apppool: 'testapppool'
3 changes: 3 additions & 0 deletions tests/integration/targets/web_application/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
dependencies:
- setup_remote_tmp_dir
84 changes: 84 additions & 0 deletions tests/integration/targets/web_application/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
- name: check if we can run the tests
ansible.windows.win_shell: |
$osVersion = [Version](Get-Item -LiteralPath "$env:SystemRoot\System32\kernel32.dll").VersionInfo.ProductVersion
$osVersion -ge [Version]"6.2"
register: run_test
changed_when: False

- name: Run on Server 2012 and higher
when: run_test.stdout | trim | bool
block:
- name: ensure IIS features are installed
ansible.windows.win_feature:
name: Web-Server
state: present
include_management_tools: True
register: feature_install

- name: reboot after feature install
ansible.windows.win_reboot:
when: feature_install.reboot_required

# may be possible that copy corrupts the file
- name: Get iis configuration checksum
ansible.windows.win_stat:
path: C:\Windows\System32\inetsrv\config\applicationHost.config
checksum_algorithm: sha1
register: stat_result

- name: take a copy of the original iis configuration
ansible.windows.win_copy:
src: C:\Windows\System32\inetsrv\config\applicationHost.config
dest: '{{ remote_tmp_dir }}\applicationHost.config'
remote_src: yes
register: copy_result

- assert:
that:
- "stat_result.stat.checksum == copy_result.checksum"

# Tests
- name: run tests on hosts that support it
include_tasks: tests.yml

always:
# Cleanup
- name: remove test application
web_application:
state: absent
site: "{{ test_site_name }}"
name: "{{ test_app_name }}"

- name: remove test application pool
community.windows.win_iis_webapppool:
name: "{{ test_apppool }}"
state: absent

- name: remove test site
win_iis_website:
name: "{{ test_site_name }}"
state: absent

- name: restore iis configuration
ansible.windows.win_copy:
src: '{{ remote_tmp_dir }}\applicationHost.config'
dest: C:\Windows\System32\inetsrv\config\applicationHost.config
remote_src: yes
register: copy_result

- assert:
that:
- "stat_result.stat.checksum == copy_result.checksum"

- name: remove IIS feature if it was installed
ansible.windows.win_feature:
name: Web-Server
state: absent
include_management_tools: True
when: feature_install is changed
register: feature_uninstall

- name: reboot after removing IIS features
ansible.windows.win_reboot:
when: feature_uninstall.reboot_required | default(False)
Loading

0 comments on commit bc56e7b

Please sign in to comment.