├── .editorconfig ├── .envrc ├── .gitattributes ├── .github ├── CODEOWNERS └── workflows │ ├── ci.yml │ └── stale.yml ├── .gitignore ├── .markdownlint-cli2.yaml ├── .mdlrc ├── .overcommit.yml ├── .rubocop.yml ├── .vscode └── extensions.json ├── .yamllint ├── Berksfile ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dangerfile ├── LICENSE ├── README.md ├── TESTING.md ├── attributes └── default.rb ├── chefignore ├── documentation ├── .gitkeep ├── iis_app.md ├── iis_certificate_binding.md ├── iis_config.md ├── iis_config_property.md ├── iis_http_acl.md ├── iis_install.md ├── iis_manager.md ├── iis_manager_permission.md ├── iis_module.md ├── iis_pool.md ├── iis_root.md ├── iis_section.md ├── iis_site.md └── iis_vdir.md ├── kitchen.dokken.yml ├── kitchen.exec.yml ├── kitchen.global.yml ├── kitchen.yml ├── libraries ├── constants.rb ├── helper.rb ├── processors.rb └── section_helper.rb ├── metadata.rb ├── recipes ├── default.rb ├── mod_application_initialization.rb ├── mod_aspnet.rb ├── mod_aspnet45.rb ├── mod_auth_anonymous.rb ├── mod_auth_basic.rb ├── mod_auth_digest.rb ├── mod_auth_windows.rb ├── mod_cgi.rb ├── mod_compress_dynamic.rb ├── mod_compress_static.rb ├── mod_ftp.rb ├── mod_iis6_metabase_compat.rb ├── mod_isapi.rb ├── mod_logging.rb ├── mod_management.rb ├── mod_security.rb ├── mod_tracing.rb └── remove_default_site.rb ├── renovate.json ├── resources ├── app.rb ├── certificate_binding.rb ├── config.rb ├── config_property.rb ├── http_acl.rb ├── install.rb ├── manager.rb ├── manager_permission.rb ├── module.rb ├── pool.rb ├── root.rb ├── section.rb ├── site.rb └── vdir.rb ├── spec ├── spec_helper.rb └── unit │ ├── recipes │ ├── default_spec.rb │ ├── mod_application_initialization_spec.rb │ ├── mod_aspnet45_spec.rb │ ├── mod_aspnet_spec.rb │ ├── mod_auth_anonymous_spec.rb │ ├── mod_auth_basic_spec.rb │ ├── mod_auth_digest_spec.rb │ ├── mod_auth_windows_spec.rb │ ├── mod_cgi_spec.rb │ ├── mod_compress_dynamic_spec.rb │ ├── mod_compress_static_spec.rb │ ├── mod_ftp_spec.rb │ ├── mod_iis6_metabase_compat.rb │ ├── mod_isapi_spec.rb │ ├── mod_logging_spec.rb │ ├── mod_management_spec.rb │ ├── mod_security_spec.rb │ ├── mod_tracing_spec.rb │ └── remove_default_site_spec.rb │ └── resources │ └── install_spec.rb └── test ├── cookbooks └── test │ ├── chefignore │ ├── files │ └── default │ │ └── F5XFFHttpModule │ │ ├── x64 │ │ └── F5XFFHttpModule.dll │ │ └── x86 │ │ └── F5XFFHttpModule.dll │ ├── metadata.rb │ └── recipes │ ├── app.rb │ ├── config.rb │ ├── config_property.rb │ ├── manager.rb │ ├── manager_permission.rb │ ├── module.rb │ ├── pool.rb │ ├── root.rb │ ├── section.rb │ ├── site.rb │ └── vdir.rb └── integration ├── app ├── README.md ├── controls │ └── app_spec.rb ├── inspec.yml └── libraries │ ├── .gitkeep │ └── iis_app.rb ├── config_property └── config_property_spec.rb ├── default └── spec │ └── default_spec.rb ├── manager └── manager.rb ├── manager_permission └── manager_permission.rb ├── module ├── README.md ├── controls │ └── module_spec.rb ├── inspec.yml └── libraries │ ├── .gitkeep │ └── iis_module.rb ├── pool ├── README.md ├── controls │ └── pool_spec.rb ├── inspec.yml └── libraries │ ├── .gitkeep │ └── iis_pool.rb ├── root ├── README.md ├── controls │ └── root_spec.rb └── inspec.yml ├── section ├── README.md ├── controls │ └── section_spec.rb ├── inspec.yml └── libraries │ ├── .gitkeep │ └── iis_section.rb ├── site └── site_spec.rb └── vdir ├── README.md ├── controls └── vdir_spec.rb ├── inspec.yml └── libraries ├── .gitkeep └── iis_vdir.rb /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root=true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # Avoid issues parsing cookbook files later 16 | charset = utf-8 17 | 18 | # Avoid cookstyle warnings 19 | trim_trailing_whitespace = true 20 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use chefworkstation 2 | export KITCHEN_GLOBAL_YAML=kitchen.global.yml 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @sous-chefs/maintainers 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | "on": 5 | pull_request: 6 | push: 7 | branches: [main] 8 | 9 | jobs: 10 | lint-unit: 11 | uses: sous-chefs/.github/.github/workflows/lint-unit.yml@3.1.1 12 | with: 13 | platform: windows-latest 14 | permissions: 15 | actions: write 16 | checks: write 17 | pull-requests: write 18 | statuses: write 19 | issues: write 20 | 21 | integration: 22 | needs: lint-unit 23 | runs-on: windows-latest 24 | strategy: 25 | matrix: 26 | os: 27 | - "windows-latest" 28 | suite: 29 | - "default" 30 | - "disable-default" 31 | - "app" 32 | - "config-property" 33 | - "manager" 34 | - "manager-permission" 35 | - "module" 36 | - "pool" 37 | - "root" 38 | - "section" 39 | - "site" 40 | - "vdir" 41 | - "default-windowsfeatures-powershell" 42 | - "site-windowsfeatures-powershell" 43 | fail-fast: false 44 | 45 | steps: 46 | - name: Check out code 47 | uses: actions/checkout@v4 48 | - name: Install Chef 49 | uses: actionshub/chef-install@3.0.0 50 | - name: test-kitchen 51 | uses: actionshub/test-kitchen@3.0.0 52 | env: 53 | CHEF_LICENSE: accept-no-persist 54 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 55 | with: 56 | suite: ${{ matrix.suite }} 57 | os: ${{ matrix.os }} 58 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Mark stale issues and pull requests 3 | 4 | "on": 5 | schedule: [cron: "0 0 * * *"] 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v9 12 | with: 13 | repo-token: ${{ secrets.GITHUB_TOKEN }} 14 | close-issue-message: > 15 | Closing due to inactivity. 16 | If this is still an issue please reopen or open another issue. 17 | Alternatively drop by the #sous-chefs channel on the [Chef Community Slack](http://community-slack.chef.io/) and we'll be happy to help! 18 | Thanks, Sous-Chefs. 19 | days-before-close: 7 20 | days-before-stale: 365 21 | stale-issue-message: > 22 | Marking stale due to inactivity. 23 | Remove stale label or comment or this will be closed in 7 days. 24 | Alternatively drop by the #sous-chefs channel on the [Chef Community Slack](http://community-slack.chef.io/) and we'll be happy to help! 25 | Thanks, Sous-Chefs. 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | .config 3 | InstalledFiles 4 | pkg 5 | test/tmp 6 | test/version_tmp 7 | tmp 8 | _Store 9 | *~ 10 | *# 11 | .#* 12 | \#*# 13 | *.un~ 14 | *.tmp 15 | *.bk 16 | *.bkup 17 | 18 | # editor files 19 | .idea 20 | .*.sw[a-z] 21 | 22 | # ruby/bundler/rspec files 23 | .ruby-version 24 | .ruby-gemset 25 | .rvmrc 26 | Gemfile.lock 27 | .bundle 28 | *.gem 29 | coverage 30 | spec/reports 31 | 32 | # YARD / rdoc artifacts 33 | .yardoc 34 | _yardoc 35 | doc/ 36 | rdoc 37 | 38 | # chef infra stuff 39 | Berksfile.lock 40 | .kitchen 41 | kitchen.local.yml 42 | vendor/ 43 | .coverage/ 44 | .zero-knife.rb 45 | Policyfile.lock.json 46 | 47 | # vagrant stuff 48 | .vagrant/ 49 | .vagrant.d/ 50 | -------------------------------------------------------------------------------- /.markdownlint-cli2.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | ul-indent: false # MD007 3 | line-length: false # MD013 4 | no-duplicate-heading: false # MD024 5 | reference-links-images: false # MD052 6 | ignores: 7 | - .github/copilot-instructions.md 8 | -------------------------------------------------------------------------------- /.mdlrc: -------------------------------------------------------------------------------- 1 | rules "~MD013", "~MD024" 2 | -------------------------------------------------------------------------------- /.overcommit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | PreCommit: 3 | TrailingWhitespace: 4 | enabled: true 5 | YamlLint: 6 | enabled: true 7 | required_executable: "yamllint" 8 | ChefSpec: 9 | enabled: true 10 | required_executable: "chef" 11 | command: ["chef", "exec", "rspec"] 12 | Cookstyle: 13 | enabled: true 14 | required_executable: "cookstyle" 15 | command: ["cookstyle"] 16 | MarkdownLint: 17 | enabled: false 18 | required_executable: "npx" 19 | command: ["npx", "markdownlint-cli2", "'**/*.md'"] 20 | include: ["**/*.md"] 21 | 22 | CommitMsg: 23 | HardTabs: 24 | enabled: true 25 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # rubocop todo 2 | 3 | Lint/ParenthesesAsGroupedExpression: 4 | Exclude: 5 | - 'test/**/*.rb' 6 | 7 | Naming/PredicateName: 8 | Exclude: 9 | - 'spec/**/*' 10 | - 'test/integration/**/*' 11 | 12 | Style/IfUnlessModifier: 13 | Exclude: 14 | - 'resources/pool.rb' 15 | - 'resources/site.rb' 16 | 17 | # Fix missing Carriage return error on Windows 18 | # https://github.com/bbatsov/rubocop/issues/4293 19 | Layout/EndOfLine: 20 | EnforcedStyle: lf 21 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chef-software.chef", 4 | "rebornix.ruby", 5 | "editorconfig.editorconfig", 6 | "DavidAnson.vscode-markdownlint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | rules: 4 | line-length: 5 | max: 256 6 | level: warning 7 | document-start: disable 8 | braces: 9 | forbid: false 10 | min-spaces-inside: 0 11 | max-spaces-inside: 1 12 | min-spaces-inside-empty: -1 13 | max-spaces-inside-empty: -1 14 | comments: 15 | min-spaces-from-content: 1 16 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | source 'https://supermarket.chef.io' 2 | 3 | metadata 4 | 5 | group :integration do 6 | cookbook 'test', path: 'test/cookbooks/test' 7 | end 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Guidelines 2 | 3 | This project follows the Chef Community Guidelines 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please refer to 4 | [https://github.com/chef-cookbooks/community_cookbook_documentation/blob/main/CONTRIBUTING.MD](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/main/CONTRIBUTING.MD) 5 | -------------------------------------------------------------------------------- /Dangerfile: -------------------------------------------------------------------------------- 1 | # Reference: http://danger.systems/reference.html 2 | 3 | # A pull request summary is required. Add a description of the pull request purpose. 4 | # Changelog must be updated for each pull request that changes code. 5 | # Warnings will be issued for: 6 | # Pull request with more than 400 lines of code changed 7 | # Pull reqest that change more than 5 lines without test changes 8 | # Failures will be issued for: 9 | # Pull request without summary 10 | # Pull requests with code changes without changelog entry 11 | 12 | def code_changes? 13 | code = %w(libraries attributes recipes resources files templates) 14 | code.each do |location| 15 | return true unless git.modified_files.grep(/#{location}/).empty? 16 | end 17 | false 18 | end 19 | 20 | def test_changes? 21 | tests = %w(spec test kitchen.yml kitchen.dokken.yml) 22 | tests.each do |location| 23 | return true unless git.modified_files.grep(/#{location}/).empty? 24 | end 25 | false 26 | end 27 | 28 | failure 'Please provide a summary of your Pull Request.' if github.pr_body.length < 10 29 | 30 | warn 'This is a big Pull Request.' if git.lines_of_code > 400 31 | 32 | warn 'This is a Table Flip.' if git.lines_of_code > 2000 33 | 34 | # Require a CHANGELOG entry for non-test changes. 35 | if !git.modified_files.include?('CHANGELOG.md') && code_changes? 36 | failure 'Please include a CHANGELOG entry.' 37 | end 38 | 39 | # Require Major Minor Patch version labels 40 | unless github.pr_labels.grep /minor|major|patch/i 41 | warn 'Please add a release label to this pull request' 42 | end 43 | 44 | # A sanity check for tests. 45 | if git.lines_of_code > 5 && code_changes? && !test_changes? 46 | warn 'This Pull Request is probably missing tests.' 47 | end 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iis Cookbook 2 | 3 | [![Cookbook Version](https://img.shields.io/cookbook/v/iis.svg?style=flat)](https://supermarket.chef.io/cookbooks/iis) 4 | [![CI State](https://github.com/sous-chefs/iis/workflows/ci/badge.svg)](https://github.com/sous-chefs/iis/actions?query=workflow%3Aci) 5 | [![OpenCollective](https://opencollective.com/sous-chefs/backers/badge.svg)](#backers) 6 | [![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors) 7 | [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) 8 | 9 | ## Description 10 | 11 | Installs and configures Microsoft Internet Information Services (IIS) 7.0 and later 12 | 13 | ## Maintainers 14 | 15 | This cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If you’d like to know more please visit [sous-chefs.org](https://sous-chefs.org/) or come chat with us on the Chef Community Slack in [#sous-chefs](https://chefcommunity.slack.com/messages/C2V7B88SF). 16 | 17 | ## Requirements 18 | 19 | ### Platforms 20 | 21 | - Windows Server 2016 22 | - Windows Server 2019 23 | 24 | ### Chef 25 | 26 | - Chef 12.14+ 27 | 28 | ### Cookbooks 29 | 30 | - windows if running on chef < 16 31 | 32 | ## Attributes 33 | 34 | - `node['iis']['home']` - IIS main home directory. default is `%WINDIR%\System32\inetsrv` 35 | - `node['iis']['conf_dir']` - location where main IIS configs lives. default is `%WINDIR%\System32\inetsrv\config` 36 | - `node['iis']['pubroot']` - . default is `%SYSTEMDRIVE%\inetpub` 37 | - `node['iis']['docroot']` - IIS web site home directory. default is `%SYSTEMDRIVE%\inetpub\wwwroot` 38 | - `node['iis']['cache_dir']` - location of cached data. default is `%SYSTEMDRIVE%\inetpub\temp` 39 | - `node['iis']['windows_feature_install_method']` - specify the install method that will be used by any windows_feature resources. If ommitted it will not be specified and will use `windows_feature_dism` by default. Valid options are `:windows_feature_dism`, `:windows_feature_powershell`, `:windows_feature_servermanagercmd`. Default is `:windows_feature_dism` 40 | 41 | ## Resources 42 | 43 | - [iis_app](https://github.com/sous-chefs/iis/tree/master/documentation/iis_app.md) 44 | - [iis_config_property](https://github.com/sous-chefs/iis/tree/master/documentation/iis_config_property.md) 45 | - [iis_config](https://github.com/sous-chefs/iis/tree/master/documentation/iis_config.md) 46 | - [iis_install](https://github.com/sous-chefs/iis/tree/master/documentation/iis_install.md) 47 | - [iis_manager](https://github.com/sous-chefs/iis/tree/master/documentation/iis_manager.md) 48 | - [iis_manager_permission](https://github.com/sous-chefs/iis/tree/master/documentation/iis_manager_permission.md) 49 | - [iis_module](https://github.com/sous-chefs/iis/tree/master/documentation/iis_module.md) 50 | - [iis_pool](https://github.com/sous-chefs/iis/tree/master/documentation/iis_pool.md) 51 | - [iis_root](https://github.com/sous-chefs/iis/tree/master/documentation/iis_root.md) 52 | - [iis_section](https://github.com/sous-chefs/iis/tree/master/documentation/iis_section.md) 53 | - [iis_site](https://github.com/sous-chefs/iis/tree/master/documentation/iis_site.md) 54 | - [iis_vdir](https://github.com/sous-chefs/iis/tree/master/documentation/iis_vdir.md) 55 | 56 | ## Recipies 57 | 58 | These recipies still exist but are highly likely to be removed in future major releases of this cookbook. 59 | 60 | ### default recipe 61 | 62 | Installs and configures IIS 7.0/7.5/8.0 using the default configuration. 63 | 64 | ### mod_* recipes 65 | 66 | This cookbook also contains recipes for installing individual IIS modules (extensions). These recipes can be included in a node's run_list to build the minimal desired custom IIS installation. 67 | 68 | - `mod_aspnet` - installs ASP.NET runtime components 69 | - `mod_aspnet45` - installs ASP.NET 4.5 runtime components 70 | - `mod_auth_basic` - installs Basic Authentication support 71 | - `mod_auth_windows` - installs Windows Authentication (authenticate clients by using NTLM or Kerberos) support 72 | - `mod_compress_dynamic` - installs dynamic content compression support. _PLEASE NOTE_ - enabling dynamic compression always gives you more efficient use of bandwidth, but if your server's processor utilization is already very high, the CPU load imposed by dynamic compression might make your site perform more slowly. 73 | - `mod_compress_static` - installs static content compression support 74 | - `mod_ftp` - installs FTP service 75 | - `mod_iis6_metabase_compat` - installs IIS 6 Metabase Compatibility component. 76 | - `mod_isapi` - installs ISAPI (Internet Server Application Programming Interface) extension and filter support. 77 | - `mod_logging` - installs and enables HTTP Logging (logging of Web site activity), Logging Tools (logging tools and scripts) and Custom Logging (log any of the HTTP request/response headers, IIS server variables, and client-side fields with simple configuration) support 78 | - `mod_management` - installs Web server Management Console which supports management of local and remote Web servers 79 | - `mod_security` - installs URL Authorization (Authorizes client access to the URLs that comprise a Web application), Request Filtering (configures rules to block selected client requests) and IP Security (allows or denies content access based on IP address or domain name) support. 80 | - `mod_tracing` - installs support for tracing ASP.NET applications and failed requests. 81 | 82 | Note: Not every possible IIS module has a corresponding recipe. The foregoing recipes are included for convenience, but users may also place additional IIS modules that are installable as Windows features into the `node['iis']['components']` array. 83 | 84 | ## Contributors 85 | 86 | This project exists thanks to all the people who [contribute.](https://opencollective.com/sous-chefs/contributors.svg?width=890&button=false) 87 | 88 | ### Backers 89 | 90 | Thank you to all our backers! 91 | 92 | ![https://opencollective.com/sous-chefs#backers](https://opencollective.com/sous-chefs/backers.svg?width=600&avatarHeight=40) 93 | 94 | ### Sponsors 95 | 96 | Support this project by becoming a sponsor. Your logo will show up here with a link to your website. 97 | 98 | ![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100) 99 | ![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100) 100 | ![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100) 101 | ![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100) 102 | ![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100) 103 | ![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100) 104 | ![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100) 105 | ![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100) 106 | ![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100) 107 | ![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100) 108 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Please refer to [the community cookbook documentation on testing](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/main/TESTING.MD). 4 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Attribute:: default 4 | # 5 | # Copyright:: 2011-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | default['iis']['home'] = "#{ENV['WINDIR']}\\System32\\inetsrv" 21 | default['iis']['conf_dir'] = "#{ENV['WINDIR']}\\System32\\inetsrv\\config" 22 | default['iis']['pubroot'] = "#{ENV['SYSTEMDRIVE']}\\inetpub" 23 | default['iis']['docroot'] = "#{ENV['SYSTEMDRIVE']}\\inetpub\\wwwroot" 24 | default['iis']['cache_dir'] = "#{ENV['SYSTEMDRIVE']}\\inetpub\\temp" 25 | default['iis']['components'] = [] 26 | 27 | default['iis']['source'] = nil 28 | 29 | default['iis']['recycle']['log_events'] = 'Time, Requests, Schedule, Memory, IsapiUnhealthy, OnDemand, ConfigChange, PrivateMemory' 30 | 31 | default['iis']['windows_feature_install_method'] = :windows_feature_dism 32 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | .envrc 13 | 14 | # EDITORS # 15 | ########### 16 | .#* 17 | .project 18 | .settings 19 | *_flymake 20 | *_flymake.* 21 | *.bak 22 | *.sw[a-z] 23 | *.tmproj 24 | *~ 25 | \#* 26 | REVISION 27 | TAGS* 28 | tmtags 29 | .vscode 30 | .editorconfig 31 | 32 | ## COMPILED ## 33 | ############## 34 | *.class 35 | *.com 36 | *.dll 37 | *.exe 38 | *.o 39 | *.pyc 40 | *.so 41 | */rdoc/ 42 | a.out 43 | mkmf.log 44 | 45 | # Testing # 46 | ########### 47 | .circleci/* 48 | .codeclimate.yml 49 | .delivery/* 50 | .foodcritic 51 | .kitchen* 52 | .mdlrc 53 | .overcommit.yml 54 | .rspec 55 | .rubocop.yml 56 | .travis.yml 57 | .watchr 58 | .yamllint 59 | azure-pipelines.yml 60 | Dangerfile 61 | examples/* 62 | features/* 63 | Guardfile 64 | kitchen*.yml 65 | mlc_config.json 66 | Procfile 67 | Rakefile 68 | spec/* 69 | test/* 70 | 71 | # SCM # 72 | ####### 73 | .git 74 | .gitattributes 75 | .gitconfig 76 | .github/* 77 | .gitignore 78 | .gitkeep 79 | .gitmodules 80 | .svn 81 | */.bzr/* 82 | */.git 83 | */.hg/* 84 | */.svn/* 85 | 86 | # Berkshelf # 87 | ############# 88 | Berksfile 89 | Berksfile.lock 90 | cookbooks/* 91 | tmp 92 | 93 | # Bundler # 94 | ########### 95 | vendor/* 96 | Gemfile 97 | Gemfile.lock 98 | 99 | # Policyfile # 100 | ############## 101 | Policyfile.rb 102 | Policyfile.lock.json 103 | 104 | # Documentation # 105 | ############# 106 | CODE_OF_CONDUCT* 107 | CONTRIBUTING* 108 | documentation/* 109 | TESTING* 110 | UPGRADING* 111 | 112 | # Vagrant # 113 | ########### 114 | .vagrant 115 | Vagrantfile 116 | -------------------------------------------------------------------------------- /documentation/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/documentation/.gitkeep -------------------------------------------------------------------------------- /documentation/iis_app.md: -------------------------------------------------------------------------------- 1 | # iis_app 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Creates an application in IIS. 6 | 7 | ## Actions 8 | 9 | - `:add` - add a new application pool 10 | - `:delete` - delete an existing application pool 11 | - `:config` - configures an existing application pool 12 | 13 | ## Properties 14 | 15 | | Name | Type | Default | Description | 16 | | ------------------- | -------- | -------- | ------------------------------------------------------------------------- | 17 | | `site_name` | String | | name property. The name of the site to add this app to. We use the resource name if this isn't specified here. | 18 | | `path` | String | `/` | The virtual path for this application | 19 | | `application_pool` | String | | The pool this application belongs to | 20 | | `physical_path` | String | | The physical path where this app resides. | 21 | | `enabled_protocols` | String | | The enabled protocols that this app provides (http, https, net.pipe, net.tcp, etc) | 22 | 23 | ## Examples 24 | 25 | ```ruby 26 | # creates a new app 27 | iis_app 'myApp' do 28 | path '/v1_1' 29 | application_pool 'myAppPool_v1_1' 30 | physical_path "#{node['iis']['docroot']}/testfu/v1_1" 31 | enabled_protocols 'http,net.pipe' 32 | action :add 33 | end 34 | ``` 35 | -------------------------------------------------------------------------------- /documentation/iis_certificate_binding.md: -------------------------------------------------------------------------------- 1 | # windows_certificate_binding 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Binds a certificate to an HTTP port to enable TLS communication. 6 | 7 | ## Actions 8 | 9 | - `:create` - creates or updates a binding. 10 | - `:delete` - deletes a binding. 11 | 12 | ## Properties 13 | 14 | - `cert_name` - name attribute. The thumbprint(hash) or subject that identifies the certificate to be bound. 15 | - `name_kind` - indicates the type of cert_name. One of :subject (default) or :hash. 16 | - `address` - the address to bind against. Default is 0.0.0.0 (all IP addresses). One of: 17 | - IP v4 address `1.2.3.4` 18 | - IP v6 address `[::1]` 19 | - Host name `www.foo.com` 20 | - `port` - the port to bind against. Default is 443. 21 | - `app_id` - the GUID that defines the application that owns the binding. Default is the values used by IIS. 22 | - `store_name` - the store to locate the certificate in. One of: 23 | - MY (Personal) 24 | - CA (Intermediate Certification Authorities) 25 | - ROOT (Trusted Root Certification Authorities) 26 | - TRUSTEDPUBLISHER (Trusted Publishers) 27 | - CLIENTAUTHISSUER (Client Authentication Issuers) 28 | - REMOTE DESKTOP (Remote Desktop) 29 | - TRUSTEDDEVICES (Trusted Devices) 30 | - WEBHOSTING (Web Hosting) 31 | - AUTHROOT (Third-Party Root Certification Authorities) 32 | - TRUSTEDPEOPLE (Trusted People) 33 | - SMARTCARDROOT (Smart Card Trusted Roots) 34 | - TRUST (Enterprise Trust) 35 | 36 | ## Examples 37 | 38 | ```ruby 39 | # Bind the first certificate matching the subject to the default TLS port 40 | iis_certificate_binding "me.acme.com" do 41 | end 42 | ``` 43 | 44 | ```ruby 45 | # Bind a cert from the CA store with the given hash to port 4334 46 | iis_certificate_binding "me.acme.com" do 47 | cert_name "d234567890a23f567c901e345bc8901d34567890" 48 | name_kind :hash 49 | store_name "CA" 50 | port 4334 51 | end 52 | ``` 53 | -------------------------------------------------------------------------------- /documentation/iis_config.md: -------------------------------------------------------------------------------- 1 | # iis_config 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Runs a config command on your IIS instance. 6 | 7 | ## Actions 8 | 9 | - `:set` - Edit configuration section (appcmd set config) 10 | - `:clear` - Clear the section configuration (appcmd clear config) 11 | 12 | ## Properties 13 | 14 | | Name | Type | Default | Description | 15 | | ------------------- | -------- | -------- | ------------------------------------------------------------------------- | 16 | | `cfg_cmd` | String | | name property. What ever command you would pass in after "appcmd.exe set config" We use the resource name if this isn't specified here. | 17 | 18 | ## Examples 19 | 20 | ```ruby 21 | # Sets up logging 22 | iis_config "/section:system.applicationHost/sites /siteDefaults.logfile.directory:\"D:\\logs\"" do 23 | action :set 24 | end 25 | ``` 26 | 27 | ```ruby 28 | # Increase file upload size for 'MySite' 29 | iis_config "\"MySite\" /section:requestfiltering /requestlimits.maxallowedcontentlength:50000000" do 30 | action :set 31 | end 32 | ``` 33 | 34 | ```ruby 35 | # Set IUSR username and password authentication 36 | iis_config "\"MyWebsite/aSite\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\"True\" /userName:\"IUSR_foobar\" /password:\"p@assword\" /commit:apphost" do 37 | action :set 38 | end 39 | ``` 40 | 41 | ```ruby 42 | # Authenticate with application pool 43 | iis_config "\"MyWebsite/aSite\" -section:system.webServer/security/authentication/anonymousAuthentication /enabled:\"True\" /userName:\"\" /commit:apphost" do 44 | action :set 45 | end 46 | ``` 47 | 48 | ```ruby 49 | # Loads an array of commands from the node 50 | cfg_cmds = node['iis']['cfg_cmd'] 51 | cfg_cmds.each do |cmd| 52 | iis_config "#{cmd}" do 53 | action :set 54 | end 55 | end 56 | ``` 57 | 58 | ```ruby 59 | # Add static machine key at site level 60 | iis_config "MySite /commit:site /section:machineKey /validation:AES /validationKey:AAAAAA /decryptionKey:ZZZZZ" do 61 | action :set 62 | end 63 | ``` 64 | 65 | ```ruby 66 | # Remove machine key 67 | iis_config "MySite /commit:site /section:machineKey" do 68 | action :clear 69 | end 70 | ``` 71 | -------------------------------------------------------------------------------- /documentation/iis_config_property.md: -------------------------------------------------------------------------------- 1 | # iis_config_property 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Sets an IIS configuration property 6 | 7 | ## Actions 8 | 9 | - `:set` : Sets the property to the given value if it is not already set. 10 | - `:add` : Adds an item to a collection if one doesn't already exist. `filter` should define a collection element. An item will be added if there is no member with a `property` value of `value`. 11 | - `:remove` : Removes a item from a collection if it already exists. `filter` should define a collection element. The item will be removed if there is a member with a `property` value of `value`. 12 | 13 | ## Properties 14 | 15 | | Name | Type | Required| Description | 16 | | ------------------- | ----------------- | ------- | ------------------------------------------------------------------------- | 17 | | `property` | String | Yes | name property. The property to be set. Defaults from name. | 18 | | `ps_path` | String | Yes | Specifies the configuration path. This can be either an IIS configuration path in the format `computer name/webroot/apphost`, or the IIS module path in this format `IIS:\sites\Default Web Site`. | 19 | | `location` | String | No | The location of the configuration setting. Location tags are frequently used for configuration settings that must be set more precisely than per application or per virtual directory. For example, a setting for a particular file or directory could use a location tag. Location tags are also used if a particular section is locked. In such an instance, the configuration system would have to use a location tag in one of the parent configuration files. | 20 | | `filter` | String | Yes | Specifies the IIS configuration section or an XPath query that returns a configuration element. | 21 | | `value` | String, Integer | Yes | The value to set the property to. Either a string or an integer. | 22 | | `extra_add_values` | Hash | No | If the `add` action requires additional values to be set at creation then supply them in this hash. This property is not idempotent. It is only used when the configuration is created.| 23 | 24 | ## Examples 25 | 26 | ```ruby 27 | # Sets up logging 28 | iis_config_property 'directory' do 29 | ps_path 'MACHINE/WEBROOT/APPHOST' 30 | filter 'system.applicationHost/sites/siteDefaults/logfile' 31 | value 'D:\\logs' 32 | end 33 | ``` 34 | 35 | ```ruby 36 | # Set XSS-Protection header on all sites 37 | iis_config_property 'Add X-Xss-Protection' do 38 | ps_path 'MACHINE/WEBROOT/APPHOST' 39 | filter 'system.webServer/httpProtocol/customHeaders' 40 | property 'name' 41 | value 'X-Xss-Protection' 42 | action :add 43 | end 44 | iis_config_property 'Set X-Xss-Protection' do 45 | ps_path 'MACHINE/WEBROOT/APPHOST' 46 | filter "system.webServer/httpProtocol/customHeaders/add[@name='X-Xss-Protection']" 47 | property 'value' 48 | value '1; mode=block' 49 | end 50 | ``` 51 | 52 | ```ruby 53 | # Set environment variable ASPNETCORE_ENVIRONMENT to Test 54 | # Note we still need to maintain the value via a Set resource 55 | iis_config_property 'Add login/ASPNETCORE_ENVIRONMENT' do 56 | ps_path 'MACHINE/WEBROOT/APPHOST' 57 | location 'Default Web site' 58 | filter 'system.webServer/aspNetCore/environmentVariables' 59 | property 'name' 60 | value 'ASPNETCORE_ENVIRONMENT' 61 | extra_add_values value: 'Test' 62 | action :add 63 | end 64 | iis_config_property 'Set login/ASPNETCORE_ENVIRONMENT' do 65 | ps_path 'MACHINE/WEBROOT/APPHOST' 66 | location 'Default Web site' 67 | filter "system.webServer/aspNetCore/environmentVariables/environmentVariable[@name='ASPNETCORE_ENVIRONMENT']" 68 | property 'value' 69 | value 'Test' 70 | end 71 | ``` 72 | -------------------------------------------------------------------------------- /documentation/iis_http_acl.md: -------------------------------------------------------------------------------- 1 | # iis_http_acl 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Sets the Access Control List for an http URL to grant non-admin accounts permission to open HTTP endpoints. 6 | 7 | ## Actions 8 | 9 | - `:create` - creates or updates the ACL for a URL. 10 | - `:delete` - deletes the ACL from a URL. 11 | 12 | ## Properties 13 | 14 | - `url` - the name of the url to be created/deleted. 15 | - `sddl` - the DACL string configuring all permissions to URL. Mandatory for create if user is not provided. Can't be use with `user`. 16 | - `user` - the name (domain\user) of the user or group to be granted permission to the URL. Mandatory for create if sddl is not provided. Can't be use with `sddl`. Only one user or group can be granted permission so this replaces any previously defined entry. If you receive a parameter error your user may not exist. 17 | 18 | ## Examples 19 | 20 | ```ruby 21 | iis_http_acl 'http://+:50051/' do 22 | user 'pc\\fred' 23 | end 24 | ``` 25 | 26 | ```ruby 27 | # Grant access to users "NT SERVICE\WinRM" and "NT SERVICE\Wecsvc" via sddl 28 | iis_http_acl 'http://+:5985/' do 29 | sddl 'D:(A;;GX;;;S-1-5-80-569256582-2953403351-2909559716-1301513147-412116970)(A;;GX;;;S-1-5-80-4059739203-877974739-1245631912-527174227-2996563517)' 30 | end 31 | ``` 32 | 33 | ```ruby 34 | iis_http_acl 'http://+:50051/' do 35 | action :delete 36 | end 37 | ``` 38 | -------------------------------------------------------------------------------- /documentation/iis_install.md: -------------------------------------------------------------------------------- 1 | # iis_install 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Simple resource to install the IIS feature 6 | 7 | ## Actions 8 | 9 | - `:install` 10 | 11 | ## Properties 12 | 13 | | Name | Type | Required| Description | 14 | | ----------------------- | -------------- | -------- | ------------------------------------ | 15 | | `source` | String | No | Source to install the features from. | 16 | | `additional_components` | String,Array | No | Features of IIS to install | 17 | | `install_method` | String, Symbol| No | install_method to be used to any windows_features resources. Default is :windows_feature_dism. Options are :windows_feature_dism, :windows_feature_powershell | 18 | | `start_iis` | true, false | No | Controls whether the W3WVC service is enabled and started. Default is false | 19 | 20 | ## Examples 21 | 22 | ```ruby 23 | # creates a new app 24 | iis_install 'install IIS' 25 | ``` 26 | -------------------------------------------------------------------------------- /documentation/iis_manager.md: -------------------------------------------------------------------------------- 1 | # iis_manager 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Configures the IIS Manager service 6 | 7 | ## Actions 8 | 9 | - `:config` - Change the configuration of the service. Restarts as necessary and sets the service to be automatic and running. 10 | 11 | ## Properties 12 | 13 | | Name | Type | Default | Description | 14 | | --------------------------- | --------------- | ------- | ------------------------------------ | 15 | | `enable_remote_management` | true, false | `true` | If remote access allowed | 16 | | `log_directory` | String | | Optional. The directory to write log files to | 17 | | `port` | Integer | `8172` | The port the service listens on. | 18 | | `install_method` | String, Symbol | `:windows_feature_dism` | Optional. install_method to be used to any windows_features resources. Valid options are :windows_feature_dism, :windows_feature_powershell | 19 | 20 | ## Examples 21 | 22 | ```ruby 23 | iis_manager 'IIS Manager' do 24 | port 9090 25 | enable_remote_management true 26 | log_directory "C:\\CustomPath" 27 | end 28 | ``` 29 | -------------------------------------------------------------------------------- /documentation/iis_manager_permission.md: -------------------------------------------------------------------------------- 1 | # iis_manager_permission 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Set the permissions for user access to the IIS Manager 6 | 7 | Requires: Server 2016+ 8 | 9 | ## Actions 10 | 11 | - `:config` : Configure the given path to allow only the defined users and groups access. Removes any other principals. This is an idempotent action. 12 | 13 | ## Properties 14 | 15 | | Name | Type | Required| Description | 16 | | ------------- | -------- | -------- | ------------------------------------ | 17 | | `config_path` | String | No | Name property. The IIS Manager path to be configured. Usually just the site name. Taken from the `name` attribute if not set, The config_path takes the form of_site_name_/_application_/_application_ (where applications are optional) | 18 | | `users` | Array | No | Array of users to be allowed access | 19 | | `groups` | Array | No | Array of groups to be allowed access | 20 | 21 | ## Examples 22 | 23 | ```ruby 24 | iis_manager_permission 'Default Web Site' do 25 | users ['BUILTIN\\Users'] 26 | end 27 | ``` 28 | -------------------------------------------------------------------------------- /documentation/iis_module.md: -------------------------------------------------------------------------------- 1 | # iis_module 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Manages modules globally or on a per site basis. 6 | 7 | ## Actions 8 | 9 | - `:add` - add a new module 10 | - `:delete` - delete a module 11 | - `:install` - install a native module from the filesystem (.dll) 12 | - `:uninstall` - uninstall a native module 13 | 14 | ## Properties 15 | 16 | | Name | Type | Default | Description | 17 | | --------------- | ------------- | ------- | ------------------------------------ | 18 | | `module_name` | String | | name property. The name of the module to add or delete | 19 | | `type` | String | | The type of module | 20 | | `precondition` | true, false | | precondition for module | 21 | | `application` | String | | The application or site to add the module to | 22 | | `add` | String | `false` | Whether the module you install has to be globally added | 23 | | `image` | String | | Location of the DLL of the module to install | 24 | 25 | ## Examples 26 | 27 | ```ruby 28 | # Adds a module called "My 3rd Party Module" to mySite/ 29 | iis_module "My 3rd Party Module" do 30 | application "mySite/" 31 | precondition "bitness64" 32 | action :add 33 | end 34 | ``` 35 | 36 | ```ruby 37 | # Adds a module called "MyModule" to all IIS sites on the server 38 | iis_module "MyModule" 39 | ``` 40 | -------------------------------------------------------------------------------- /documentation/iis_section.md: -------------------------------------------------------------------------------- 1 | # iis_section 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Allows for the locking/unlocking of sections ([listed here](http://www.iis.net/configreference) or via the command `appcmd list config \"\" /config:* /xml`) 6 | 7 | This is valuable to allow the `web.config` of an individual application/website control it's own settings. 8 | 9 | ## Actions 10 | 11 | - `section`: The name of the section to lock. 12 | - `site`: The name of the site you want to lock or unlock a section for. 13 | - `application_path`: The path to the application you want to lock or unlock a section for. 14 | 15 | ## Properties 16 | 17 | | Name | Type | Default | Description | 18 | | ------------------- | -------- | -------- | ------------------------------------------------------------------------- | 19 | | `section` | String | | The name of the section to lock. | 20 | | `site` | String | `/` | The name of the site you want to lock or unlock a section for | 21 | | `application_path` | String | | The path to the application you want to lock or unlock a section for.| 22 | 23 | ## Examples 24 | 25 | ```ruby 26 | # Sets the IIS global windows authentication to be locked globally 27 | iis_section 'locks global configuration of windows auth' do 28 | section 'system.webServer/security/authentication/windowsAuthentication' 29 | action :lock 30 | end 31 | ``` 32 | 33 | ```ruby 34 | # Sets the IIS global Basic authentication to be locked globally 35 | iis_section 'locks global configuration of Basic auth' do 36 | section 'system.webServer/security/authentication/basicAuthentication' 37 | action :lock 38 | end 39 | ``` 40 | 41 | ```ruby 42 | # Sets the IIS global windows authentication to be unlocked globally 43 | iis_section 'unlocked web.config globally for windows auth' do 44 | action :unlock 45 | section 'system.webServer/security/authentication/windowsAuthentication' 46 | end 47 | ``` 48 | 49 | ```ruby 50 | # Sets the IIS global Basic authentication to be unlocked globally 51 | iis_section 'unlocked web.config globally for Basic auth' do 52 | action :unlock 53 | section 'system.webServer/security/authentication/basicAuthentication' 54 | end 55 | ``` 56 | 57 | ```ruby 58 | # Sets the static content section for default web site and root to unlocked 59 | iis_section 'unlock staticContent of default web site' do 60 | section 'system.webServer/staticContent' 61 | site 'Default Web Site' 62 | action :unlock 63 | end 64 | ``` 65 | 66 | ```ruby 67 | # Sets the static content section for test_app under default website and root to be unlocked 68 | iis_section 'unlock staticContent of default web site' do 69 | section 'system.webServer/staticContent' 70 | site 'Default Web Site' 71 | application_path '/test_app' 72 | action :unlock 73 | end 74 | ``` 75 | -------------------------------------------------------------------------------- /documentation/iis_site.md: -------------------------------------------------------------------------------- 1 | # iis_site 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Allows for easy management of IIS virtual sites. 6 | 7 | ## Actions 8 | 9 | - `:add` - add a new virtual site 10 | - `:config` - apply configuration to an existing virtual site 11 | - `:delete` - delete an existing virtual site 12 | - `:start` - start a virtual site 13 | - `:stop` - stop a virtual site 14 | - `:restart` - restart a virtual site 15 | 16 | ## Properties 17 | 18 | | Name | Type | Default | Description | Allowed Values | 19 | | ------------------- | --------------- | -------- | ------------------------------------------------------------------------- |--- | 20 | | `site_name` | String | | name property. Specify the name of the site | | 21 | | `site_id` | Integer | | if not given IIS generates a unique ID for the site | | 22 | | `path` | String | | IIS will create a root application and a root virtual directory mapped to this specified local pathq| | 23 | | `protocol` | Symbol, String | | Protocol type the site should respond.| `:http`, `:https`, `:ftp`| 24 | | `port` | Integer | `80` | port site will listen on.| | 25 | | `host_header` | String | | host header (also known as domains or host names) the site should map to.| | 26 | | `bindings` | String | | Advanced options to configure the information required for requests to communicate with a Web site. See [iis bindings](http://www.iis.net/configreference/system.applicationhost/sites/site/bindings/binding) for parameter format. When binding is used, port protocol and host_header should not be used..| | 27 | | `application_pool` | String | | set the application pool of the site.| | 28 | | `options` | String | | additional options to configure the site. Such as `"-logDir"`, `"-limits"`, `"-ftpServer"`, `"-applicationDefaults.preloadEnabled:True"`. This can be anything that you would normally add to a appcmd. This only runs during `add` since it isn't idempotent| | 29 | | `log_directory` | String | | specifies the logging directory, where the log file and logging-related support files are stored.| | 30 | | `log_period` | Symbol, String | `:Daily` | specifies how often iis creates a new log file.| `:Daily`, `:Hourly`, `:MaxSize`, `:Monthly`, `:Weekly`| 31 | | `log_truncsize` | Integer |`1048576` | specifies the maximum size of the log file (in bytes) after which to create a new log file.| | 32 | 33 | ## Examples 34 | 35 | ```ruby 36 | # stop and delete the default site 37 | iis_site 'Default Web Site' do 38 | action [:stop, :delete] 39 | end 40 | ``` 41 | 42 | ```ruby 43 | # create and start a new site that maps to 44 | # the physical location C:\inetpub\wwwroot\testfu 45 | # first the physical location must exist 46 | directory "#{node['iis']['docroot']}/testfu" do 47 | action :create 48 | end 49 | 50 | # now create and start the site (note this will use the default application pool which must exist) 51 | iis_site 'Testfu Site' do 52 | protocol :http 53 | port 80 54 | path "#{node['iis']['docroot']}/testfu" 55 | action [:add,:start] 56 | end 57 | ``` 58 | 59 | ```ruby 60 | # do the same but map to testfu.chef.io domain 61 | # first the physical location must exist 62 | directory "#{node['iis']['docroot']}/testfu" do 63 | action :create 64 | end 65 | 66 | # now create and start the site (note this will use the default application pool which must exist) 67 | iis_site 'Testfu Site' do 68 | protocol :http 69 | port 80 70 | path "#{node['iis']['docroot']}/testfu" 71 | host_header "testfu.chef.io" 72 | action [:add,:start] 73 | end 74 | ``` 75 | 76 | ```ruby 77 | # create and start a new site that maps to 78 | # the physical C:\inetpub\wwwroot\testfu 79 | # first the physical location must exist 80 | directory "#{node['iis']['docroot']}/testfu" do 81 | action :create 82 | end 83 | 84 | # also adds bindings to http and https 85 | # binding http to the ip address 10.12.0.136, 86 | # the port 80, and the host header www.domain.com 87 | # also binding https to any ip address, 88 | # the port 443, and the host header www.domain.com 89 | # now create and start the site (note this will use the default application pool which must exist) 90 | iis_site 'FooBar Site' do 91 | bindings "http/10.12.0.136:80:www.domain.com,https/*:443:www.domain.com" 92 | path "#{node['iis']['docroot']}/testfu" 93 | action [:add,:start] 94 | end 95 | ``` 96 | 97 | ```ruby 98 | # create a site with preloadEnabled enabled 99 | iis_site 'mysite.com' do 100 | protocol :http 101 | port 80 102 | path "#{node['iis']['docroot']}\dataverify" 103 | application_pool 'dataverify.com' 104 | options "-applicationDefaults.preloadEnabled:True" 105 | action [:add, :start, :config] 106 | end 107 | ``` 108 | -------------------------------------------------------------------------------- /documentation/iis_vdir.md: -------------------------------------------------------------------------------- 1 | # iis_vdir 2 | 3 | [back to resource list](https://github.com/sous-chefs/iis#resources) 4 | 5 | Allows easy management of IIS virtual directories (i.e. vdirs). 6 | 7 | ## Actions 8 | 9 | - `:add` - add a new virtual directory 10 | - `:delete` - delete an existing virtual directory 11 | - `:config` - configure a virtual directory 12 | 13 | ## Properties 14 | 15 | | Name | Type | Default | Description | Allowed Values | 16 | | --------------------- | --------------- | ----------- | ------------------------------------------------------------------------- |--- | 17 | | `application_name` | String | | name property. This is the name of the website or site + application you are adding it to. | | 18 | | `path` | String | | The virtual directory path on the site. | | 19 | | `physical_path` | String | | The physical path of the virtual directory on the disk. | | 20 | | `username` | String | | The username required to logon to the physical_path. If set to "" will clear username and password.| | 21 | | `password` | String | | The password required to logon to the physical_path.| | 22 | | `logon_method` | Symbol, String | `:ClearText`| The method used to logon. For more information on these types, see [LogonUser Function](http://msdn2.microsoft.com/en-us/library/aa378184.aspx)|`:Interactive`, `:Batch`, `:Network`, `:ClearText` | 23 | | `allow_sub_dir_config`| true, false | `true` | Boolean that specifies whether or not the Web server will look for configuration files located in the subdirectories of this virtual directory. Setting this to false can improve performance on servers with very large numbers of web.config files, but doing so prevents IIS configuration from being read in subdirectories. | | 24 | 25 | ## Examples 26 | 27 | ```ruby 28 | # add a virtual directory to default application 29 | iis_vdir 'Default Web Site/' do 30 | action :add 31 | path '/Content/Test' 32 | physical_path 'C:\wwwroot\shared\test' 33 | end 34 | ``` 35 | 36 | ```ruby 37 | # add a virtual directory to an application under a site 38 | iis_vdir 'Default Web Site/my application' do 39 | action :add 40 | path '/Content/Test' 41 | physical_path 'C:\wwwroot\shared\test' 42 | end 43 | ``` 44 | 45 | ```ruby 46 | # adds a virtual directory to default application which points to a smb share. (Remember to escape the "\"'s) 47 | iis_vdir 'Default Web Site/' do 48 | action :add 49 | path '/Content/Test' 50 | physical_path '\\\\sharename\\sharefolder\\1' 51 | end 52 | ``` 53 | 54 | ```ruby 55 | # configure a virtual directory to have a username and password 56 | iis_vdir 'Default Web Site/' do 57 | action :config 58 | path '/Content/Test' 59 | username 'domain\myspecialuser' 60 | password 'myspecialpassword' 61 | end 62 | ``` 63 | 64 | ```ruby 65 | # delete a virtual directory from the default application 66 | iis_vdir 'Default Web Site/' do 67 | action :delete 68 | path '/Content/Test' 69 | end 70 | ``` 71 | -------------------------------------------------------------------------------- /kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | driver: 2 | name: dokken 3 | privileged: true 4 | chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> 5 | 6 | transport: { name: dokken } 7 | provisioner: { name: dokken } 8 | 9 | platforms: 10 | - name: almalinux-8 11 | driver: 12 | image: dokken/almalinux-8 13 | pid_one_command: /usr/lib/systemd/systemd 14 | 15 | - name: almalinux-9 16 | driver: 17 | image: dokken/almalinux-9 18 | pid_one_command: /usr/lib/systemd/systemd 19 | 20 | - name: almalinux-10 21 | driver: 22 | image: dokken/almalinux-10 23 | pid_one_command: /usr/lib/systemd/systemd 24 | 25 | - name: amazonlinux-2023 26 | driver: 27 | image: dokken/amazonlinux-2023 28 | pid_one_command: /usr/lib/systemd/systemd 29 | 30 | - name: centos-stream-9 31 | driver: 32 | image: dokken/centos-stream-9 33 | pid_one_command: /usr/lib/systemd/systemd 34 | 35 | - name: centos-stream-10 36 | driver: 37 | image: dokken/centos-stream-10 38 | pid_one_command: /usr/lib/systemd/systemd 39 | 40 | - name: debian-11 41 | driver: 42 | image: dokken/debian-11 43 | pid_one_command: /bin/systemd 44 | 45 | - name: debian-12 46 | driver: 47 | image: dokken/debian-12 48 | pid_one_command: /bin/systemd 49 | 50 | - name: fedora-latest 51 | driver: 52 | image: dokken/fedora-latest 53 | pid_one_command: /usr/lib/systemd/systemd 54 | 55 | - name: opensuse-leap-15 56 | driver: 57 | image: dokken/opensuse-leap-15 58 | pid_one_command: /usr/lib/systemd/systemd 59 | 60 | - name: oraclelinux-8 61 | driver: 62 | image: dokken/oraclelinux-8 63 | pid_one_command: /usr/lib/systemd/systemd 64 | 65 | - name: oraclelinux-9 66 | driver: 67 | image: dokken/oraclelinux-9 68 | pid_one_command: /usr/lib/systemd/systemd 69 | 70 | - name: rockylinux-8 71 | driver: 72 | image: dokken/rockylinux-8 73 | pid_one_command: /usr/lib/systemd/systemd 74 | 75 | - name: rockylinux-9 76 | driver: 77 | image: dokken/rockylinux-9 78 | pid_one_command: /usr/lib/systemd/systemd 79 | 80 | - name: ubuntu-20.04 81 | driver: 82 | image: dokken/ubuntu-20.04 83 | pid_one_command: /bin/systemd 84 | 85 | - name: ubuntu-22.04 86 | driver: 87 | image: dokken/ubuntu-22.04 88 | pid_one_command: /bin/systemd 89 | 90 | - name: ubuntu-24.04 91 | driver: 92 | image: dokken/ubuntu-24.04 93 | pid_one_command: /bin/systemd 94 | -------------------------------------------------------------------------------- /kitchen.exec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: { name: exec } 3 | transport: { name: exec } 4 | 5 | platforms: 6 | - name: macos-latest 7 | - name: windows-latest 8 | -------------------------------------------------------------------------------- /kitchen.global.yml: -------------------------------------------------------------------------------- 1 | --- 2 | provisioner: 3 | name: chef_infra 4 | product_name: chef 5 | product_version: <%= ENV['CHEF_VERSION'] || 'latest' %> 6 | channel: stable 7 | install_strategy: once 8 | chef_license: accept 9 | enforce_idempotency: <%= ENV['ENFORCE_IDEMPOTENCY'] || true %> 10 | multiple_converge: <%= ENV['MULTIPLE_CONVERGE'] || 2 %> 11 | deprecations_as_errors: true 12 | log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %> 13 | 14 | verifier: 15 | name: inspec 16 | 17 | platforms: 18 | - name: almalinux-8 19 | - name: almalinux-9 20 | - name: amazonlinux-2023 21 | - name: centos-stream-9 22 | - name: debian-11 23 | - name: debian-12 24 | - name: fedora-latest 25 | - name: opensuse-leap-15 26 | - name: oraclelinux-8 27 | - name: oraclelinux-9 28 | - name: rockylinux-8 29 | - name: rockylinux-9 30 | - name: ubuntu-20.04 31 | - name: ubuntu-22.04 32 | - name: ubuntu-24.04 33 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | driver: 2 | name: vagrant 3 | customize: 4 | cpus: 2 5 | memory: 4096 6 | 7 | transport: 8 | name: winrm 9 | elevated: true 10 | 11 | provisioner: 12 | name: chef_zero 13 | deprecations_as_errors: true 14 | product_name: chef 15 | channel: stable 16 | chef_license: accept 17 | 18 | verifier: 19 | name: inspec 20 | 21 | platforms: 22 | - name: windows-2008r2 23 | driver_config: 24 | box: tas50/windows_2008r2 25 | - name: windows-2012r2 26 | driver_config: 27 | box: tas50/windows_2012r2 28 | - name: windows-2016 29 | driver_config: 30 | box: tas50/windows_2016 31 | - name: windows-2019 32 | driver_config: 33 | box: tas50/windows_2019 34 | 35 | suites: 36 | - name: default 37 | run_list: 38 | - recipe[iis::default] 39 | - name: disable_default 40 | run_list: 41 | - recipe[iis::default] 42 | - recipe[iis::remove_default_site] 43 | - name: app 44 | run_list: 45 | - recipe[test::app] 46 | - name: config_property 47 | run_list: 48 | - recipe[test::config_property] 49 | - name: manager 50 | run_list: 51 | - recipe[test::manager] 52 | - name: manager_permission 53 | run_list: 54 | - recipe[test::manager_permission] 55 | excludes: ["windows-2008r2", "windows-2012r2"] 56 | - name: module 57 | run_list: 58 | - recipe[test::module] 59 | - name: pool 60 | run_list: 61 | - recipe[test::pool] 62 | - name: root 63 | run_list: 64 | - recipe[test::root] 65 | - name: section 66 | run_list: 67 | - recipe[test::section] 68 | - name: site 69 | run_list: 70 | - recipe[test::site] 71 | - name: vdir 72 | run_list: 73 | - recipe[test::vdir] 74 | - name: default-windowsfeatures-powershell 75 | run_list: 76 | - recipe[iis::default] 77 | verifier: 78 | inspec_tests: 79 | - test/integration/default/spec 80 | attributes: 81 | iis: 82 | windows_feature_install_method: windows_feature_powershell 83 | - name: site-windowsfeatures-powershell 84 | run_list: 85 | - recipe[test::site] 86 | verifier: 87 | inspec_tests: 88 | - test/integration/site 89 | attributes: 90 | iis: 91 | windows_feature_install_method: windows_feature_powershell 92 | -------------------------------------------------------------------------------- /libraries/helper.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Library:: helper 4 | # 5 | # Copyright:: 2017-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | module IISCookbook 21 | # Contains functions that are used throughout this cookbook 22 | module Helper 23 | @iis_version = nil 24 | 25 | if RUBY_PLATFORM =~ /mswin|mingw32|windows/ 26 | require 'chef/win32/version' 27 | require 'win32/registry' 28 | end 29 | 30 | require 'rexml/document' 31 | require 'chef/mixin/shell_out' 32 | 33 | include Chef::Mixin::ShellOut 34 | include REXML 35 | 36 | def self.older_than_windows2012? 37 | if RUBY_PLATFORM =~ /mswin|mingw32|windows/ 38 | win_version = Chef::ReservedNames::Win32::Version.new 39 | win_version.windows_7? || win_version.windows_server_2008_r2? 40 | end 41 | end 42 | 43 | def windows_cleanpath(path) 44 | path = if defined?(Chef::Util::PathHelper.cleanpath).nil? 45 | win_friendly_path(path) 46 | else 47 | Chef::Util::PathHelper.cleanpath(path) 48 | end 49 | # Remove any trailing slashes to prevent them from accidentally escaping any quotes. 50 | path.tr('/', '\\') 51 | end 52 | 53 | def application_cleanname(application_name) 54 | if application_name.count('/') == 0 55 | "#{application_name}/" 56 | elsif application_name.count('/') > 1 57 | application_name.chomp('/') 58 | else 59 | application_name 60 | end 61 | end 62 | 63 | def value(document, xpath) 64 | Text.unnormalize(XPath.first(document, xpath).to_s) 65 | end 66 | 67 | def get_value(document, xpath) 68 | XPath.match(document, xpath) 69 | end 70 | 71 | def bool(value) 72 | value == 'true' 73 | end 74 | 75 | def appcmd(node) 76 | @appcmd ||= "#{node['iis']['home']}\\appcmd.exe" 77 | end 78 | 79 | def iis_version 80 | if @iis_version.nil? 81 | version_string = Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\InetStp').read('VersionString')[1] 82 | version_string.slice! 'Version ' 83 | @iis_version = version_string 84 | end 85 | @iis_version.to_f 86 | end 87 | 88 | def locate_sysnative_cmd(cmd) 89 | if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\#{cmd}") 90 | "#{ENV['WINDIR']}\\sysnative\\#{cmd}" 91 | elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\#{cmd}") 92 | "#{ENV['WINDIR']}\\system32\\#{cmd}" 93 | else 94 | cmd 95 | end 96 | end 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /libraries/processors.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Library:: processors 4 | # 5 | # Copyright:: 2017-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | module IISCookbook 21 | # Contains functions that are used throughout this cookbook 22 | module Processors 23 | def current_default_documents_config(specifier = '') 24 | cmd = shell_out! get_default_documents_command specifier 25 | return unless cmd.stderr.empty? 26 | xml = cmd.stdout 27 | doc = REXML::Document.new xml 28 | 29 | { 30 | default_documents_enabled: value(doc.root, 'CONFIG/system.webServer-defaultDocument/@enabled'), 31 | default_documents: REXML::XPath.match(doc.root, 'CONFIG/system.webServer-defaultDocument/files/add/@value').map(&:value), 32 | } 33 | end 34 | 35 | def current_mime_maps_config(specifier = '') 36 | # handles mime maps 37 | cmd = shell_out! get_mime_map_command specifier 38 | return unless cmd.stderr.empty? 39 | xml = cmd.stdout 40 | doc = REXML::Document.new xml 41 | 42 | REXML::XPath.match(doc.root, 'CONFIG/system.webServer-staticContent/mimeMap').map { |x| "fileExtension='#{x.attribute 'fileExtension'}',mimeType='#{x.attribute 'mimeType'}'" } 43 | end 44 | 45 | def set_default_documents_enabled(value, specifier = '') 46 | cmd = default_documents_command specifier 47 | cmd << " /enabled:#{value}" 48 | shell_out! cmd 49 | end 50 | 51 | def set_default_documents(desired_default_documents, current_default_documents, add = true, remove = true, specifier = '') 52 | cmd = default_documents_command specifier 53 | Chef::Log.warn("new #{desired_default_documents} --- old #{current_default_documents}") 54 | if add 55 | (desired_default_documents - current_default_documents).each do |document| 56 | cmd << " /+files.[value='#{document}']" 57 | end 58 | end 59 | if remove && !add 60 | (desired_default_documents - current_default_documents).each do |document| 61 | cmd << " /-files.[value='#{document}']" 62 | end 63 | end 64 | if remove && add 65 | (current_default_documents - desired_default_documents).each do |document| 66 | cmd << " /-files.[value='#{document}']" 67 | end 68 | end 69 | 70 | Chef::Log.warn("before cmd -- #{cmd}") 71 | 72 | return unless cmd != default_documents_command(specifier) 73 | Chef::Log.warn("after cmd -- #{cmd}") 74 | shell_out! cmd 75 | end 76 | 77 | def set_mime_maps(desired_mime_maps, current_mime_maps, add = true, remove = true, specifier = '') 78 | cmd = mime_map_command specifier 79 | 80 | if add 81 | (desired_mime_maps - current_mime_maps).each do |mime_map| 82 | cmd << " /+\"[#{mime_map}]\"" 83 | end 84 | end 85 | if remove && !add 86 | (desired_mime_maps - current_mime_maps).each do |mime_map| 87 | cmd << " /-\"[#{mime_map}]\"" 88 | end 89 | end 90 | if remove && add 91 | (current_mime_maps - desired_mime_maps).each do |mime_map| 92 | cmd << " /-\"[#{mime_map}]\"" 93 | end 94 | end 95 | 96 | return unless cmd != mime_map_command(specifier) 97 | shell_out! cmd 98 | end 99 | 100 | private 101 | 102 | def get_default_documents_command(specifier = '') 103 | "#{appcmd(node)} list config #{specifier} /section:defaultDocument /config:* /xml" 104 | end 105 | 106 | def default_documents_command(specifier = '') 107 | "#{appcmd(node)} set config #{specifier} /section:defaultDocument" 108 | end 109 | 110 | def get_mime_map_command(specifier = '') 111 | "#{appcmd(node)} list config #{specifier} /section:staticContent /config:* /xml" 112 | end 113 | 114 | def mime_map_command(specifier = '') 115 | "#{appcmd(node)} set config #{specifier} /section:staticContent" 116 | end 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /libraries/section_helper.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Library:: section-helper 4 | # 5 | # Copyright:: 2017-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | module IISCookbook 21 | # Contains functions that are used throughout this cookbook 22 | module SectionHelper 23 | require 'rexml/document' 24 | include REXML 25 | 26 | def lock(node, section, location = '', returns = [0]) 27 | cmd_list_section node, :lock, section, location, returns 28 | end 29 | 30 | def unlock(node, section, location = '', returns = [0]) 31 | cmd_list_section node, :unlock, section, location, returns 32 | end 33 | 34 | def override_mode(node, action, section, location = '', returns = [0]) 35 | cmd_list_section(node, action, section, location, returns) 36 | end 37 | 38 | def get_current_lock(node, section, location = '') 39 | command_path = 'MACHINE/WEBROOT/APPHOST' 40 | command_path << "/#{location}" if location 41 | cmd = "#{appcmd(node)} list config \"#{command_path}}\"" 42 | cmd << " -section:#{section} -commit:apphost /config:* /xml" 43 | result = shell_out cmd 44 | if result.stderr.empty? 45 | xml = result.stdout 46 | doc = Document.new xml 47 | value(doc.root, 'CONFIG/@overrideMode') 48 | else 49 | Chef::Log.info(result.stderr) 50 | end 51 | 52 | nil 53 | end 54 | 55 | def cmd_section(node, check, section, location, returns) 56 | cmd = "#{appcmd(node)} set config \"MACHINE/WEBROOT/APPHOST/#{location}\"" 57 | cmd << " -section:\"#{section}\" -overrideMode:#{check}" 58 | cmd << ' -commit:apphost' 59 | Chef::Log.debug(cmd) 60 | shell_out!(cmd, returns: returns) 61 | 62 | return unless location 63 | cmd = "#{appcmd(node)} set config \"MACHINE/WEBROOT/APPHOST/#{location}\"" 64 | cmd << " -section:\"#{section}\" -overrideMode:#{check}" 65 | Chef::Log.debug(cmd) 66 | shell_out!(cmd, returns: returns) 67 | end 68 | 69 | def cmd_list_section(node, action, section, location, returns) 70 | current_lock = get_current_lock(node, section, location) 71 | check = action if action == 'Inherit' 72 | check = (action == :lock ? 'Deny' : 'Allow') if action != 'Inherit' 73 | 74 | cmd_section node, check, section, location, returns unless current_lock == check 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'iis' 2 | maintainer 'Sous Chefs' 3 | maintainer_email 'help@sous-chefs.org' 4 | license 'Apache-2.0' 5 | description 'Installs/Configures Windows IIS' 6 | source_url 'https://github.com/sous-chefs/iis' 7 | issues_url 'https://github.com/sous-chefs/iis/issues' 8 | chef_version '>= 15.3' 9 | version '8.2.6' 10 | 11 | supports 'windows' 12 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: default 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS' do 22 | additional_components node['iis']['components'] 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_application_initialization.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_application_initialization 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, ApplicationInit' do 22 | additional_components 'IIS-ApplicationInit' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_aspnet.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_aspnet 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, ASPNET' do 22 | additional_components %w(IIS-NetFxExtensibility IIS-ASPNET) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | 28 | include_recipe 'iis::mod_isapi' 29 | -------------------------------------------------------------------------------- /recipes/mod_aspnet45.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Blair Hamilton () 3 | # Cookbook:: iis 4 | # Recipe:: mod_aspnet45 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, ASPNET45' do 22 | additional_components %w(NetFx4Extended-ASPNET45 IIS-NetFxExtensibility45 IIS-ASPNET45) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | 28 | include_recipe 'iis::mod_isapi' 29 | -------------------------------------------------------------------------------- /recipes/mod_auth_anonymous.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Justin Schuhmann 3 | # Cookbook:: iis 4 | # Recipe:: mod_auth_basic 5 | # 6 | # Copyright:: 2016, Justin Schuhmann 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS' do 22 | source node['iis']['source'] 23 | install_method node['iis']['windows_feature_install_method'] 24 | start_iis true 25 | end 26 | 27 | iis_section 'unlocks anonymous authentication control in web.config' do 28 | section 'system.webServer/security/authentication/anonymousAuthentication' 29 | action :unlock 30 | end 31 | -------------------------------------------------------------------------------- /recipes/mod_auth_basic.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_auth_basic 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, BasicAuth' do 22 | additional_components 'IIS-BasicAuthentication' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | 28 | iis_section 'unlocks basic authentication control in web.config' do 29 | section 'system.webServer/security/authentication/basicAuthentication' 30 | action :unlock 31 | end 32 | -------------------------------------------------------------------------------- /recipes/mod_auth_digest.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Justin Schuhmann 3 | # Cookbook:: iis 4 | # Recipe:: mod_auth_basic 5 | # 6 | # Copyright:: 2016, Justin Schuhmann 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, DigestAuth' do 22 | additional_components 'IIS-DigestAuthentication' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | 28 | iis_section 'unlocks digest authentication control in web.config' do 29 | section 'system.webServer/security/authentication/digestAuthentication' 30 | action :unlock 31 | end 32 | -------------------------------------------------------------------------------- /recipes/mod_auth_windows.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_auth_windows 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, WindowsAuth' do 22 | additional_components 'IIS-WindowsAuthentication' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | 28 | iis_section 'unlocks windows authentication control in web.config' do 29 | section 'system.webServer/security/authentication/windowsAuthentication' 30 | action :unlock 31 | end 32 | -------------------------------------------------------------------------------- /recipes/mod_cgi.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Richard Downer () 3 | # Cookbook:: iis 4 | # Recipe:: mod_cgi 5 | # 6 | # Copyright:: 2013-2016, Cloudsoft Corporation 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, CGI' do 22 | additional_components 'IIS-CGI' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_compress_dynamic.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_compress_dynamic 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, HttpCompressionDynamic' do 22 | additional_components 'IIS-HttpCompressionDynamic' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_compress_static.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_compress_static 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, HttpCompressionStatic' do 22 | additional_components 'IIS-HttpCompressionStatic' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_ftp.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Kevin Rivers () 3 | # Cookbook:: iis 4 | # Recipe:: mod_ftp 5 | # 6 | # Copyright:: 2014-2016, Kevin Rivers 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, FTP' do 22 | additional_components %w(IIS-FTPServer IIS-FTPSvc IIS-FTPExtensibility) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_iis6_metabase_compat.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Kristian Vlaardingerbroek () 3 | # Cookbook:: iis 4 | # Recipe:: mod_iis6_metabase_compat 5 | # 6 | # Copyright:: 2013-2016, Schuberg Philis B.V. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, Compatability, Metabase' do 22 | additional_components %w(IIS-IIS6ManagementCompatibility IIS-Metabase) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_isapi.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_isapi 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, ISAPI' do 22 | additional_components %w(IIS-ISAPIFilter IIS-ISAPIExtensions) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_logging.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_logging 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, CustomLogging' do 22 | additional_components 'IIS-CustomLogging' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_management.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_management 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, Management' do 22 | additional_components %w(IIS-ManagementConsole IIS-ManagementService) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_security.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_security 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, Security' do 22 | additional_components %w(IIS-URLAuthorization IIS-RequestFiltering IIS-IPSecurity) 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/mod_tracing.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Seth Chisamore () 3 | # Cookbook:: iis 4 | # Recipe:: mod_diagnostics 5 | # 6 | # Copyright:: 2011-2019, Chef Software, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_install 'install IIS, Tracing' do 22 | additional_components 'IIS-HttpTracing' 23 | source node['iis']['source'] 24 | install_method node['iis']['windows_feature_install_method'] 25 | start_iis true 26 | end 27 | -------------------------------------------------------------------------------- /recipes/remove_default_site.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Kendrick Martin () 3 | # Cookbook:: iis 4 | # Recipe:: remove_default_site 5 | # 6 | # Copyright:: 2012-2018, Webtrends, Inc. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | iis_site 'Default Web Site' do 22 | action [:stop, :delete] 23 | end 24 | 25 | iis_pool 'DefaultAppPool' do 26 | action [:stop, :delete] 27 | end 28 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:base"], 4 | "packageRules": [ 5 | { 6 | "groupName": "Actions", 7 | "matchUpdateTypes": ["minor", "patch", "pin"], 8 | "automerge": true, 9 | "addLabels": ["Release: Patch", "Skip: Announcements"] 10 | }, 11 | { 12 | "groupName": "Actions", 13 | "matchUpdateTypes": ["major"], 14 | "automerge": false, 15 | "addLabels": ["Release: Patch", "Skip: Announcements"] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /resources/app.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: app 4 | # 5 | # Copyright:: 2011-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | require 'rexml/document' 23 | 24 | include REXML 25 | include IISCookbook::Helper 26 | 27 | property :site_name, String, name_property: true 28 | property :path, String, default: '/' 29 | property :application_pool, String 30 | property :physical_path, String 31 | property :enabled_protocols, String 32 | 33 | load_current_value do |desired| 34 | site_name desired.site_name 35 | # Sanitize physical path 36 | desired.physical_path = windows_cleanpath(desired.physical_path) if desired.physical_path 37 | cmd = shell_out("#{appcmd(node)} list app \"#{desired.site_name}#{desired.path}\"") 38 | Chef::Log.debug("#{appcmd(node)} list app command output: #{cmd.stdout}") 39 | if cmd.stderr.empty? 40 | Chef::Log.debug('Running regex') 41 | regex = /^APP\s\"#{desired.site_name}#{desired.path}\"/ 42 | result = cmd.stdout.match(regex) 43 | Chef::Log.debug("#{desired} current_resource match output: #{result}") 44 | if !result.nil? 45 | cmd_current_values = "#{appcmd(node)} list app \"#{desired.site_name}#{desired.path}\" /config:* /xml" 46 | Chef::Log.debug(cmd_current_values) 47 | cmd_current_values = shell_out(cmd_current_values) 48 | if cmd_current_values.stderr.empty? 49 | xml = cmd_current_values.stdout 50 | doc = Document.new(xml) 51 | path value doc.root, 'APP/application/@path' 52 | application_pool value doc.root, 'APP/application/@applicationPool' 53 | enabled_protocols value doc.root, 'APP/application/@enabledProtocols' 54 | physical_path windows_cleanpath(value(doc.root, 'APP/application/virtualDirectory/@physicalPath')) 55 | end 56 | else 57 | path '' 58 | end 59 | else 60 | Chef::Log.warn "Failed to run iis_app action :load_current_resource, #{cmd_current_values.stderr}" 61 | end 62 | end 63 | 64 | action :add do 65 | if exists 66 | Chef::Log.debug("#{new_resource.inspect} app already exists - nothing to do") 67 | else 68 | converge_by "Creating the Application - \"#{new_resource}\"" do 69 | cmd = "#{appcmd(node)} add app /site.name:\"#{new_resource.site_name}\"" 70 | cmd << " /path:\"#{new_resource.path}\"" 71 | cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool 72 | cmd << " /physicalPath:\"#{new_resource.physical_path}\"" if new_resource.physical_path 73 | cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols 74 | cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' 75 | Chef::Log.debug(cmd) 76 | shell_out!(cmd) 77 | end 78 | end 79 | end 80 | 81 | action :config do 82 | if exists 83 | # only get the beginning of the command if there is something that changes 84 | cmd = cmd_set_app 85 | converge_if_changed :path do 86 | # adds path to the cmd 87 | cmd << " /path:\"#{new_resource.path}\"" if new_resource.path 88 | end 89 | converge_if_changed :application_pool do 90 | # adds applicationPool to the cmd 91 | cmd << " /applicationPool:\"#{new_resource.application_pool}\"" if new_resource.application_pool 92 | end 93 | converge_if_changed :enabled_protocols do 94 | # adds enabledProtocols to the cmd 95 | cmd << " /enabledProtocols:\"#{new_resource.enabled_protocols}\"" if new_resource.enabled_protocols 96 | end 97 | Chef::Log.debug(cmd) 98 | 99 | if cmd == cmd_set_app 100 | Chef::Log.debug("#{new_resource.inspect} application - nothing to do") 101 | else 102 | converge_by "Updating the Application - \"#{new_resource}\"" do 103 | shell_out!(cmd) 104 | end 105 | end 106 | 107 | converge_if_changed :physical_path do 108 | cmd = "#{appcmd(node)} set vdir /vdir.name:\"#{vdir_identifier}\"" 109 | cmd << " /physicalPath:\"#{new_resource.physical_path}\"" 110 | Chef::Log.debug(cmd) 111 | shell_out!(cmd) 112 | end 113 | else 114 | Chef::Log.debug("#{new_resource.inspect} app needs to be added - cannot configure non-existent items") 115 | end 116 | end 117 | 118 | action :delete do 119 | if exists 120 | converge_by "Deleting the Application - \"#{new_resource}\"" do 121 | shell_out!("#{appcmd(node)} delete app \"#{site_identifier}\"") 122 | Chef::Log.info("#{new_resource} deleted") 123 | end 124 | else 125 | Chef::Log.debug("#{new_resource.inspect} app does not exist - nothing to do") 126 | end 127 | end 128 | 129 | action_class do 130 | def exists 131 | !current_resource.path.empty? 132 | end 133 | 134 | def cmd_set_app 135 | "#{appcmd(node)} set app \"#{site_identifier}\"" 136 | end 137 | 138 | def site_identifier 139 | "#{new_resource.site_name}#{new_resource.path}" 140 | end 141 | 142 | # Ensure VDIR identifier has a trailing slash 143 | def vdir_identifier 144 | site_identifier.end_with?('/') ? site_identifier : site_identifier + '/' 145 | end 146 | end 147 | -------------------------------------------------------------------------------- /resources/certificate_binding.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Richard Lavey (richard.lavey@calastone.com) 3 | # Cookbook:: windows 4 | # Resource:: certificate_binding 5 | # 6 | # Copyright:: 2015-2017, Calastone Ltd. 7 | # Copyright:: 2018, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | unified_mode true 23 | 24 | property :cert_name, String, name_property: true 25 | property :name_kind, Symbol, equal_to: [:hash, :subject], default: :subject 26 | property :address, String, default: '0.0.0.0' 27 | property :port, Integer, default: 443 28 | property :app_id, String, default: '{4dc3e181-e14b-4a21-b022-59fc669b0914}' 29 | property :store_name, String, default: 'MY', equal_to: ['TRUSTEDPUBLISHER', 'CLIENTAUTHISSUER', 'REMOTE DESKTOP', 'ROOT', 'TRUSTEDDEVICES', 'WEBHOSTING', 'CA', 'AUTHROOT', 'TRUSTEDPEOPLE', 'MY', 'SMARTCARDROOT', 'TRUST'] 30 | property :exists, [true, false] 31 | 32 | load_current_value do |desired| 33 | cmd = shell_out("#{netsh_command} http show sslcert #{address_mode(desired.address)}=#{desired.address}:#{desired.port}") 34 | Chef::Log.debug "netsh reports: #{cmd.stdout}" 35 | 36 | address desired.address 37 | port desired.port 38 | store_name desired.store_name 39 | app_id desired.app_id 40 | 41 | if cmd.exitstatus == 0 42 | m = cmd.stdout.scan(/Certificate Hash\s+:\s?([A-Fa-f0-9]{40})/) 43 | raise "Failed to extract hash from command output #{cmd.stdout}" if m.empty? 44 | cert_name m[0][0] 45 | name_kind :hash 46 | exists true 47 | else 48 | exists false 49 | end 50 | end 51 | 52 | def address_mode(address) 53 | address.match(/(\d+\.){3}\d+|\[.+\]/).nil? ? 'hostnameport' : 'ipport' 54 | end 55 | 56 | def netsh_command 57 | # account for Window's wacky File System Redirector 58 | # http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx 59 | # especially important for 32-bit processes (like Ruby) on a 60 | # 64-bit instance of Windows. 61 | if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\netsh.exe") 62 | "#{ENV['WINDIR']}\\sysnative\\netsh.exe" 63 | elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\netsh.exe") 64 | "#{ENV['WINDIR']}\\system32\\netsh.exe" 65 | else 66 | 'netsh.exe' 67 | end 68 | end 69 | 70 | action :create do 71 | hash = new_resource.name_kind == :subject ? hash_from_subject : new_resource.cert_name 72 | 73 | if current_resource.exists 74 | needs_change = (hash.casecmp(current_resource.cert_name) != 0) 75 | 76 | if needs_change 77 | converge_by("Changing #{current_resource.address}:#{current_resource.port}") do 78 | delete_binding 79 | add_binding hash 80 | end 81 | else 82 | Chef::Log.debug("#{new_resource.address}:#{new_resource.port} already bound to #{hash} - nothing to do") 83 | end 84 | else 85 | converge_by("Binding #{new_resource.address}:#{new_resource.port}") do 86 | add_binding hash 87 | end 88 | end 89 | end 90 | 91 | action :delete do 92 | if current_resource.exists 93 | converge_by("Deleting #{current_resource.address}:#{current_resource.port}") do 94 | delete_binding 95 | end 96 | else 97 | Chef::Log.debug("#{current_resource.address}:#{current_resource.port} not bound - nothing to do") 98 | end 99 | end 100 | 101 | action_class do 102 | def add_binding(hash) 103 | cmd = "#{netsh_command} http add sslcert" 104 | mode = address_mode(current_resource.address) 105 | cmd << " #{mode}=#{current_resource.address}:#{current_resource.port}" 106 | cmd << " certhash=#{hash}" 107 | cmd << " appid=\"#{current_resource.app_id}\"" 108 | cmd << " certstorename=#{current_resource.store_name}" 109 | check_hash hash 110 | 111 | shell_out!(cmd) 112 | end 113 | 114 | def delete_binding 115 | mode = address_mode(current_resource.address) 116 | shell_out!("#{netsh_command} http delete sslcert #{mode}=#{current_resource.address}:#{current_resource.port}") 117 | end 118 | 119 | def check_hash(hash) 120 | p = powershell_out!("Test-Path \"cert:\\LocalMachine\\#{current_resource.store_name}\\#{hash}\"") 121 | 122 | unless p.stderr.empty? && p.stdout =~ /True/i 123 | raise "A Cert with hash of #{hash} doesn't exist in keystore LocalMachine\\#{current_resource.store_name}" 124 | end 125 | nil 126 | end 127 | 128 | def hash_from_subject 129 | # escape wildcard subject name (*.acme.com) 130 | subject = new_resource.cert_name.sub(/\*/, '`*') 131 | ps_script = "& { gci cert:\\localmachine\\#{new_resource.store_name} | where { $_.subject -like '*#{subject}*' } | select -first 1 -expandproperty Thumbprint }" 132 | 133 | Chef::Log.debug "Running PS script #{ps_script}" 134 | p = powershell_out!(ps_script) 135 | 136 | raise "#{ps_script} failed with #{p.stderr}" if p.error? 137 | raise "Couldn't find thumbprint for subject #{new_resource.cert_name}" if p.stdout.nil? || p.stdout.empty? 138 | 139 | # seem to get a UTF-8 string with BOM returned sometimes! Strip any such BOM 140 | hash = p.stdout.strip 141 | hash[0].ord == 239 ? hash.force_encoding('UTF-8').delete!("\xEF\xBB\xBF".force_encoding('UTF-8')) : hash 142 | end 143 | end 144 | -------------------------------------------------------------------------------- /resources/config.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: config 4 | # 5 | # Copyright:: 2017-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | include IISCookbook::Helper 23 | include IISCookbook::Processors 24 | 25 | property :cfg_cmd, String, name_property: true 26 | property :returns, [Integer, Array], default: 0 27 | 28 | action :set do 29 | config 30 | end 31 | 32 | action :clear do 33 | config(:clear) 34 | end 35 | 36 | action_class do 37 | def config(action = :set) 38 | converge_by "Executing IIS Config #{action}" do 39 | cmd = "#{appcmd(node)} #{action} config #{new_resource.cfg_cmd}" 40 | Chef::Log.debug(cmd) 41 | shell_out!(cmd, returns: new_resource.returns) 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /resources/config_property.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: config_property 4 | # 5 | # Copyright:: 2018, Calastone Ltd. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # Configures an IIS property (using powershell for idempotence) 20 | 21 | unified_mode true 22 | 23 | property :property, String, name_property: true 24 | property :ps_path, String, required: true 25 | property :location, String 26 | property :filter, String, required: true 27 | property :value, [String, Integer], required: true 28 | property :extra_add_values, Hash 29 | 30 | action :set do 31 | location_param = "-location \"#{new_resource.location}\"" if 32 | property_is_set?(:location) 33 | 34 | # powershell doesn't like { or } in xpath values (e.g. server variables) 35 | escaped_filter = new_resource.filter.gsub('{', '{{').gsub('}', '}}') 36 | 37 | property_value = if new_resource.value.is_a?(Integer) 38 | new_resource.value.to_s 39 | else 40 | "\"#{new_resource.value}\"" 41 | end 42 | powershell_script "Set #{new_resource.ps_path}#{new_resource.location}\ 43 | /#{escaped_filter}/#{new_resource.property}" do 44 | code <<-EOH 45 | Set-WebConfigurationProperty -pspath "#{new_resource.ps_path}" \ 46 | #{location_param} -filter "#{escaped_filter}" \ 47 | -name "#{new_resource.property}" \ 48 | -value #{property_value} -ErrorAction Stop 49 | EOH 50 | only_if <<-EOH 51 | (Get-WebConfigurationProperty -pspath "#{new_resource.ps_path}" \ 52 | #{location_param} -filter "#{escaped_filter}" \ 53 | -name "#{new_resource.property}" -ErrorAction Stop) -ne #{property_value} 54 | EOH 55 | end 56 | end 57 | 58 | action :add do 59 | location_param = "-location \"#{new_resource.location}\"" if 60 | property_is_set?(:location) 61 | 62 | # powershell doesn't like { or } in xpath values (e.g. server variables) 63 | escaped_value = new_resource.value.gsub('{', '{{').gsub('}', '}}') 64 | escaped_filter = new_resource.filter.gsub('{', '{{').gsub('}', '}}') 65 | extra_values = new_resource.extra_add_values.map do |n, v| 66 | property_value = if v.is_a?(Integer) 67 | v.to_s 68 | else 69 | "'#{v}'" 70 | end 71 | "#{n} = #{property_value}" 72 | end.join(';') if property_is_set?(:extra_add_values) 73 | 74 | powershell_script "Set #{new_resource.ps_path}#{new_resource.location}\ 75 | /#{escaped_filter}/#{new_resource.property}" do 76 | code <<-EOH 77 | Add-WebConfigurationProperty -pspath "#{new_resource.ps_path}" \ 78 | #{location_param} -filter "#{escaped_filter}" \ 79 | -name "." -value @{ #{new_resource.property} = '#{new_resource.value}'; #{extra_values} } \ 80 | -ErrorAction Stop 81 | EOH 82 | only_if <<-EOH 83 | (Get-WebConfiguration -pspath "#{new_resource.ps_path}" #{location_param} \ 84 | -filter "#{escaped_filter}/*[@#{new_resource.property}='#{escaped_value}']" \ 85 | -ErrorAction Stop) -eq $null 86 | EOH 87 | end 88 | end 89 | 90 | action :remove do 91 | location_param = "-location \"#{new_resource.location}\"" if 92 | property_is_set?(:location) 93 | 94 | # powershell doesn't like { or } in xpath values (e.g. server variables) 95 | escaped_value = new_resource.value.gsub('{', '{{').gsub('}', '}}') 96 | escaped_filter = new_resource.filter.gsub('{', '{{').gsub('}', '}}') 97 | 98 | powershell_script "Set #{new_resource.ps_path}#{new_resource.location}\ 99 | /#{escaped_filter}/#{new_resource.property}" do 100 | code <<-EOH 101 | Remove-WebConfigurationProperty -pspath "#{new_resource.ps_path}" \ 102 | #{location_param} -filter "#{escaped_filter}" \ 103 | -name "." -AtElement @{ #{new_resource.property} = \ 104 | '#{new_resource.value}'; } -ErrorAction Stop 105 | EOH 106 | only_if <<-EOH 107 | (Get-WebConfiguration -pspath "#{new_resource.ps_path}" #{location_param} \ 108 | -filter "#{escaped_filter}/*[@#{new_resource.property}='#{escaped_value}']" \ 109 | -ErrorAction Stop) -ne $null 110 | EOH 111 | end 112 | end 113 | -------------------------------------------------------------------------------- /resources/http_acl.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Richard Lavey (richard.lavey@calastone.com) 3 | # Cookbook:: windows 4 | # Resource:: http_acl 5 | # 6 | # Copyright:: 2015-2017, Calastone Ltd. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | unified_mode true 22 | 23 | include IISCookbook::Helper 24 | 25 | property :url, String, name_property: true 26 | property :user, String 27 | property :sddl, String 28 | property :exists, [true, false] 29 | 30 | # See https://msdn.microsoft.com/en-us/library/windows/desktop/cc307236%28v=vs.85%29.aspx for netsh info 31 | 32 | load_current_value do |desired| 33 | cmd_out = shell_out!("#{locate_sysnative_cmd('netsh.exe')} http show urlacl url=#{desired.url}").stdout 34 | Chef::Log.debug "netsh reports: #{cmd_out}" 35 | 36 | if cmd_out.include? desired.url 37 | exists true 38 | url desired.url 39 | # Checks first for sddl, because it generates user(s) 40 | sddl_match = cmd_out.match(/SDDL:\s*(?\S+)/) 41 | if sddl_match 42 | sddl sddl_match['sddl'] 43 | else 44 | # if no sddl, tries to find a single user 45 | user_match = cmd_out.match(/User:\s*(?.+)/) 46 | user user_match['user'] 47 | end 48 | else 49 | exists false 50 | end 51 | end 52 | 53 | action :create do 54 | raise '`user` xor `sddl` can\'t be used together' if new_resource.user && new_resource.sddl 55 | raise 'When provided user property can\'t be empty' if new_resource.user && new_resource.user.empty? 56 | raise 'When provided sddl property can\'t be empty' if new_resource.sddl && new_resource.sddl.empty? 57 | 58 | if current_resource.exists 59 | sddl_changed = ( 60 | new_resource.sddl && 61 | current_resource.sddl && 62 | current_resource.sddl.casecmp(new_resource.sddl) != 0 63 | ) 64 | user_changed = ( 65 | new_resource.user && 66 | current_resource.user && 67 | current_resource.user.casecmp(new_resource.user) != 0 68 | ) 69 | 70 | if sddl_changed || user_changed 71 | converge_by("Changing #{new_resource.url}") do 72 | delete_acl 73 | apply_acl 74 | end 75 | else 76 | Chef::Log.debug("#{new_resource.url} already set - nothing to do") 77 | end 78 | else 79 | converge_by("Setting #{new_resource.url}") do 80 | apply_acl 81 | end 82 | end 83 | end 84 | 85 | action :delete do 86 | if current_resource.exists 87 | converge_by("Deleting #{new_resource.url}") do 88 | delete_acl 89 | end 90 | else 91 | Chef::Log.debug("#{new_resource.url} does not exist - nothing to do") 92 | end 93 | end 94 | 95 | action_class do 96 | def netsh_command 97 | locate_sysnative_cmd('netsh.exe') 98 | end 99 | 100 | def apply_acl 101 | if current_resource.sddl 102 | shell_out!("#{netsh_command} http add urlacl url=#{new_resource.url} sddl=\"#{new_resource.sddl}\"") 103 | else 104 | shell_out!("#{netsh_command} http add urlacl url=#{new_resource.url} user=\"#{new_resource.user}\"") 105 | end 106 | end 107 | 108 | def delete_acl 109 | shell_out!("#{netsh_command} http delete urlacl url=#{new_resource.url}") 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /resources/install.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: install 4 | # 5 | # Copyright:: 2018-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | include IISCookbook::Helper 23 | 24 | property :source, String 25 | property :additional_components, [Array, String], 26 | coerce: proc { |c| Array(c) }, 27 | default: [] 28 | property :install_method, [String, Symbol], 29 | required: false, 30 | coerce: proc { |i| i.to_sym }, 31 | equal_to: [:windows_feature_dism, :windows_feature_powershell, :windows_feature_servermanagercmd], 32 | default: :windows_feature_dism 33 | property :start_iis, [true, false], default: false 34 | 35 | action :install do 36 | features = ['IIS-WebServerRole'].concat(new_resource.additional_components) 37 | 38 | features_to_install = if new_resource.install_method == :windows_feature_powershell 39 | powershell_feature_name(features) 40 | else 41 | features 42 | end 43 | 44 | windows_feature 'Install IIS and additional components' do 45 | feature_name features_to_install 46 | action :install 47 | all !IISCookbook::Helper.older_than_windows2012? 48 | source new_resource.source unless new_resource.source.nil? 49 | install_method new_resource.install_method 50 | end 51 | 52 | service 'iis' do 53 | service_name 'W3SVC' 54 | action [:enable, :start] 55 | only_if { new_resource.start_iis } 56 | end 57 | end 58 | 59 | action_class do 60 | def powershell_feature_name(names) 61 | Array(names).map do |name| 62 | # This will search for the powershell format (Name) of the feature name, by the both the install name or Name, meaning 63 | # that it doesnt care if you pass the powershell format or dism format, it will return the powershell format 64 | cmd = "Get-WindowsFeature | Where-Object {$_.AdditionalInfo.InstallName -Eq '#{name}' -or $_.Name -eq '#{name}'} | Select -Expand Name" 65 | result = powershell_out cmd 66 | if result.stderr.to_s.empty? 67 | next result.stdout.strip 68 | else 69 | Chef::Log.error(result.stderr) 70 | raise "Unable to translate feature #{name}" 71 | end 72 | end 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /resources/manager.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Jason Field 3 | # Cookbook:: iis 4 | # Resource:: manager 5 | # 6 | # Copyright:: 2018, Calastone Ltd. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | # Configures IIS Manager 21 | 22 | unified_mode true 23 | 24 | property :enable_remote_management, [true, false], default: true 25 | property :log_directory, String 26 | property :port, Integer, default: 8172 27 | property :install_method, [Symbol, String], 28 | required: false, 29 | coerce: proc { |m| m.to_sym }, 30 | equal_to: [:windows_feature_dism, :windows_feature_powershell, :windows_feature_servermanagercmd], 31 | default: :windows_feature_dism 32 | 33 | action :config do 34 | iis_install 'Web-Mgmt-Service' do 35 | additional_components ['IIS-ManagementService'] 36 | install_method new_resource.install_method 37 | start_iis false 38 | end 39 | 40 | # properties stored in the registry 41 | reg_values = [{ 42 | name: 'EnableRemoteManagement', 43 | type: :dword, 44 | data: new_resource.enable_remote_management ? 1 : 0, 45 | }, { 46 | name: 'Port', 47 | type: :dword, 48 | data: new_resource.port, 49 | }] 50 | 51 | if property_is_set?(:log_directory) 52 | directory new_resource.log_directory do 53 | recursive true 54 | end 55 | 56 | reg_values.push( 57 | name: 'LoggingDirectory', 58 | type: :string, 59 | data: new_resource.log_directory 60 | ) 61 | end 62 | 63 | registry_key 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WebManagement\Server' do 64 | values reg_values 65 | notifies :restart, 'service[WMSVC]', :delayed 66 | end 67 | 68 | # if using a custom port then we need to allow the service account to listen on it 69 | if property_is_set?(:port) 70 | iis_http_acl "https://*:#{new_resource.port}/" do 71 | user 'NT SERVICE\WMSvc' 72 | end 73 | # WMSVC is the self signed cert auto generated by windows 74 | iis_certificate_binding 'WMSVC' do 75 | port new_resource.port 76 | app_id '{d7d72267-fcf9-4424-9eec-7e1d8dcec9a9}' 77 | end 78 | end 79 | 80 | service 'WMSVC' do 81 | action [:enable, :start] 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /resources/manager_permission.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Jason Field 3 | # Cookbook:: iis 4 | # Resource:: manager_permissions 5 | # 6 | # Copyright:: 2018, Calastone Ltd. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | # Grants access to IIS manager against a site or application 21 | 22 | unified_mode true 23 | 24 | property :config_path, String, name_property: true 25 | property :users, Array, default: [] 26 | property :groups, Array, default: [] 27 | 28 | action :config do 29 | # This only works on 2016 + servers, Server 2012r2 does not dispose 30 | # of com objects when called from a cmd style script for IIS User 31 | # https://serverfault.com/questions/587305/powershell-has-stopped-working-on-ps-exit-after-creating-iis-user 32 | if node['os_version'].to_f < 10.0 33 | Chef::Log.warn('IIS Manager Permission requires Windows 2016 or newer, Skipping') 34 | return 35 | end 36 | # user permissions are accessed by .Net API 37 | all_users = (new_resource.users + new_resource.groups).map { |i| "\"#{i}\"" }.join ',' 38 | 39 | unless new_resource.users.count == 0 40 | set_users = <<-EOH 41 | foreach ($principal in #{new_resource.users.map { |i| "\"#{i}\"" }.join ','}) 42 | { 43 | if (($current | Where-Object { $_.Name -eq $principal -and -not $_.IsRole }) -eq $null) 44 | { 45 | [Microsoft.Web.Management.Server.ManagementAuthorization]::Grant($principal, "#{new_resource.config_path}", $false) 46 | } 47 | } 48 | EOH 49 | end 50 | 51 | unless new_resource.groups.count == 0 52 | set_groups = <<-EOH 53 | foreach ($principal in #{new_resource.groups.map { |i| "\"#{i}\"" }.join ','}) 54 | { 55 | if (($current | Where-Object { $_.Name -eq $principal -and $_.IsRole }) -eq $null) 56 | { 57 | [Microsoft.Web.Management.Server.ManagementAuthorization]::Grant($principal, "#{new_resource.config_path}", $true) 58 | } 59 | } 60 | EOH 61 | end 62 | 63 | powershell_script "Set permissions for Path #{new_resource.config_path}" do 64 | code <<-EOH 65 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Management") | Out-Null 66 | $current = [Microsoft.Web.Management.Server.ManagementAuthorization]::GetAuthorizedUsers("#{new_resource.config_path}", $false, 0, 1000) 67 | 68 | #{set_users} 69 | #{set_groups} 70 | 71 | # Delete entries not in current definition 72 | $current | Where-Object { $_.Name -notin #{all_users} } | ` 73 | Foreach-Object { [Microsoft.Web.Management.Server.ManagementAuthorization]::Revoke($_.Name, "#{new_resource.config_path}") } 74 | EOH 75 | only_if <<-EOH 76 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Management") | Out-Null 77 | $current = [Microsoft.Web.Management.Server.ManagementAuthorization]::GetAuthorizedUsers("#{new_resource.config_path}", $false, 0, 1000) 78 | $current.Count -ne #{new_resource.users.count + new_resource.groups.count} -or ($current | Where-Object { $_.Name -in #{all_users} }).Count -ne #{new_resource.users.count + new_resource.groups.count} 79 | EOH 80 | notifies :restart, 'service[WMSVC]', :delayed 81 | end 82 | 83 | service 'WMSVC' do 84 | action :nothing 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /resources/module.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: module 4 | # 5 | # Copyright:: 2017-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | include IISCookbook::Helper 23 | include IISCookbook::Processors 24 | include IISCookbook::SectionHelper 25 | 26 | property :module_name, String, name_property: true 27 | property :type, String 28 | property :add, [true, false], default: false 29 | property :image, String 30 | property :precondition, String 31 | property :application, String 32 | property :previous_lock, String 33 | 34 | load_current_value do |desired| 35 | module_name desired.module_name 36 | application desired.application if desired.application 37 | # Sanitize Image Path (file system path) 38 | desired.image = windows_cleanpath(desired.image) if desired.image 39 | cmd = "#{appcmd(node)} list module /module.name:\"#{desired.module_name}\"" 40 | cmd << " /app.name:\"#{desired.application}\"" if desired.application 41 | 42 | cmd_result = shell_out cmd 43 | # 'MODULE "Module Name" ( type:module.type, preCondition:condition )' 44 | # 'MODULE "Module Name" ( native, preCondition:condition )' 45 | 46 | Chef::Log.debug("#{desired.name} list module command output: #{cmd_result.stdout}") 47 | unless cmd_result.stdout.empty? 48 | previous_lock get_current_lock(node, 'system.webServer/modules', desired.application) 49 | cmd = "#{appcmd(node)} list module /module.name:\"#{desired.module_name}\"" 50 | cmd << " /app.name:\"#{desired.application}\"" if desired.application 51 | cmd << ' /config:* /xml' 52 | cmd_result = shell_out cmd 53 | if cmd_result.stderr.empty? 54 | xml = cmd_result.stdout 55 | doc = Document.new(xml) 56 | type value doc.root, 'MODULE/@type' 57 | precondition value doc.root, 'MODULE/@preCondition' 58 | end 59 | end 60 | end 61 | 62 | # appcmd syntax for adding modules 63 | # appcmd add module /name:string /type:string /preCondition:string 64 | action :add do 65 | if exists 66 | Chef::Log.debug("#{new_resource} module already exists - nothing to do") 67 | else 68 | converge_by("add IIS module #{new_resource.module_name}") do 69 | unlock(node, 'system.webServer/modules', new_resource.application) 70 | cmd = "#{appcmd(node)} add module /module.name:\"#{new_resource.module_name}\"" 71 | cmd << " /app.name:\"#{new_resource.application}\"" if new_resource.application 72 | cmd << " /type:\"#{new_resource.type}\"" if new_resource.type 73 | cmd << " /preCondition:\"#{new_resource.precondition}\"" if new_resource.precondition 74 | 75 | shell_out!(cmd, returns: [0, 42]) 76 | override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) 77 | end 78 | end 79 | end 80 | 81 | action :delete do 82 | if exists 83 | converge_by("delete IIS module #{new_resource.module_name}") do 84 | unlock(node, 'system.webServer/modules', new_resource.application) 85 | cmd = "#{appcmd(node)} delete module /module.name:\"#{new_resource.module_name}\"" 86 | cmd << " /app.name:\"#{new_resource.application}\"" if new_resource.application 87 | 88 | shell_out!(cmd, returns: [0, 42]) 89 | override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) 90 | end 91 | else 92 | Chef::Log.debug("#{new_resource} module does not exist - nothing to do") 93 | end 94 | end 95 | 96 | # appcmd syntax for installing native modules 97 | # appcmd install module /name:string /add:string(true|false) /image:string 98 | action :install do 99 | if exists 100 | Chef::Log.debug("#{new_resource} module already exists - nothing to do") 101 | else 102 | converge_by("install IIS module #{new_resource.module_name}") do 103 | unlock(node, 'system.webServer/modules', new_resource.application) 104 | cmd = "#{appcmd(node)} install module /name:\"#{new_resource.module_name}\"" 105 | cmd << " /add:\"#{new_resource.add}\"" unless new_resource.add.nil? 106 | cmd << " /image:\"#{new_resource.image}\"" if new_resource.image 107 | cmd << " /preCondition:\"#{new_resource.precondition}\"" if new_resource.precondition 108 | 109 | shell_out!(cmd, returns: [0, 42]) 110 | override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) 111 | end 112 | end 113 | end 114 | 115 | # appcmd syntax for uninstalling native modules 116 | # appcmd uninstall module 117 | action :uninstall do 118 | if exists 119 | converge_by("uninstall IIS module #{new_resource.module_name}") do 120 | unlock(node, 'system.webServer/modules', new_resource.application) 121 | cmd = "#{appcmd(node)} uninstall module \"#{new_resource.module_name}\"" 122 | 123 | shell_out!(cmd, returns: [0, 42]) 124 | override_mode(node, current_resource.previous_lock, 'system.webServer/modules', new_resource.application) 125 | end 126 | else 127 | Chef::Log.debug("#{new_resource} module does not exists - nothing to do") 128 | end 129 | end 130 | 131 | action_class do 132 | def exists 133 | current_resource.type ? true : false 134 | end 135 | end 136 | -------------------------------------------------------------------------------- /resources/root.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: root 4 | # 5 | # Copyright:: 2017-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | include IISCookbook::Constants 23 | include IISCookbook::Helper 24 | include IISCookbook::Processors 25 | 26 | property :default_documents_enabled, [true, false], default: true 27 | property :default_documents, Array, default: IISCookbook::Constants.default_documents 28 | property :mime_maps, Array, default: IISCookbook::Constants.default_mime_types 29 | property :add_default_documents, Array, default: [] 30 | property :add_mime_maps, Array, default: [] 31 | property :delete_default_documents, Array, default: [] 32 | property :delete_mime_maps, Array, default: [] 33 | 34 | load_current_value do |desired| 35 | current_default_documents_object = current_default_documents_config 36 | return unless current_default_documents_object 37 | 38 | current_mime_maps = current_mime_maps_config 39 | return unless current_mime_maps_config 40 | 41 | default_documents_enabled bool(current_default_documents_object[:default_documents_enabled]) 42 | default_documents current_default_documents_object[:default_documents] 43 | mime_maps current_mime_maps 44 | 45 | current_add_default_documents = desired.add_default_documents - current_default_documents_object[:default_documents] 46 | add_default_documents desired.add_default_documents - current_add_default_documents 47 | 48 | delete_default_documents desired.delete_default_documents - current_default_documents_object[:default_documents] 49 | 50 | current_add_mime_maps = desired.add_mime_maps - current_mime_maps 51 | add_mime_maps desired.add_mime_maps - current_add_mime_maps 52 | 53 | delete_mime_maps desired.delete_mime_maps - current_mime_maps 54 | end 55 | 56 | action :config do 57 | converge_if_changed :default_documents_enabled do 58 | set_default_documents_enabled(new_resource.default_documents_enabled) 59 | end 60 | 61 | converge_if_changed :default_documents do 62 | set_default_documents(new_resource.default_documents, current_resource.default_documents) 63 | end 64 | 65 | converge_if_changed :mime_maps do 66 | set_mime_maps(new_resource.mime_maps, current_resource.mime_maps) 67 | end 68 | end 69 | 70 | action :add do 71 | converge_if_changed :add_default_documents do 72 | set_default_documents(new_resource.add_default_documents, current_resource.add_default_documents, true, false) 73 | end 74 | 75 | converge_if_changed :add_mime_maps do 76 | set_mime_maps(new_resource.add_mime_maps, current_resource.add_mime_maps, true, false) 77 | end 78 | end 79 | 80 | action :delete do 81 | converge_if_changed :delete_default_documents do 82 | set_default_documents(new_resource.delete_default_documents, current_resource.delete_default_documents, false, true) 83 | end 84 | 85 | converge_if_changed :delete_mime_maps do 86 | set_mime_maps(new_resource.delete_mime_maps, current_resource.delete_mime_maps, false, true) 87 | end 88 | end 89 | -------------------------------------------------------------------------------- /resources/section.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: section 4 | # 5 | # Copyright:: 2016-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | require 'rexml/document' 23 | 24 | include REXML 25 | include IISCookbook::Helper 26 | include IISCookbook::SectionHelper 27 | include IISCookbook::Processors 28 | 29 | property :section, String, name_property: true 30 | property :site, String 31 | property :application_path, String 32 | property :returns, [Integer, Array], default: 0 33 | property :locked, String 34 | 35 | load_current_value do |desired| 36 | section desired.section 37 | site desired.site 38 | application_path desired.application_path 39 | command_path = 'MACHINE/WEBROOT/APPHOST' 40 | command_path << "/#{site}" if site 41 | command_path << application_path.to_s if application_path 42 | cmd = "#{appcmd(node)} list config \"#{command_path}\"" 43 | cmd << " -section:\"#{section}\" /commit:apphost /config:* /xml" 44 | Chef::Log.debug(cmd) 45 | cmd = shell_out(cmd) 46 | if cmd.stderr.empty? 47 | xml = cmd.stdout 48 | doc = Document.new(xml) 49 | locked value doc.root, 'CONFIG/@overrideMode' 50 | else 51 | Chef::Log.info(cmd.stderr) 52 | end 53 | end 54 | 55 | action :unlock do 56 | if current_resource.locked != 'Allow' 57 | converge_by "Unlocking the section - \"#{new_resource}\"" do 58 | unlock node, new_resource.section, "#{new_resource.site}#{new_resource.application_path}", new_resource.returns 59 | end 60 | else 61 | Chef::Log.debug("#{new_resource} already unlocked - nothing to do") 62 | end 63 | end 64 | 65 | action :lock do 66 | if current_resource.locked != 'Deny' 67 | converge_by "Locking the section - \"#{new_resource}\"" do 68 | lock node, new_resource.section, "#{new_resource.site}#{new_resource.application_path}", new_resource.returns 69 | end 70 | else 71 | Chef::Log.debug("#{new_resource} already locked - nothing to do") 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /resources/vdir.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Resource:: vdir 4 | # 5 | # Copyright:: 2016-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | unified_mode true 21 | 22 | require 'rexml/document' 23 | 24 | include REXML 25 | include IISCookbook::Helper 26 | include IISCookbook::Processors 27 | 28 | property :application_name, String, name_property: true 29 | property :path, String 30 | property :physical_path, String 31 | property :username, String 32 | property :password, String, sensitive: true 33 | property :logon_method, [Symbol, String], default: :ClearText, equal_to: [:Interactive, :Batch, :Network, :ClearText], coerce: proc { |v| v.to_sym } 34 | property :allow_sub_dir_config, [true, false], default: true 35 | 36 | load_current_value do |desired| 37 | # Sanitize Application Name 38 | desired.application_name = application_cleanname(desired.application_name) 39 | # Sanitize Physical Path 40 | desired.physical_path = windows_cleanpath(desired.physical_path) if desired.physical_path 41 | application_name desired.application_name 42 | path desired.path 43 | cmd = shell_out("#{appcmd(node)} list vdir \"#{application_name.chomp('/') + path}\"") 44 | Chef::Log.debug("#{desired} list vdir command output: #{cmd.stdout}") 45 | 46 | if cmd.stderr.empty? 47 | # VDIR "Testfu Site/Content/Test" 48 | result = cmd.stdout.match(/^VDIR\s\"#{Regexp.escape(application_name.chomp('/') + path)}\"/) 49 | Chef::Log.debug("#{desired} current_resource match output: #{result}") 50 | unless result.nil? 51 | cmd = shell_out("#{appcmd(node)} list vdir \"#{application_name.chomp('/') + path}\" /config:* /xml") 52 | if cmd.stderr.empty? 53 | xml = cmd.stdout 54 | doc = Document.new(xml) 55 | physical_path windows_cleanpath(value(doc.root, 'VDIR/@physicalPath')) 56 | username value doc.root, 'VDIR/virtualDirectory/@userName' 57 | password value doc.root, 'VDIR/virtualDirectory/@password' 58 | logon_method value(doc.root, 'VDIR/virtualDirectory/@logonMethod').to_sym 59 | allow_sub_dir_config bool(value(doc.root, 'VDIR/virtualDirectory/@allowSubDirConfig')) 60 | end 61 | end 62 | else 63 | Chef::Log.warn "Failed to run iis_vdir action :load_current_resource, #{cmd.stderr}" 64 | end 65 | end 66 | 67 | action :add do 68 | if exists 69 | Chef::Log.debug("#{new_resource} virtual directory already exists - nothing to do") 70 | else 71 | converge_by "Created the VDIR - \"#{new_resource}\"" do 72 | cmd = "#{appcmd(node)} add vdir /app.name:\"#{vdir_identifier}\"" 73 | cmd << " /path:\"#{new_resource.path}\"" 74 | cmd << " /physicalPath:\"#{new_resource.physical_path}\"" 75 | cmd << " /userName:\"#{new_resource.username}\"" if new_resource.username 76 | cmd << " /password:\"#{new_resource.password}\"" if new_resource.password 77 | cmd << " /logonMethod:#{new_resource.logon_method}" if new_resource.logon_method 78 | cmd << " /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" if new_resource.allow_sub_dir_config 79 | cmd << ' /commit:\"MACHINE/WEBROOT/APPHOST\"' 80 | 81 | Chef::Log.debug(cmd) 82 | shell_out!(cmd, returns: [0, 42, 183]) 83 | end 84 | end 85 | end 86 | 87 | action :config do 88 | if exists 89 | cmd = "#{appcmd(node)} set vdir \"#{application_identifier}\"" 90 | converge_if_changed :physical_path do 91 | cmd << " /physicalPath:\"#{new_resource.physical_path}\"" 92 | end 93 | 94 | converge_if_changed :username do 95 | cmd << " /userName:\"#{new_resource.username}\"" 96 | end 97 | 98 | converge_if_changed :password do 99 | cmd << " /password:\"#{new_resource.password}\"" 100 | end 101 | 102 | converge_if_changed :logon_method do 103 | cmd << " /logonMethod:#{new_resource.logon_method}" 104 | end 105 | 106 | converge_if_changed :allow_sub_dir_config do 107 | cmd << " /allowSubDirConfig:#{new_resource.allow_sub_dir_config}" 108 | end 109 | 110 | if cmd != "#{appcmd(node)} set vdir \"#{application_identifier}\"" 111 | converge_by "Updated the VDIR - \"#{new_resource}\"" do 112 | Chef::Log.debug(cmd) 113 | shell_out!(cmd) 114 | end 115 | else 116 | Chef::Log.debug("#{new_resource} virtual directory - nothing changed") 117 | end 118 | end 119 | end 120 | 121 | action :delete do 122 | if exists 123 | converge_by "Deleted the VDIR - \"#{new_resource}\"" do 124 | Chef::Log.debug("#{appcmd(node)} delete vdir \"#{application_identifier}\"") 125 | shell_out!("#{appcmd(node)} delete vdir \"#{application_identifier}\"", returns: [0, 42]) 126 | end 127 | else 128 | Chef::Log.debug("#{new_resource} virtual directory does not exist - nothing to do") 129 | end 130 | end 131 | 132 | action_class do 133 | def exists 134 | current_resource.physical_path ? true : false 135 | end 136 | 137 | def application_identifier 138 | new_resource.path.start_with?('/') ? vdir_identifier.chomp('/') + new_resource.path : vdir_identifier + new_resource.path 139 | end 140 | 141 | def vdir_identifier 142 | new_resource.application_name.include?('/') ? new_resource.application_name : new_resource.application_name + '/' 143 | end 144 | end 145 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/berkshelf' 3 | 4 | RSpec.configure do |config| 5 | config.color = true # Use color in STDOUT 6 | config.formatter = :documentation # Use the specified formatter 7 | config.log_level = :error # Avoid deprecation notice SPAM 8 | config.platform = 'windows' 9 | config.version = '2012R2' 10 | end 11 | -------------------------------------------------------------------------------- /spec/unit/recipes/default_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: default 4 | # 5 | # Copyright:: 2015-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::default' do 22 | context 'when iis components provided, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new do |node| 25 | node.override['iis']['components'] = ['foobar'] 26 | end.converge(described_recipe) 27 | end 28 | 29 | it 'converges successfully' do 30 | expect { chef_run }.to_not raise_error 31 | end 32 | 33 | it 'installs windows feature foobar' do 34 | expect(chef_run).to install_iis_install('install IIS').with(additional_components: ['foobar']) 35 | end 36 | end 37 | 38 | context 'When all attributes are default, on an unspecified platform' do 39 | cached(:chef_run) do 40 | ChefSpec::SoloRunner.new.converge(described_recipe) 41 | end 42 | 43 | it 'converges successfully' do 44 | expect { chef_run }.to_not raise_error 45 | end 46 | end 47 | 48 | [:windows_feature_dism, :windows_feature_powershell, :windows_feature_servermanagercmd].each do |method| 49 | context "When iis windows feature install method is provided as #{method}, on a unspecified platform" do 50 | let(:chef_run) do 51 | ChefSpec::SoloRunner.new do |node| 52 | node.override['iis']['windows_feature_install_method'] = method 53 | end.converge(described_recipe) 54 | end 55 | 56 | it "installs windows features using #{method}" do 57 | expect(chef_run).to install_iis_install('install IIS').with(install_method: method) 58 | end 59 | end 60 | end 61 | 62 | context 'When source provided, on an unspecified platform' do 63 | let(:chef_run) do 64 | ChefSpec::SoloRunner.new do |node| 65 | node.override['iis']['source'] = 'somesource' 66 | end.converge(described_recipe) 67 | end 68 | 69 | it 'converges successfully' do 70 | expect { chef_run }.to_not raise_error 71 | end 72 | 73 | it 'installs features with source' do 74 | chef_run.node.override['iis']['source'] = 'somesource' 75 | chef_run.converge(described_recipe) 76 | expect(chef_run).to install_iis_install('install IIS').with(source: 'somesource') 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_application_initialization_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_application_initialization 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_application_initialization' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_aspnet45_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_aspnet45 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_aspnet45' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_aspnet_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_aspnet 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_aspnet' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_auth_anonymous_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_auth_anonymous 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_auth_anonymous' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_auth_basic_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_auth_basic 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_auth_basic' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_auth_digest_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_auth_digest 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_auth_digest' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_auth_windows_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_auth_windows 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_auth_windows' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_cgi_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_cgi 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_cgi' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_compress_dynamic_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_compress_dynamic 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_compress_dynamic' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_compress_static_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_compress_static 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_compress_static' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_ftp_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_ftp 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_ftp' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_iis6_metabase_compat.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_iis6_metabase_compat 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_iis6_metabase_compat' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_isapi_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_isapi 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_isapi' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_logging_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_logging 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_logging' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_management_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_management 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_management' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_security_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_security 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_security' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/mod_tracing_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: mod_tracing 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::mod_tracing' do 22 | context 'when all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'converges successfully' do 28 | expect { chef_run }.to_not raise_error 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/unit/recipes/remove_default_site_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: default 4 | # 5 | # Copyright:: 2015-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'iis::remove_default_site' do 22 | context 'When all attributes are default, on an unspecified platform' do 23 | let(:chef_run) do 24 | ChefSpec::SoloRunner.new.converge(described_recipe) 25 | end 26 | 27 | it 'stops default site' do 28 | expect(chef_run).to stop_iis_site('Default Web Site') 29 | end 30 | 31 | it 'deletes default site' do 32 | expect(chef_run).to delete_iis_site('Default Web Site') 33 | end 34 | 35 | it 'stops default app pool' do 36 | expect(chef_run).to stop_iis_pool('DefaultAppPool') 37 | end 38 | 39 | it 'deletes default app pool ' do 40 | expect(chef_run).to delete_iis_pool('DefaultAppPool') 41 | end 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /spec/unit/resources/install_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: iis 3 | # Spec:: install 4 | # 5 | # Copyright:: 2015-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'ostruct' 20 | require 'spec_helper' 21 | 22 | describe 'iis_install' do 23 | step_into :iis_install 24 | context 'When no additional iis components provided, on an unspecified platform' do 25 | recipe do 26 | iis_install 'Just iis' 27 | end 28 | 29 | it 'installs windows feature IIS' do 30 | expect(chef_run).to install_windows_feature('Install IIS and additional components') 31 | .with(feature_name: ['IIS-WebServerRole']) 32 | .with(install_method: :windows_feature_dism) 33 | end 34 | end 35 | 36 | context 'When install_mode is powershell, on an unspecified platform' do 37 | shell_out = OpenStruct.new 38 | shell_out.strerr = '' 39 | shell_out.stdout = 'WebServer' 40 | stubs_for_provider('iis_install[Just iis powershell]') do |provider| 41 | allow(provider).to receive_shell_out().and_return(shell_out) 42 | end 43 | recipe do 44 | iis_install 'Just iis powershell' do 45 | install_method :windows_feature_powershell 46 | end 47 | end 48 | 49 | it 'installs windows feature IIS' do 50 | expect(chef_run).to install_windows_feature('Install IIS and additional components') 51 | .with(feature_name: ['WebServer']) 52 | .with(install_method: :windows_feature_powershell) 53 | end 54 | end 55 | 56 | context 'When install_mode is powershell as a string, on an unspecified platform' do 57 | shell_out = OpenStruct.new 58 | shell_out.strerr = '' 59 | shell_out.stdout = 'WebServer' 60 | stubs_for_provider('iis_install[Just iis powershell]') do |provider| 61 | allow(provider).to receive_shell_out().and_return(shell_out) 62 | end 63 | recipe do 64 | iis_install 'Just iis powershell' do 65 | install_method 'windows_feature_powershell' 66 | end 67 | end 68 | 69 | it 'installs windows feature IIS' do 70 | expect(chef_run).to install_windows_feature('Install IIS and additional components') 71 | .with(feature_name: ['WebServer']) 72 | .with(install_method: :windows_feature_powershell) 73 | end 74 | end 75 | 76 | context 'When start_iis is true' do 77 | recipe do 78 | iis_install 'Just iis' do 79 | start_iis true 80 | end 81 | end 82 | 83 | it 'enables iis service with name W3WVC' do 84 | expect(chef_run).to enable_service('iis').with(service_name: 'W3SVC') 85 | end 86 | 87 | it 'starts iis service with name W3WVC' do 88 | expect(chef_run).to start_service('iis').with(service_name: 'W3SVC') 89 | end 90 | end 91 | 92 | context 'When single additional component specified, on an unspecified platform' do 93 | recipe do 94 | iis_install 'IIs and Foobar' do 95 | additional_components 'foobar' 96 | end 97 | end 98 | 99 | it 'installs iis and additional component' do 100 | expect(chef_run).to install_windows_feature('Install IIS and additional components') 101 | .with(feature_name: %w(IIS-WebServerRole foobar)) 102 | end 103 | end 104 | 105 | context 'When multiple additional components specified, on an unspecified platform' do 106 | recipe do 107 | iis_install 'IIs and Foobar' do 108 | additional_components %w(foo bar) 109 | end 110 | end 111 | 112 | it 'installs iis and additional component' do 113 | expect(chef_run).to install_windows_feature('Install IIS and additional components') 114 | .with(feature_name: %w(IIS-WebServerRole foo bar)) 115 | end 116 | end 117 | 118 | context 'When source provided, on an unspecified platform' do 119 | recipe do 120 | iis_install 'just iis' do 121 | source 'somesource' 122 | end 123 | end 124 | 125 | it 'converges successfully' do 126 | expect { chef_run }.to_not raise_error 127 | end 128 | 129 | it 'installs features with source' do 130 | expect(chef_run).to install_windows_feature('Install IIS and additional components') 131 | .with(source: 'somesource') 132 | end 133 | end 134 | end 135 | -------------------------------------------------------------------------------- /test/cookbooks/test/chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a chef-server or supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | Icon? 9 | nohup.out 10 | ehthumbs.db 11 | Thumbs.db 12 | 13 | # SASS # 14 | ######## 15 | .sass-cache 16 | 17 | # EDITORS # 18 | ########### 19 | \#* 20 | .#* 21 | *~ 22 | *.sw[a-z] 23 | *.bak 24 | REVISION 25 | TAGS* 26 | tmtags 27 | *_flymake.* 28 | *_flymake 29 | *.tmproj 30 | .project 31 | .settings 32 | mkmf.log 33 | 34 | ## COMPILED ## 35 | ############## 36 | a.out 37 | *.o 38 | *.pyc 39 | *.so 40 | *.com 41 | *.class 42 | *.exe 43 | */rdoc/ 44 | 45 | # Testing # 46 | ########### 47 | .watchr 48 | .rspec 49 | spec/* 50 | spec/fixtures/* 51 | test/* 52 | features/* 53 | examples/* 54 | Guardfile 55 | Procfile 56 | .kitchen* 57 | .rubocop.yml 58 | spec/* 59 | Rakefile 60 | .travis.yml 61 | .foodcritic 62 | .codeclimate.yml 63 | 64 | # SCM # 65 | ####### 66 | .git 67 | */.git 68 | .gitignore 69 | .gitmodules 70 | .gitconfig 71 | .gitattributes 72 | .svn 73 | */.bzr/* 74 | */.hg/* 75 | */.svn/* 76 | 77 | # Berkshelf # 78 | ############# 79 | Berksfile 80 | Berksfile.lock 81 | cookbooks/* 82 | tmp 83 | 84 | # Cookbooks # 85 | ############# 86 | CONTRIBUTING* 87 | CHANGELOG* 88 | TESTING* 89 | 90 | # Strainer # 91 | ############ 92 | Colanderfile 93 | Strainerfile 94 | .colander 95 | .strainer 96 | 97 | # Vagrant # 98 | ########### 99 | .vagrant 100 | Vagrantfile 101 | -------------------------------------------------------------------------------- /test/cookbooks/test/files/default/F5XFFHttpModule/x64/F5XFFHttpModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/cookbooks/test/files/default/F5XFFHttpModule/x64/F5XFFHttpModule.dll -------------------------------------------------------------------------------- /test/cookbooks/test/files/default/F5XFFHttpModule/x86/F5XFFHttpModule.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/cookbooks/test/files/default/F5XFFHttpModule/x86/F5XFFHttpModule.dll -------------------------------------------------------------------------------- /test/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'test' 2 | maintainer 'Chef Software, Inc.' 3 | maintainer_email 'cookbooks@chef.io' 4 | license 'Apache-2.0' 5 | version '0.1.0' 6 | 7 | depends 'iis' 8 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/app.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: app 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | directory "#{node['iis']['docroot']}\\v1_1" do 22 | recursive true 23 | end 24 | 25 | iis_app 'Default Web Site' do 26 | path '/v1_1' 27 | application_pool 'DefaultAppPool' 28 | physical_path "#{node['iis']['docroot']}/v1_1" 29 | enabled_protocols 'http,net.pipe' 30 | action [:add, :config] 31 | end 32 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/config.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: config 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | # create and start a new site that maps to 22 | # the physical location C:\inetpub\wwwroot\testfu 23 | # first the physical location must exist 24 | directory "#{node['iis']['docroot']}/MySite" do 25 | action :create 26 | end 27 | 28 | # now create and start the site (note this will use the default application pool which must exist) 29 | iis_site 'MySite' do 30 | protocol :http 31 | port 80 32 | path "#{node['iis']['docroot']}/MySite" 33 | action [:add, :start] 34 | end 35 | 36 | # Sets up logging 37 | iis_config '/section:system.applicationHost/sites /siteDefaults.logfile.directory:\"D:\\logs\"' do 38 | action :set 39 | end 40 | 41 | # Increase file upload size for 'MySite' 42 | iis_config '\"MySite\" /section:requestfiltering /requestlimits.maxallowedcontentlength:50000000' do 43 | action :set 44 | end 45 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/config_property.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: config_property 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | # create and start a new site that maps to 22 | # the physical location C:\inetpub\wwwroot\testfu 23 | # first the physical location must exist 24 | directory "#{node['iis']['docroot']}/ConfigSite" do 25 | action :create 26 | end 27 | 28 | # now create and start the site (note this will use the default application pool which must exist) 29 | iis_site 'ConfigSite' do 30 | protocol :http 31 | port 8080 32 | path "#{node['iis']['docroot']}/ConfigSite" 33 | action [:add, :start] 34 | end 35 | 36 | # Sets up logging 37 | iis_config_property 'directory' do 38 | ps_path 'MACHINE/WEBROOT/APPHOST' 39 | filter 'system.applicationHost/sites/siteDefaults/logfile' 40 | value 'D:\\logs' 41 | end 42 | 43 | # Increase file upload size for 'ConfigSite' 44 | iis_config_property 'maxAllowedContentLength' do 45 | ps_path 'MACHINE/WEBROOT/APPHOST/ConfigSite' 46 | filter 'system.webServer/security/requestFiltering/requestLimits' 47 | value 50_000_000 48 | end 49 | 50 | # Set XSS-Protection header on all sites 51 | iis_config_property 'Add X-Xss-Protection' do 52 | ps_path 'MACHINE/WEBROOT/APPHOST' 53 | filter 'system.webServer/httpProtocol/customHeaders' 54 | property 'name' 55 | value 'X-Xss-Protection' 56 | action :add 57 | end 58 | iis_config_property 'Set X-Xss-Protection' do 59 | ps_path 'MACHINE/WEBROOT/APPHOST' 60 | filter "system.webServer/httpProtocol/customHeaders/add[@name='X-Xss-Protection']" 61 | property 'value' 62 | value '1; mode=block' 63 | end 64 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/manager.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'iis' 2 | 3 | iis_manager 'IIS Manager' do 4 | port 19500 5 | enable_remote_management true 6 | log_directory 'C:\\CustomPath' 7 | end 8 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/manager_permission.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'iis' 2 | 3 | iis_manager 'IIS Manager' do 4 | enable_remote_management true 5 | end 6 | 7 | iis_manager_permission 'Default Web Site' do 8 | users ['BUILTIN\\Users'] 9 | end 10 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/module.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: module 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | directory "#{node['iis']['docroot']}\\v1_1" do 22 | recursive true 23 | end 24 | 25 | iis_app 'Default Web Site' do 26 | path '/v1_1' 27 | application_pool 'DefaultAppPool' 28 | physical_path "#{node['iis']['docroot']}/v1_1" 29 | enabled_protocols 'http,net.pipe' 30 | action :add 31 | end 32 | 33 | iis_module 'example module' do 34 | application 'Default Web Site/v1_1' 35 | type 'System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 36 | precondition 'managedHandler' 37 | action :add 38 | end 39 | 40 | f5xff_module_path = 'C:/httpmodules/F5XFF' 41 | 42 | directory f5xff_module_path do 43 | recursive true 44 | action :create 45 | end 46 | 47 | cookbook_file ::File.join(f5xff_module_path, 'F5XFFHttpModule-x64.dll') do 48 | source 'F5XFFHttpModule/x64/F5XFFHttpModule.dll' 49 | action :create 50 | end 51 | 52 | cookbook_file ::File.join(f5xff_module_path, 'F5XFFHttpModule-x86.dll') do 53 | source 'F5XFFHttpModule/x86/F5XFFHttpModule.dll' 54 | action :create 55 | end 56 | 57 | iis_module 'F5XFFHttpModule-x64' do 58 | module_name 'F5XFFHttpModule-x64' 59 | precondition 'bitness64' 60 | image ::File.join(f5xff_module_path, 'F5XFFHttpModule-x64.dll') 61 | action [:install, :add] 62 | end 63 | 64 | iis_module 'F5XFFHttpModule-x86' do 65 | module_name 'F5XFFHttpModule-x86' 66 | precondition 'bitness32' 67 | image ::File.join(f5xff_module_path, 'F5XFFHttpModule-x86.dll') 68 | action [:install, :add] 69 | end 70 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/pool.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: pool 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | # Defines default app pool recycle time(s) 22 | iis_config "/section:system.applicationHost/applicationPools /+\"applicationPoolDefaults.recycling.periodicRestart.schedule.[value='06:00:00']\" /commit:apphost" do 23 | returns [0, 183] 24 | action :set 25 | end 26 | 27 | directory "#{node['iis']['docroot']}\\test" do 28 | recursive true 29 | end 30 | 31 | # creates a new app pool 32 | iis_pool 'myAppPool_v1_1' do 33 | runtime_version '2.0' 34 | pipeline_mode :Classic 35 | action [:add, :config, :stop] 36 | end 37 | 38 | iis_pool 'test_start' do 39 | pipeline_mode :Classic 40 | action [:add, :config, :stop] 41 | end 42 | 43 | iis_pool 'test_no_managed_code' do 44 | no_managed_code false 45 | pipeline_mode :Integrated 46 | action [:add, :config, :start] 47 | end 48 | 49 | iis_pool 'testapppool' do 50 | thirty_two_bit false 51 | runtime_version '4.0' 52 | pipeline_mode :Integrated 53 | start_mode :OnDemand 54 | identity_type :SpecificUser 55 | periodic_restart_schedule ['06:00:00', '14:00:00', '17:00:00'] 56 | recycle_after_requests '1024' 57 | environment_variables ['HELLO=WORLD', 'FOO=BAR', 'ALPHA=BETA2'] 58 | username "#{node['hostname']}\\vagrant" 59 | password 'vagrant' 60 | action [:add, :config] 61 | end 62 | 63 | iis_pool 'test_no_managed_code' do 64 | no_managed_code true 65 | pipeline_mode :Classic 66 | action [:add, :config, :start] 67 | end 68 | 69 | iis_pool 'passwordwithentityapppool' do 70 | thirty_two_bit false 71 | runtime_version '4.0' 72 | pipeline_mode :Integrated 73 | start_mode :OnDemand 74 | identity_type :SpecificUser 75 | periodic_restart_schedule ['06:00:00', '14:00:00', '17:00:00'] 76 | environment_variables 'HELLO=WORLD' 77 | username "#{node['hostname']}\\vagrant" 78 | password 'vagrant&' 79 | action [:add, :config] 80 | end 81 | 82 | iis_pool 'start test_start' do 83 | pool_name 'test_start' 84 | action [:start] 85 | end 86 | 87 | iis_pool 'My App Pool' do 88 | runtime_version '4.0.30319' 89 | thirty_two_bit true 90 | pipeline_mode :Integrated 91 | action [:add, :config, :start] 92 | end 93 | 94 | iis_pool 'test_identity_type' do 95 | identity_type :NetworkService 96 | action [:add, :config, :start] 97 | end 98 | 99 | iis_pool 'Process Model Create' do 100 | pool_name 'Process Model Cleanup' 101 | identity_type :SpecificUser 102 | username "#{node['hostname']}\\vagrant" 103 | password 'vagrant' 104 | action [:add, :config, :start] 105 | end 106 | 107 | iis_pool 'Process Model Cleanup' do 108 | pool_name 'Process Model Cleanup' 109 | identity_type :ApplicationPoolIdentity 110 | action [:add, :config, :start] 111 | end 112 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/root.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: root 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | iis_root 'adding test html' do 22 | add_default_documents ['test.html'] 23 | add_mime_maps ['fileExtension=\'.dmg\',mimeType=\'application/octet-stream\''] 24 | action :add 25 | end 26 | 27 | iis_root 'remove mime types' do 28 | delete_mime_maps ['fileExtension=\'.rpm\',mimeType=\'audio/x-pn-realaudio-plugin\'', 'fileExtension=\'.msi\',mimeType=\'application/octet-stream\''] 29 | action :delete 30 | end 31 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/section.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: site 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | iis_section 'unlock staticContent of default web site' do 22 | section 'system.webServer/staticContent' 23 | site 'Default Web Site' 24 | action :unlock 25 | end 26 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/site.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: site 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | include_recipe 'iis::mod_ftp' 21 | 22 | directory "#{node['iis']['docroot']}\\site_test" do 23 | recursive true 24 | end 25 | 26 | directory "#{node['iis']['docroot']}\\site_test2" do 27 | recursive true 28 | end 29 | 30 | directory "#{node['iis']['docroot']}\\ftp_site_test" do 31 | recursive true 32 | end 33 | 34 | iis_site 'add/start to_be_deleted' do 35 | site_name 'to_be_deleted' 36 | application_pool 'DefaultAppPool' 37 | path "#{node['iis']['docroot']}/site_test" 38 | host_header 'localhost' 39 | port 8081 40 | action [:add, :start] 41 | end 42 | 43 | iis_site 'test' do 44 | application_pool 'DefaultAppPool' 45 | path "#{node['iis']['docroot']}/site_test" 46 | host_header 'localhost' 47 | action [:add, :start] 48 | end 49 | 50 | iis_site 'restart to_be_deleted' do 51 | site_name 'to_be_deleted' 52 | action [:restart] 53 | end 54 | 55 | iis_site 'test2' do 56 | application_pool 'DefaultAppPool' 57 | path "#{node['iis']['docroot']}/site_test2" 58 | host_header 'localhost' 59 | port 8080 60 | action [:add, :start] 61 | end 62 | 63 | iis_site 'stop/delete to_be_deleted' do 64 | site_name 'to_be_deleted' 65 | action [:stop, :delete] 66 | end 67 | 68 | iis_site 'myftpsite' do 69 | path "#{node['iis']['docroot']}\\ftp_site_test" 70 | application_pool 'DefaultAppPool' 71 | bindings 'ftp/*:21:*' 72 | action [:add, :config] 73 | end 74 | 75 | directory "#{node['iis']['docroot']}\\mytest" do 76 | action :create 77 | end 78 | 79 | iis_site 'add/start MyTest' do 80 | site_name 'MyTest' 81 | protocol :http 82 | port 8090 83 | path "#{node['iis']['docroot']}\\mytest" 84 | action [:add, :start] 85 | end 86 | 87 | iis_app 'MyTest' do 88 | path '/testpool' 89 | application_pool 'Test AppPool' 90 | physical_path "#{node['iis']['docroot']}\\mytest" 91 | enabled_protocols 'http' 92 | action :add 93 | end 94 | 95 | iis_site 'config MyTest' do 96 | site_name 'MyTest' 97 | protocol :http 98 | port 8090 99 | path "#{node['iis']['docroot']}\\mytest" 100 | action :config 101 | end 102 | -------------------------------------------------------------------------------- /test/cookbooks/test/recipes/vdir.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: test 3 | # Recipe:: vdir 4 | # 5 | # copyright: 2017, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | include_recipe 'iis' 20 | 21 | directory node['iis']['docroot'].to_s do 22 | recursive true 23 | end 24 | 25 | directory "#{node['iis']['docroot']}\\vdir_test" do 26 | recursive true 27 | end 28 | 29 | directory "#{node['iis']['docroot']}\\foo" do 30 | recursive true 31 | end 32 | 33 | directory "#{node['iis']['docroot']}\\app_test" do 34 | recursive true 35 | end 36 | 37 | directory "#{node['iis']['docroot']}\\app_test\\vdir_test2" do 38 | recursive true 39 | end 40 | 41 | iis_pool 'DefaultAppPool' do 42 | pipeline_mode :Classic 43 | action :add 44 | end 45 | 46 | iis_site 'Default Web Site' do 47 | protocol :http 48 | port 80 49 | path node['iis']['docroot'].to_s 50 | action [:add, :start] 51 | end 52 | 53 | iis_app 'Default Web Site' do 54 | path '/app_test' 55 | application_pool 'DefaultAppPool' 56 | physical_path "#{node['iis']['docroot']}/app_test" 57 | enabled_protocols 'http,net.pipe' 58 | action [:add, :config] 59 | end 60 | 61 | iis_vdir 'Default Web Site/' do 62 | path '/vdir_test' 63 | physical_path "#{node['iis']['docroot']}\\vdir_test" 64 | username 'vagrant' 65 | password 'vagrant' 66 | logon_method :ClearText 67 | allow_sub_dir_config false 68 | action [:add, :config] 69 | end 70 | 71 | iis_vdir 'Creating vDir /foo for Sitename' do 72 | application_name 'Default Web Site' 73 | path '/foo' 74 | physical_path "#{node['iis']['docroot']}\\foo" 75 | action [:add, :config] 76 | end 77 | 78 | iis_vdir 'Creating vDir /vdir_test2 in app' do 79 | application_name 'Default Web Site/app_test' 80 | path '/vdir_test2' 81 | physical_path "#{node['iis']['docroot']}\\app_test\\vdir_test2" 82 | action [:add, :config] 83 | end 84 | 85 | iis_vdir 'Default Web Site/' do 86 | path '/vdir_test' 87 | physical_path "#{node['iis']['docroot']}\\vdir_test" 88 | username 'vagrant' 89 | password 'vagrant' 90 | logon_method :ClearText 91 | allow_sub_dir_config false 92 | action [:add, :config] 93 | end 94 | -------------------------------------------------------------------------------- /test/integration/app/README.md: -------------------------------------------------------------------------------- 1 | # iis_app InSpec Profile 2 | 3 | This will allow the testing of iis_app until it can be added into inspec. 4 | -------------------------------------------------------------------------------- /test/integration/app/controls/app_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2017, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | title 'iis_app section' 5 | 6 | describe service('W3SVC') do 7 | it { should be_installed } 8 | it { should be_running } 9 | its('startmode') { should eq 'Auto' } 10 | end 11 | 12 | describe iis_site('Default Web Site') do 13 | it { should exist } 14 | it { should be_running } 15 | it { should have_app_pool('DefaultAppPool') } 16 | end 17 | 18 | describe iis_app('/v1_1', 'Default Web Site') do 19 | it { should exist } 20 | it { should have_application_pool('DefaultAppPool') } 21 | it { should have_physical_path('C:\\inetpub\\wwwroot\\v1_1') } 22 | it { should have_protocol('http') } 23 | end 24 | -------------------------------------------------------------------------------- /test/integration/app/inspec.yml: -------------------------------------------------------------------------------- 1 | name: app 2 | title: iis_app InSpec Profile 3 | copyright: 2017, Chef Software, Inc. 4 | license: All Rights Reserved 5 | summary: An InSpec Compliance Profile for iis_app 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /test/integration/app/libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/integration/app/libraries/.gitkeep -------------------------------------------------------------------------------- /test/integration/app/libraries/iis_app.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # check for web applications in IIS 3 | # Usage: 4 | # describe iis_app('/myapp', 'Website') do 5 | # it { should exist } 6 | # it { should have_application_pool('MyAppPool') } 7 | # it { should have_protocols('http') } 8 | # it { should have_site_name('Default Web Site') } 9 | # it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') } 10 | # it { should have_path('\\My Application') } 11 | # end 12 | # 13 | # Note: this is only supported in windows 2012 and later 14 | 15 | class IisApp < Inspec.resource(1) 16 | name 'iis_app' 17 | desc 'Tests IIS application configuration on windows. Supported in server 2012+ only' 18 | example " 19 | describe iis_app('/myapp', 'Default Web Site') do 20 | it { should exist } 21 | it { should have_application_pool('MyAppPool') } 22 | it { should have_protocols('http') } 23 | it { should have_site_name('Default Web Site') } 24 | it { should have_physical_path('C:\\inetpub\\wwwroot\\myapp') } 25 | it { should have_path('\\My Application') } 26 | end 27 | " 28 | 29 | def initialize(path, site_name) 30 | @path = path 31 | @site_name = site_name 32 | @cache = nil 33 | 34 | @app_provider = AppProvider.new(inspec) 35 | 36 | # verify that this resource is only supported on Windows 37 | return skip_resource 'The `iis_app` resource is not supported on your OS.' unless inspec.os.windows? 38 | end 39 | 40 | def application_pool 41 | iis_app[:application_pool] 42 | end 43 | 44 | def protocols 45 | iis_app[:protocols] 46 | end 47 | 48 | def site_name 49 | iis_app[:site_name] 50 | end 51 | 52 | def path 53 | iis_app[:path] 54 | end 55 | 56 | def physical_path 57 | iis_app[:physical_path] 58 | end 59 | 60 | def exists? 61 | !iis_app[:path].empty? 62 | end 63 | 64 | def has_site_name?(site_name) 65 | iis_app[:site_name] == site_name 66 | end 67 | 68 | def has_application_pool?(application_pool) 69 | iis_app[:application_pool] == application_pool 70 | end 71 | 72 | def has_path?(path) 73 | iis_app[:path] == path 74 | end 75 | 76 | def has_physical_path?(physical_path) 77 | iis_app[:physical_path] == physical_path 78 | end 79 | 80 | def has_protocol?(protocol) 81 | (iis_app[:protocols].include? protocol) 82 | end 83 | 84 | def to_s 85 | "iis_app '#{@site_name}#{@path}'" 86 | end 87 | 88 | def iis_app 89 | return @cache unless @cache.nil? 90 | @cache = @app_provider.iis_app(@path, @site_name) unless @app_provider.nil? 91 | end 92 | end 93 | 94 | class AppProvider 95 | attr_reader :inspec 96 | 97 | def initialize(inspec) 98 | @inspec = inspec 99 | end 100 | 101 | # want to populate everything using one powershell command here and spit it out as json 102 | def iis_app(path, site_name) 103 | command = "Import-Module WebAdministration; Get-WebApplication -Name '#{path}' -Site '#{site_name}' | Select-Object * | ConvertTo-Json" 104 | cmd = @inspec.command(command) 105 | 106 | begin 107 | app = JSON.parse(cmd.stdout) 108 | rescue JSON::ParserError => _e 109 | return {} 110 | end 111 | 112 | # map our values to a hash table 113 | { 114 | site_name: site_name, 115 | path: path, 116 | application_pool: app['applicationPool'], 117 | physical_path: app['PhysicalPath'], 118 | protocols: app['enabledProtocols'], 119 | } 120 | end 121 | end 122 | -------------------------------------------------------------------------------- /test/integration/config_property/config_property_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2018, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | control 'config_property' do 5 | title 'Check IIS properties are set' 6 | 7 | describe powershell("(Get-WebConfigurationProperty -PSPath \"MACHINE/WEBROOT/APPHOST\" \ 8 | -filter \"system.applicationHost/sites/siteDefaults/logfile\" \ 9 | -Name \"directory\").value") do 10 | its('stdout') { should eq "D:\\logs\r\n" } 11 | end 12 | 13 | describe powershell("(Get-WebConfigurationProperty -PSPath \"MACHINE/WEBROOT/APPHOST\" \ 14 | -filter \"system.webServer/httpProtocol/customHeaders/add[@name='X-Xss-Protection']\" \ 15 | -Name \"value\").value") do 16 | its('stdout') { should eq "1; mode=block\r\n" } 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/integration/default/spec/default_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2015-2019, Chef Software, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | describe service('W3SVC') do 18 | it { should be_installed } 19 | it { should be_running } 20 | its('startmode') { should eq 'Auto' } 21 | end 22 | 23 | # Unless we are on a 'polluted' machine, the default website should 24 | # be present if the IIS Role was freshly installed. All our vagrant 25 | # configurations install with the system drive at C:\ 26 | describe iis_site('Default Web Site') do 27 | it { should exist } 28 | it { should be_running } 29 | it { should have_app_pool('DefaultAppPool') } 30 | end 31 | -------------------------------------------------------------------------------- /test/integration/manager/manager.rb: -------------------------------------------------------------------------------- 1 | control 'Manager Property' do 2 | title 'Check manager is setup and listening correctly' 3 | 4 | describe port(19500) do 5 | it { should be_listening } 6 | end 7 | describe windows_feature('Web-Mgmt-Service') do 8 | it { should be_installed } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/integration/manager_permission/manager_permission.rb: -------------------------------------------------------------------------------- 1 | control 'Manager Permissions' do 2 | title 'Check permissions to access the manager has been correctly granted' 3 | 4 | describe powershell('[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Management") | Out-Null 5 | $current = [Microsoft.Web.Management.Server.ManagementAuthorization]::GetAuthorizedUsers("Default Web Site", $false, 0, 1000) 6 | ($current | ? { $_.ConfigurationPath -eq "/Default Web Site" } | Select-Object Name).Name') do 7 | its('strip') { should eq 'BUILTIN\\Users' } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/module/README.md: -------------------------------------------------------------------------------- 1 | # iis_module InSpec Profile 2 | 3 | This will allow the testing of iis_module until it can be added into inspec. 4 | -------------------------------------------------------------------------------- /test/integration/module/controls/module_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2017, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | title 'iis_module section' 5 | 6 | describe service('W3SVC') do 7 | it { should be_installed } 8 | it { should be_running } 9 | its('startmode') { should eq 'Auto' } 10 | end 11 | 12 | describe iis_module('example module', 'Default Web Site/v1_1') do 13 | it { should exist } 14 | it { should have_name('example module') } 15 | it { should have_pre_condition('managedHandler') } 16 | it { should have_type('System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35') } 17 | end 18 | 19 | describe iis_module('F5XFFHttpModule-x64') do 20 | it { should exist } 21 | it { should have_name('F5XFFHttpModule-x64') } 22 | it { should have_pre_condition('bitness64') } 23 | end 24 | 25 | describe iis_module('F5XFFHttpModule-x86') do 26 | it { should exist } 27 | it { should have_name('F5XFFHttpModule-x86') } 28 | it { should have_pre_condition('bitness32') } 29 | end 30 | -------------------------------------------------------------------------------- /test/integration/module/inspec.yml: -------------------------------------------------------------------------------- 1 | name: module 2 | title: iis_module InSpec Profile 3 | copyright: 2017, Chef Software, Inc. 4 | license: All Rights Reserved 5 | summary: An InSpec Compliance Profile for iis_module 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /test/integration/module/libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/integration/module/libraries/.gitkeep -------------------------------------------------------------------------------- /test/integration/module/libraries/iis_module.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # check for application modules in IIS 3 | # Usage: 4 | # describe iis_module('module_name', 'Default Web Site') do 5 | # it { should exist } 6 | # it { should have_name('module_name') } 7 | # it { should have_type('System.Web.Security.FileAuthorizationModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') } 8 | # end 9 | # 10 | # Note: this is only supported in windows 2012 and later 11 | 12 | class IisModule < Inspec.resource(1) 13 | name 'iis_module' 14 | desc 'Tests IIS module configuration on windows. Supported in server 2012+ only' 15 | example " 16 | describe iis_module('module_name', 'Default Web Site') do 17 | it { should exist } 18 | it { should have_name('module_name') } 19 | it { should have_type('System.Web.Security.FileAuthorizationModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') } 20 | end 21 | " 22 | 23 | def initialize(module_name, application = nil) 24 | @module_name = module_name 25 | @application = application 26 | @cache = nil 27 | 28 | @module_provider = ModuleProvider.new(inspec) 29 | 30 | # verify that this resource is only supported on Windows 31 | return skip_resource 'The `iis_module` resource is not supported on your OS.' unless inspec.os.windows? 32 | end 33 | 34 | def name 35 | iis_module[:name] 36 | end 37 | 38 | def type 39 | iis_module[:type] 40 | end 41 | 42 | def pre_condition 43 | iis_module[:pre_condition] 44 | end 45 | 46 | def exists? 47 | !iis_module.nil? && !iis_module[:name].nil? 48 | end 49 | 50 | def has_name?(module_name) 51 | iis_module.nil? ? false : iis_module[:name] == module_name 52 | end 53 | 54 | def has_type?(module_type) 55 | iis_module.nil? ? false : iis_module[:type] == module_type 56 | end 57 | 58 | def has_pre_condition?(pre_condition) 59 | iis_module.nil? ? false : iis_module[:pre_condition] == pre_condition 60 | end 61 | 62 | def to_s 63 | "iis_module `#{@module_name}` - `#{@application}`" 64 | end 65 | 66 | def iis_module 67 | return @cache unless @cache.nil? 68 | @cache = @module_provider.iis_module(@module_name, @application) unless @module_provider.nil? 69 | end 70 | end 71 | 72 | class ModuleProvider 73 | attr_reader :inspec 74 | 75 | def initialize(inspec) 76 | @inspec = inspec 77 | end 78 | 79 | # want to populate everything using one powershell command here and spit it out as json 80 | def iis_module(module_name, application = nil) 81 | command = if application.nil? 82 | "Import-Module WebAdministration; Get-WebGlobalModule -Name '#{module_name}' | Select-Object name, type, preCondition | ConvertTo-Json" 83 | else 84 | "Import-Module WebAdministration; Get-WebManagedModule -Name '#{module_name}' -PSPath 'IIS:\\sites\\#{application}' | Select-Object name, type, preCondition | ConvertTo-Json" 85 | end 86 | 87 | cmd = @inspec.command(command) 88 | 89 | begin 90 | mod = JSON.parse(cmd.stdout) 91 | rescue JSON::ParserError => _e 92 | return {} 93 | end 94 | 95 | # map our values to a hash table 96 | { 97 | name: mod['name'], 98 | type: mod['type'], 99 | pre_condition: mod['preCondition'], 100 | } 101 | end 102 | end 103 | -------------------------------------------------------------------------------- /test/integration/pool/README.md: -------------------------------------------------------------------------------- 1 | # Example InSpec Profile 2 | 3 | This example shows the implementation of an InSpec [profile](../../docs/profiles.rst). 4 | -------------------------------------------------------------------------------- /test/integration/pool/controls/pool_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2017, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | title 'iis_app section' 5 | 6 | describe service('W3SVC') do 7 | it { should be_installed } 8 | it { should be_running } 9 | its('startmode') { should eq 'Auto' } 10 | end 11 | 12 | describe iis_pool('myAppPool_v1_1') do 13 | it { should exist } 14 | it { should_not be_running } 15 | its('managed_runtime_version') { should eq 'v2.0' } 16 | it { should have_name('myAppPool_v1_1') } 17 | it { should have_queue_length(1000) } 18 | end 19 | 20 | describe iis_pool('testapppool') do 21 | it { should exist } 22 | it { should be_running } 23 | its('managed_runtime_version') { should eq 'v4.0' } 24 | its('managed_pipeline_mode') { should eq 'Integrated' } 25 | it { should have_name('testapppool') } 26 | its('start_mode') { should eq 'OnDemand' } 27 | its('identity_type') { should eq 'SpecificUser' } 28 | its('periodic_restart_schedule') { should eq ['06:00:00', '14:00:00', '17:00:00'] } 29 | its('recycle_after_requests') { should eq 1024 } 30 | its('environment_variables') { should eq ['ALPHA=BETA2', 'FOO=BAR', 'HELLO=WORLD'] } 31 | its('username') { should include('\\vagrant') } 32 | its('password') { should eq 'vagrant' } 33 | end 34 | 35 | describe iis_pool('passwordwithentityapppool') do 36 | it { should exist } 37 | its('password') { should eq 'vagrant&' } 38 | its('environment_variables') { should eq ['HELLO=WORLD'] } 39 | end 40 | 41 | describe iis_pool('test_start') do 42 | it { should exist } 43 | it { should be_running } 44 | its('managed_pipeline_mode') { should eq 'Classic' } 45 | it { should have_name('test_start') } 46 | end 47 | 48 | describe iis_pool('My App Pool') do 49 | it { should exist } 50 | it { should be_running } 51 | it { should be_enable_32bit_app_on_win64 } 52 | its('managed_runtime_version') { should eq 'v4.0.30319' } 53 | its('managed_pipeline_mode') { should eq 'Integrated' } 54 | it { should have_name('My App Pool') } 55 | end 56 | 57 | describe iis_pool('test_identity_type') do 58 | it { should exist } 59 | it { should be_running } 60 | its('identity_type') { should eq 'NetworkService' } 61 | end 62 | 63 | describe iis_pool('test_no_managed_code') do 64 | it { should exist } 65 | it { should be_running } 66 | its('managed_pipeline_mode') { should eq 'Classic' } 67 | its('managed_runtime_version') { should eq '' } 68 | end 69 | 70 | describe iis_pool('Process Model Cleanup') do 71 | it { should exist } 72 | it { should be_running } 73 | its('identity_type') { should eq 'ApplicationPoolIdentity' } 74 | its('username') { should eq '' } 75 | its('password') { should eq '' } 76 | end 77 | -------------------------------------------------------------------------------- /test/integration/pool/inspec.yml: -------------------------------------------------------------------------------- 1 | name: pool 2 | title: InSpec Profile 3 | maintainer: The Authors 4 | copyright: The Authors 5 | copyright_email: you@example.com 6 | license: All Rights Reserved 7 | summary: An InSpec Compliance Profile 8 | version: 0.1.0 9 | -------------------------------------------------------------------------------- /test/integration/pool/libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/integration/pool/libraries/.gitkeep -------------------------------------------------------------------------------- /test/integration/root/README.md: -------------------------------------------------------------------------------- 1 | # `iis_root` InSpec Profile 2 | 3 | This will allow the testing of `iis_root` until it can be added into inspec. 4 | -------------------------------------------------------------------------------- /test/integration/root/controls/root_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2017, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | title 'iis_app section' 5 | 6 | describe service('W3SVC') do 7 | it { should be_installed } 8 | it { should be_running } 9 | its('startmode') { should eq 'Auto' } 10 | end 11 | 12 | # This is not working and needs more investigation 13 | # describe iis_root do 14 | # its('default_documents') { should eq ['test.html', 'Default.htm', 'Default.asp', 'index.htm', 'index.html', 'iisstart.htm', 'default.aspx'] } 15 | # end 16 | 17 | control 'document tests' do 18 | title 'Check IIS default documents are set' 19 | 20 | describe powershell('Import-Module WebAdministration; Get-WebConfiguration -Filter /system.webServer/defaultDocument/files/add -PSPath MACHINE/WEBROOT/APPHOST | Select-Object value') do 21 | its('stdout') { should match /test\.html/ } 22 | its('stdout') { should_not match /not_there\.html/ } 23 | end 24 | end 25 | 26 | control 'mime tests' do 27 | title 'Check IIS mimes are set' 28 | 29 | describe powershell('Get-WebConfiguration -Filter system.webServer/staticContent/mimeMap -PSPath MACHINE/WEBROOT/APPHOST | Select-Object fileExtension, mimeType') do 30 | its('stdout') { should match %r{\.dmg\s+application/octet-stream} } 31 | its('stdout') { should_not match %r{\.rpm\s+audio/x-pn-realaudio-plugin} } 32 | its('stdout') { should_not match %r{\.msi\s+application/octet-stream} } 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/integration/root/inspec.yml: -------------------------------------------------------------------------------- 1 | name: root 2 | title: iis_root InSpec Profile 3 | copyright: 2017, Chef Software, Inc. 4 | license: All Rights Reserved 5 | summary: An InSpec Compliance Profile for iis_root 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /test/integration/section/README.md: -------------------------------------------------------------------------------- 1 | # `iis_section` InSpec Profile 2 | 3 | This will allow the testing of `iis_section` until it can be added into inspec. 4 | -------------------------------------------------------------------------------- /test/integration/section/controls/section_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2017, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | title 'iis_section section' 5 | 6 | describe service('W3SVC') do 7 | it { should be_installed } 8 | it { should be_running } 9 | its('startmode') { should eq 'Auto' } 10 | end 11 | 12 | describe iis_section('system.webServer/staticContent', 'Default Web Site') do 13 | it { should exist } 14 | it { should have_override_mode('Allow') } 15 | it { should have_override_mode_effective('Allow') } 16 | end 17 | -------------------------------------------------------------------------------- /test/integration/section/inspec.yml: -------------------------------------------------------------------------------- 1 | name: section 2 | title: iis_section InSpec Profile 3 | copyright: 2017, Chef Software, Inc. 4 | license: All Rights Reserved 5 | summary: An InSpec Compliance Profile for iis_section 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /test/integration/section/libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/integration/section/libraries/.gitkeep -------------------------------------------------------------------------------- /test/integration/section/libraries/iis_section.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # check for sections in IIS 3 | # Usage: 4 | # describe iis_section('//staticContent', 'Default Web Site') do 5 | # it { should exist } 6 | # it { should have_override_mode('Allow') } 7 | # it { should have_override_mode_effective('Allow') } 8 | # end 9 | # 10 | # Note: this is only supported in windows 2012 and later 11 | 12 | class IisSection < Inspec.resource(1) 13 | name 'iis_section' 14 | desc 'Tests IIS section on windows. Supported in server 2012+ only' 15 | example " 16 | describe iis_section('//staticContent', 'Default Web Site') do 17 | it { should exist } 18 | it { should have_override_mode('Allow') } 19 | it { should have_override_mode_effective('Allow') } 20 | end 21 | " 22 | 23 | def initialize(section, location) 24 | @section = section 25 | @location = location 26 | @cache = nil 27 | 28 | @section_provider = SectionProvider.new(inspec) 29 | 30 | # verify that this resource is only supported on Windows 31 | skip_resource 'The `iis_section` resource is not supported on your OS.' unless inspec.os.windows? 32 | end 33 | 34 | def is_locked 35 | iis_section[:is_locked] 36 | end 37 | 38 | def override_mode 39 | iis_section[:override_mode] 40 | end 41 | 42 | def override_mode_effective 43 | iis_section[:override_mode_effective] 44 | end 45 | 46 | def exists? 47 | !iis_section[:override_mode].empty? 48 | end 49 | 50 | def has_locked?(locked) 51 | iis_section[:is_locked] == locked 52 | end 53 | 54 | def has_override_mode?(override_mode) 55 | iis_section[:override_mode] == override_mode 56 | end 57 | 58 | def has_override_mode_effective?(effective_override) 59 | iis_section[:override_mode_effective] == effective_override 60 | end 61 | 62 | def to_s 63 | "iis_section section: '#{@section}' - location: '#{@location}'" 64 | end 65 | 66 | def iis_section 67 | return @cache unless @cache.nil? 68 | @cache = @section_provider.iis_section(@section, @location) unless @section_provider.nil? 69 | end 70 | end 71 | 72 | class SectionProvider 73 | attr_reader :inspec 74 | 75 | def initialize(inspec) 76 | @inspec = inspec 77 | end 78 | 79 | # want to populate everything using one powershell command here and spit it out as json 80 | def iis_section(section, location) 81 | command = "Import-Module WebAdministration; get-webconfiguration -Filter '#{section}' -PSPath 'MACHINE/WEBROOT/APPHOST' -Location '#{location}' -metadata | Select-Object IsLocked, OverrideMode, OverrideModeEffective | ConvertTo-JSON" 82 | cmd = @inspec.command(command) 83 | override_mode_enumeration = %w(N/A Inherit Allow Deny Unknown) 84 | 85 | begin 86 | section = JSON.parse(cmd.stdout) 87 | rescue JSON::ParserError => _e 88 | return {} 89 | end 90 | 91 | # map our values to a hash table 92 | { 93 | is_locked: section['IsLocked'], 94 | override_mode: override_mode_enumeration[section['OverrideMode']], 95 | override_mode_effective: override_mode_enumeration[section['OverrideModeEffective']], 96 | } 97 | end 98 | end 99 | -------------------------------------------------------------------------------- /test/integration/site/site_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2019, Chef Software, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | describe service('W3SVC') do 18 | it { should be_installed } 19 | it { should be_running } 20 | its('startmode') { should eq 'Auto' } 21 | end 22 | 23 | # Unless we are on a 'polluted' machine, the default website should 24 | # be present if the IIS Role was freshly installed. All our vagrant 25 | # configurations install with the system drive at C:\ 26 | describe iis_site('test') do 27 | it { should exist } 28 | it { should be_running } 29 | it { should have_app_pool('DefaultAppPool') } 30 | end 31 | 32 | describe iis_site('test2') do 33 | it { should exist } 34 | it { should be_running } 35 | it { should have_app_pool('DefaultAppPool') } 36 | its('bindings') { should eq ['http *:8080:localhost'] } 37 | end 38 | 39 | describe iis_site('to_be_deleted') do 40 | it { should_not exist } 41 | it { should_not be_running } 42 | end 43 | 44 | describe iis_site('myftpsite') do 45 | it { should exist } 46 | it { should be_running } 47 | its('bindings') { should eq ['ftp *:21:*'] } 48 | end 49 | 50 | describe iis_site('mytest') do 51 | it { should exist } 52 | it { should be_running } 53 | its('bindings') { should eq ['http *:8090:'] } 54 | end 55 | 56 | describe port(8090) do 57 | it { should be_listening } 58 | end 59 | -------------------------------------------------------------------------------- /test/integration/vdir/README.md: -------------------------------------------------------------------------------- 1 | # `iis_vdir` InSpec Profile 2 | 3 | This will allow the testing of `iis_vdir` until it can be added into inspec. 4 | -------------------------------------------------------------------------------- /test/integration/vdir/controls/vdir_spec.rb: -------------------------------------------------------------------------------- 1 | # copyright: 2017, Chef Software, Inc. 2 | # license: All rights reserved 3 | 4 | title 'iis_vdir section' 5 | 6 | describe service('W3SVC') do 7 | it { should be_installed } 8 | it { should be_running } 9 | its('startmode') { should eq 'Auto' } 10 | end 11 | 12 | describe iis_vdir('/vdir_test', 'Default Web Site') do 13 | it { should exist } 14 | it { should have_path('/vdir_test') } 15 | it { should have_physical_path('C:\\inetpub\\wwwroot\\vdir_test') } 16 | it { should have_username('vagrant') } 17 | it { should have_password('vagrant') } 18 | it { should have_logon_method('ClearText') } 19 | it { should have_allow_sub_dir_config(false) } 20 | end 21 | 22 | describe iis_vdir('/foo', 'Default Web Site') do 23 | it { should exist } 24 | it { should have_path('/foo') } 25 | it { should have_physical_path('C:\\inetpub\\wwwroot\\foo') } 26 | end 27 | 28 | describe iis_vdir('/vdir_test2', 'Default Web Site/app_test') do 29 | it { should exist } 30 | it { should have_path('/vdir_test2') } 31 | it { should have_physical_path('C:\\inetpub\\wwwroot\\app_test\\vdir_test2') } 32 | it { should have_logon_method('ClearText') } 33 | it { should have_username('') } 34 | it { should have_password('') } 35 | end 36 | -------------------------------------------------------------------------------- /test/integration/vdir/inspec.yml: -------------------------------------------------------------------------------- 1 | name: vdir 2 | title: iis_vdir InSpec Profile 3 | copyright: 2017, Chef Software, Inc. 4 | license: All Rights Reserved 5 | summary: An InSpec Compliance Profile for iis_vdir 6 | version: 0.1.0 7 | -------------------------------------------------------------------------------- /test/integration/vdir/libraries/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sous-chefs/iis/076c3509b658a2c7a5f5f89de6464f8a936c456a/test/integration/vdir/libraries/.gitkeep -------------------------------------------------------------------------------- /test/integration/vdir/libraries/iis_vdir.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # check for virtual directories in IIS 3 | # Usage: 4 | # describe iis_vdir('Default Web Site', '/vdir_test') do 5 | # it { should exist } 6 | # it { should have_path('/vdir_test') } 7 | # it { should have_physical_path('C:\\inetpub\\wwwroot\\vdir_test') } 8 | # it { should have_username('vagrant') } 9 | # it { should have_password('vagrant') } 10 | # it { should have_logon_method('ClearText') } 11 | # it { should have_allow_sub_dir_config(false) } 12 | # end 13 | # 14 | # Note: this is only supported in windows 2012 and later 15 | 16 | class IisVdir < Inspec.resource(1) 17 | name 'iis_vdir' 18 | desc 'Tests IIS application configuration on windows. Supported in server 2012+ only' 19 | example " 20 | describe iis_vdir('Default Web Site', '/vdir_test') do 21 | it { should exist } 22 | it { should have_path('/vdir_test') } 23 | it { should have_physical_path('C:\\inetpub\\wwwroot\\vdir_test') } 24 | it { should have_username('vagrant') } 25 | it { should have_password('vagrant') } 26 | it { should have_logon_method('ClearText') } 27 | it { should have_allow_sub_dir_config(false) } 28 | end 29 | " 30 | 31 | def initialize(path, application_name) 32 | @path = path 33 | @application_name = application_name 34 | @cache = nil 35 | 36 | @vdir_provider = VdirProvider.new(inspec) 37 | 38 | # verify that this resource is only supported on Windows 39 | skip_resource 'The `iis_vdir` resource is not supported on your OS.' unless inspec.os.windows? 40 | end 41 | 42 | def application_name 43 | iis_vdir[:application_name] 44 | end 45 | 46 | def path 47 | iis_vdir[:path] 48 | end 49 | 50 | def physical_path 51 | iis_vdir[:physical_path] 52 | end 53 | 54 | def username 55 | iis_vdir[:username] 56 | end 57 | 58 | def password 59 | iis_vdir[:password] 60 | end 61 | 62 | def logon_method 63 | iis_vdir[:logon_method] 64 | end 65 | 66 | def allow_sub_dir_config 67 | iis_vdir[:allow_sub_dir_config] 68 | end 69 | 70 | def exists? 71 | !iis_vdir[:path].empty? 72 | end 73 | 74 | def has_application_name?(application_name) 75 | iis_vdir[:application_name] == application_name 76 | end 77 | 78 | def has_path?(path) 79 | iis_vdir[:path] == path 80 | end 81 | 82 | def has_physical_path?(physical_path) 83 | iis_vdir[:physical_path] == physical_path 84 | end 85 | 86 | def has_password?(password) 87 | iis_vdir[:password] == password 88 | end 89 | 90 | def has_username?(username) 91 | iis_vdir[:username] == username 92 | end 93 | 94 | def has_logon_method?(method) 95 | iis_vdir[:logon_method] == method 96 | end 97 | 98 | def has_allow_sub_dir_config?(allow) 99 | iis_vdir[:allow_sub_dir_config] == allow 100 | end 101 | 102 | def to_s 103 | "iis_vdir '#{@application_name}#{@path}'" 104 | end 105 | 106 | def iis_vdir 107 | return @cache unless @cache.nil? 108 | @cache = @vdir_provider.iis_vdir(@path, @application_name) unless @vdir_provider.nil? 109 | end 110 | end 111 | 112 | class VdirProvider 113 | attr_reader :inspec 114 | 115 | def initialize(inspec) 116 | @inspec = inspec 117 | end 118 | 119 | # want to populate everything using one powershell command here and spit it out as json 120 | def iis_vdir(path, application_name) 121 | site_app = application_name.split('/', 2) 122 | 123 | command = "Import-Module WebAdministration; Get-WebVirtualDirectory -Site \"#{site_app[0]}\"" 124 | command = "#{command.dup} -Application \"#{site_app[1]}\"" if site_app.length > 1 125 | command = "#{command.dup} -Name \"#{path}\" | Select-Object path, physicalPath, userName, password, logonMethod, allowSubDirConfig, PSPath, ItemXPath | ConvertTo-Json" 126 | cmd = @inspec.command(command) 127 | 128 | begin 129 | vdir = JSON.parse(cmd.stdout) 130 | Log.info(vdir) 131 | rescue JSON::ParserError => _e 132 | return {} 133 | end 134 | 135 | # map our values to a hash table 136 | { 137 | application_name: application_name, 138 | path: path, 139 | physical_path: vdir['physicalPath'], 140 | username: vdir['userName'], 141 | password: vdir['password'], 142 | logon_method: vdir['logonMethod'], 143 | allow_sub_dir_config: vdir['allowSubDirConfig'], 144 | } 145 | end 146 | end 147 | --------------------------------------------------------------------------------